Przeglądaj źródła

feature: 系统管理->用户管理
1.增加新用户时根据系统参数是否自动开户逻辑处理
2.支付管理->账户管理增加了数据范围权限

luoyb 1 rok temu
rodzic
commit
da3f4e8e00
29 zmienionych plików z 754 dodań i 68 usunięć
  1. 3 2
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteUserAccountService.java
  2. 9 0
      ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/bo/RemoteUserAccountBo.java
  3. 4 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
  4. 8 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java
  5. 90 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/CardOpenEnum.java
  6. 98 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/CardStatusEnum.java
  7. 90 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserAccountStatusEnum.java
  8. 1 0
      ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
  9. 12 0
      ruoyi-common/ruoyi-common-sensitive/pom.xml
  10. 44 0
      ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveServiceImpl.java
  11. 9 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/controller/PtParameterController.java
  12. 10 7
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/service/impl/PtParameterServiceImpl.java
  13. 52 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/accouunt/UserAccountBusiness.java
  14. 97 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/card/CardBusiness.java
  15. 54 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/card/CardNoBusiness.java
  16. 0 5
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/domain/bo/PtCardBo.java
  17. 6 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/IPtCardService.java
  18. 23 7
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/impl/PtCardServiceImpl.java
  19. 16 10
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/dubbo/RemoteUserAccountServiceImpl.java
  20. 27 0
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/mapper/PtUserAccountMapper.java
  21. 3 1
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/service/IPtUserAccountService.java
  22. 13 3
      ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/service/impl/PtUserAccountServiceImpl.java
  23. 2 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
  24. 7 10
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
  25. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
  26. 19 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
  27. 5 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
  28. 7 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
  29. 44 20
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

+ 3 - 2
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/RemoteUserAccountService.java

@@ -1,6 +1,7 @@
 package org.dromara.backstage.api;
 
 import org.dromara.backstage.api.domain.bo.RemoteUserAccountBo;
+import org.dromara.common.core.domain.R;
 
 /**
  * name: RemoteUserAccountService
@@ -21,8 +22,8 @@ public interface RemoteUserAccountService {
      */
     Long queryCardTypeByUserId(Long userId);
 
-    //void insertByBo(RemoteUserAccountBo bo);
+    void insertByBo(RemoteUserAccountBo bo);
 
-    //void openAccount(RemoteUserAccountBo bo);
+    R<String> openAccount(RemoteUserAccountBo bo);
 
 }

+ 9 - 0
ruoyi-api/ruoyi-api-backstage/src/main/java/org/dromara/backstage/api/domain/bo/RemoteUserAccountBo.java

@@ -1,5 +1,6 @@
 package org.dromara.backstage.api.domain.bo;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
@@ -38,6 +39,10 @@ public class RemoteUserAccountBo implements Serializable {
      */
     @NotNull(message = "部门Id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long deptId;
+    /**
+     * 账户名/登录账号
+     */
+    private String userName;
     /**
      * 学/工号
      */
@@ -54,6 +59,10 @@ public class RemoteUserAccountBo implements Serializable {
      */
     @NotBlank(message = "手机号码不能为空", groups = { AddGroup.class, EditGroup.class })
     private String phone;
+    /**
+     * 身份证号
+     */
+    private String idNumber;
     /**
      * 一卡通账户状态(0-未开户  1-已开户  -1已销户)
      */

+ 4 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java

@@ -117,4 +117,8 @@ public interface CacheNames {
      * 房间信息
      */
     String PT_ROOM = "pt_room";
+    /**
+     * 卡流水号
+     */
+    String  CARD_NO = "card_no";
 }

+ 8 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/Constants.java

@@ -77,6 +77,14 @@ public interface Constants {
      */
     Long TOP_PARENT_ID = 0L;
 
+    /**
+     * 收管理费
+     */
     String TAKE_COMMISSION = "1";
+
+    /**
+     * 自动创建一卡通账户
+     */
+    String AUTO_USER_ACCOUNT = "1";
 }
 

+ 90 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/CardOpenEnum.java

@@ -0,0 +1,90 @@
+package org.dromara.common.core.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * name: OpenCardEnum
+ * package: org.dromara.common.core.enums
+ * description: 一卡通账户开卡情况枚举
+ * date: 2024-09-14 09:29:23 09:29
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+public enum CardOpenEnum {
+    /**
+     * 未开卡
+     */
+    NO(0, "未开卡"),
+    /**
+     * 实体卡
+     */
+    ENTITY(1, "实体卡"),
+    /**
+     * 虚拟卡
+     */
+    VIRTUAL(2, "虚拟卡");
+
+    private final Integer code;
+    private final String message;
+
+    CardOpenEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return this.code;
+    }
+
+    public String message() {
+        return this.message;
+    }
+
+    public static String getMessage(String name) {
+        for (CardOpenEnum item : CardOpenEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.message;
+            }
+        }
+        return name;
+    }
+
+    public static String getMessage(int code) {
+        for (CardOpenEnum item : CardOpenEnum.values()) {
+            if (item.code().equals(code)) {
+                return item.message;
+            }
+        }
+        return "未知";
+    }
+
+    public static Integer getCode(String name) {
+        for (CardOpenEnum item : CardOpenEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.code;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+
+    /***
+     * 校验重复的code值
+     */
+    public static void main(String[] args) {
+        CardOpenEnum[] thisEnums = CardOpenEnum.values();
+        List<Integer> codeList = new ArrayList<>();
+        for (CardOpenEnum thisEnum : thisEnums) {
+            if (!codeList.contains(thisEnum.code)) {
+                codeList.add(thisEnum.code());
+            }
+        }
+    }
+}

+ 98 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/CardStatusEnum.java

@@ -0,0 +1,98 @@
+package org.dromara.common.core.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * name: CardStatusEnum
+ * package: org.dromara.common.core.enums
+ * description: 卡片状态枚举
+ * date: 2024-09-14 09:39:13 09:39
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+public enum CardStatusEnum {
+    /**
+     * 正常
+     */
+    NORMAL(1, "正常"),
+    /**
+     * 挂失
+     */
+    LOCK(2, "挂失"),
+    /**
+     * 注销
+     */
+    CLOSE(3, "注销"),
+    /**
+     * 换卡
+     */
+    CHANGE(4, "换卡"),
+    /**
+     * 冻结
+     */
+    FREEZE(7, "冻结");
+
+    private final Integer code;
+    private final String message;
+
+    CardStatusEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return this.code;
+    }
+
+    public String message() {
+        return this.message;
+    }
+
+    public static String getMessage(String name) {
+        for (CardStatusEnum item : CardStatusEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.message;
+            }
+        }
+        return name;
+    }
+
+    public static String getMessage(int code) {
+        for (CardStatusEnum item : CardStatusEnum.values()) {
+            if (item.code().equals(code)) {
+                return item.message;
+            }
+        }
+        return "未知";
+    }
+
+    public static Integer getCode(String name) {
+        for (CardStatusEnum item : CardStatusEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.code;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+
+    /***
+     * 校验重复的code值
+     */
+    public static void main(String[] args) {
+        CardStatusEnum[] thisEnums = CardStatusEnum.values();
+        List<Integer> codeList = new ArrayList<>();
+        for (CardStatusEnum thisEnum : thisEnums) {
+            if (!codeList.contains(thisEnum.code)) {
+                codeList.add(thisEnum.code());
+            }
+        }
+    }
+}

+ 90 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/UserAccountStatusEnum.java

@@ -0,0 +1,90 @@
+package org.dromara.common.core.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * name: UserAccountStatusEnum
+ * package: org.dromara.common.core.enums
+ * description: 一卡通账户状态枚举
+ * date: 2024-09-14 09:08:21 09:08
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+public enum UserAccountStatusEnum {
+    /**
+     * 未开户
+     */
+    NOT_OPEN(0, "未开户"),
+    /**
+     * 已开户
+     */
+    IS_OPEN(1, "已开户"),
+    /**
+     * 已销户
+     */
+    IS_CLOSE(-1, "已销户");
+
+    private final Integer code;
+    private final String message;
+
+    UserAccountStatusEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return this.code;
+    }
+
+    public String message() {
+        return this.message;
+    }
+
+    public static String getMessage(String name) {
+        for (UserAccountStatusEnum item : UserAccountStatusEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.message;
+            }
+        }
+        return name;
+    }
+
+    public static String getMessage(int code) {
+        for (UserAccountStatusEnum item : UserAccountStatusEnum.values()) {
+            if (item.code().equals(code)) {
+                return item.message;
+            }
+        }
+        return "未知";
+    }
+
+    public static Integer getCode(String name) {
+        for (UserAccountStatusEnum item : UserAccountStatusEnum.values()) {
+            if (item.name().equals(name)) {
+                return item.code;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return this.name();
+    }
+
+    /***
+     * 校验重复的code值
+     */
+    public static void main(String[] args) {
+        UserAccountStatusEnum[] thisEnums = UserAccountStatusEnum.values();
+        List<Integer> codeList = new ArrayList<>();
+        for (UserAccountStatusEnum thisEnum : thisEnums) {
+            if (!codeList.contains(thisEnum.code)) {
+                codeList.add(thisEnum.code());
+            }
+        }
+    }
+}

+ 1 - 0
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java

@@ -207,6 +207,7 @@ public class RedisUtils {
      */
     public static <T> T getCacheObject(final String key) {
         RBucket<T> rBucket = CLIENT.getBucket(key);
+
         return rBucket.get();
     }
 

+ 12 - 0
ruoyi-common/ruoyi-common-sensitive/pom.xml

@@ -20,6 +20,18 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-json</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-satoken</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-tenant</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 44 - 0
ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveServiceImpl.java

@@ -0,0 +1,44 @@
+package org.dromara.common.sensitive.core;
+
+import cn.dev33.satoken.stp.StpUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.springframework.stereotype.Service;
+
+/**
+ * 脱敏服务
+ * 默认管理员不过滤
+ * 需自行根据业务重写实现
+ *
+ * @author Lion Li
+ */
+@Service
+public class SensitiveServiceImpl implements SensitiveService {
+    /**
+     * 是否脱敏
+     */
+    @Override
+    public boolean isSensitive(String roleKey, String perms) {
+        if (!LoginHelper.isLogin()) {
+            return true;
+        }
+        boolean roleExist = StringUtils.isNotBlank(roleKey);
+        boolean permsExist = StringUtils.isNotBlank(perms);
+        if (roleExist && permsExist) {
+            if (StpUtil.hasRole(roleKey) && StpUtil.hasPermission(perms)) {
+                return false;
+            }
+        } else if (roleExist && StpUtil.hasRole(roleKey)) {
+            return false;
+        } else if (permsExist && StpUtil.hasPermission(perms)) {
+            return false;
+        }
+
+        if (TenantHelper.isEnable()) {
+            return !LoginHelper.isSuperAdmin() && !LoginHelper.isTenantAdmin();
+        }
+        return !LoginHelper.isSuperAdmin();
+    }
+
+}

+ 9 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/controller/PtParameterController.java

@@ -103,4 +103,13 @@ public class PtParameterController extends BaseController {
                           @PathVariable Long[] paramIds) {
         return toAjax(ptParameterService.deleteWithValidByIds(List.of(paramIds), true));
     }
+    /**
+     * 根据参数键名查询参数值
+     *
+     * @param paramCode 参数Key
+     */
+    @GetMapping(value = "/paramCode/{paramCode}")
+    public R<String> getConfigKey(@PathVariable String paramCode) {
+        return R.ok("操作成功", ptParameterService.selectParamByCode(paramCode));
+    }
 }

+ 10 - 7
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/service/impl/PtParameterServiceImpl.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.dromara.backstage.basics.domain.bo.PtParameterBo;
@@ -85,6 +86,7 @@ public class PtParameterServiceImpl implements IPtParameterService {
      * @param bo 系统参数
      * @return 是否新增成功
      */
+    @Cacheable(cacheNames = CacheNames.PT_PARAMETER, key = "#bo.paramCode")
     @Override
     public Boolean insertByBo(PtParameterBo bo) {
         PtParameter add = MapstructUtils.convert(bo, PtParameter.class);
@@ -102,6 +104,7 @@ public class PtParameterServiceImpl implements IPtParameterService {
      * @param bo 系统参数
      * @return 是否修改成功
      */
+    @CacheEvict(cacheNames = CacheNames.PT_PARAMETER, key = "#bo.paramCode")
     @Override
     public Boolean updateByBo(PtParameterBo bo) {
         PtParameter update = MapstructUtils.convert(bo, PtParameter.class);
@@ -109,13 +112,6 @@ public class PtParameterServiceImpl implements IPtParameterService {
         return baseMapper.updateById(update) > 0;
     }
 
-    /**
-     * 保存前的数据校验
-     */
-    private void validEntityBeforeSave(PtParameter entity){
-        //TODO 做一些数据校验,如唯一约束
-    }
-
     /**
      * 校验并批量删除系统参数信息
      *
@@ -123,6 +119,7 @@ public class PtParameterServiceImpl implements IPtParameterService {
      * @param isValid 是否进行有效性校验
      * @return 是否删除成功
      */
+    @CacheEvict(cacheNames = CacheNames.PT_PARAMETER, allEntries = true)
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
         if(isValid){
@@ -146,4 +143,10 @@ public class PtParameterServiceImpl implements IPtParameterService {
         }
         return StringUtils.EMPTY;
     }
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(PtParameter entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
 }

+ 52 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/accouunt/UserAccountBusiness.java

@@ -0,0 +1,52 @@
+package org.dromara.backstage.business.accouunt;
+
+/**
+ * name: UserAccountBusiness
+ * package: org.dromara.backstage.business.accouunt
+ * description: 一卡通账户业务处理逻辑
+ * date: 2024-09-14 10:45:04 10:45
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+
+import cn.hutool.core.bean.BeanUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.backstage.business.card.CardBusiness;
+import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
+import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
+import org.dromara.backstage.payment.service.IPtBagService;
+import org.dromara.backstage.payment.service.IPtUserAccountService;
+import org.dromara.common.core.domain.R;
+import org.springframework.stereotype.Service;
+
+import java.text.MessageFormat;
+
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class UserAccountBusiness {
+    private final IPtUserAccountService ptUserAccountService;
+    private final IPtBagService bagService;
+    private final CardBusiness cardBusiness;
+
+    /**
+     * 开通一卡通账户
+     * @param bo 一卡通账户业务
+     * @return 开通结果
+     */
+    public R<String> openAccount(PtUserAccountBo bo) {
+        //写账户表
+        boolean flag = ptUserAccountService.insertByBo(bo);
+        if (flag) {
+            //写账户表成功,初始化钱包表
+            bagService.initAccountBag(bo.getUserId());
+            //钱包表初始化成功,同时发虚拟卡
+            PtCardBo cardBo = BeanUtil.copyProperties(bo, PtCardBo.class);
+            return cardBusiness.openVirtualCard(cardBo);
+        }
+        return R.fail(MessageFormat.format("[一卡通开户]-[失败]-[写账户表失败,开户Id:{0}]", bo.getUserId()));
+    }
+}

+ 97 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/card/CardBusiness.java

@@ -0,0 +1,97 @@
+package org.dromara.backstage.business.card;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
+import org.dromara.backstage.cardCenter.service.IPtCardService;
+import org.dromara.backstage.payment.domain.bo.PtBagBo;
+import org.dromara.backstage.payment.domain.vo.PtBagVo;
+import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
+import org.dromara.backstage.payment.service.IPtBagService;
+import org.dromara.backstage.payment.service.IPtUserAccountService;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.enums.CardOpenEnum;
+import org.dromara.common.core.enums.CardStatusEnum;
+import org.dromara.common.core.enums.UserAccountStatusEnum;
+import org.springframework.stereotype.Service;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+/**
+ * name: CardBusiness
+ * package: org.dromara.backstage.business.card
+ * description: 卡片业务处理
+ * date: 2024-09-12 20:25:23 20:25
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class CardBusiness {
+    private final IPtCardService ptCardService;
+    private final IPtUserAccountService userAccountService;
+    private final CardNoBusiness cardNoBusiness;
+    private final IPtBagService ptBagService;
+    public R<String> openVirtualCard(PtCardBo cardBo){
+        String resultMsg;
+        //验证是否存在开通虚拟卡的账户
+        PtUserAccountVo userAccountVo = userAccountService.queryById(cardBo.getUserId());
+        if(userAccountVo == null){
+            resultMsg = MessageFormat.format("[开通虚拟卡]-[失败]-[无此账户,账户Id:{0}]", cardBo.getUserId());
+            log.info(resultMsg);
+            return R.fail(resultMsg);
+        }
+        if(Integer.parseInt(userAccountVo.getAccountStatus())!= UserAccountStatusEnum.IS_OPEN.code()){
+            resultMsg = MessageFormat.format("[开通虚拟卡]-[失败]-[此账户尚未开户,账户Id:{0}]", cardBo.getUserId());
+            log.info(resultMsg);
+            return R.fail(resultMsg);
+        }
+        //检查当前账户是否存在正常、挂失或冻结的卡片,如果有这些卡片,表明账户是发过卡的,无须再开通虚拟卡
+        String cardInfo = ptCardService.selectAccountCardByIds(cardBo.getUserId().toString());
+        if(CardOpenEnum.NO.message().equals(cardInfo)){
+            //没有卡片,开通虚拟卡
+            PtCardBo addBo = BeanUtil.copyProperties(cardBo, PtCardBo.class);
+            addBo.setMainCard("Y");
+            addBo.setStatus(CardStatusEnum.NORMAL.code().toString());
+            addBo.setCardNo(cardNoBusiness.getCardNo());
+            addBo.setFactoryId(0L);
+            addBo.setChangeTime(DateUtil.date());
+
+            if(ptCardService.insertByBo(addBo)){
+                //写卡片表成功,检查一下是否还需要初始化钱包表
+                PtBagBo bagBo = new PtBagBo();
+                bagBo.setUserId(cardBo.getUserId());
+                List<PtBagVo> bagVos = ptBagService.queryList(bagBo);
+                if(bagVos==null || bagVos.isEmpty()){
+                    //如果没有钱包数据,初始化钱包数据
+                    if(ptBagService.initAccountBag(cardBo.getUserId())){
+                        resultMsg = MessageFormat.format("[开通虚拟卡]-[成功]-[开卡账户Id:{0}]", cardBo.getUserId());
+                        return R.ok(resultMsg);
+                    } else {
+                        resultMsg = MessageFormat.format("[开通虚拟卡]-[失败]-[写钱包数据表失败,账户Id:{0}]", cardBo.getUserId());
+                        log.info(resultMsg);
+                        return R.fail(resultMsg);
+                    }
+                } else {
+                    //已有钱包数据,不需要再初始化钱包,直接返回成功
+                    resultMsg = MessageFormat.format("[开通虚拟卡]-[成功]-[开卡账户Id:{0}]", cardBo.getUserId());
+                    return R.ok(resultMsg);
+                }
+            } else {
+                resultMsg = MessageFormat.format("[开通虚拟卡]-[失败]-[写卡片数据表失败,账户Id:{0}]", cardBo.getUserId());
+                log.info(resultMsg);
+                return R.fail(resultMsg);
+            }
+        } else {
+            //已开过卡了,无须再开虚拟卡,直接返回成功
+            resultMsg = MessageFormat.format("[开通虚拟卡]-[成功]-[账户已有卡片,开卡账户Id:{0}]", cardBo.getUserId());
+            return R.ok(resultMsg);
+        }
+    }
+}

+ 54 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/business/card/CardNoBusiness.java

@@ -0,0 +1,54 @@
+package org.dromara.backstage.business.card;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.backstage.cardCenter.service.IPtCardService;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * name: CardNoBusiness
+ * package: org.dromara.backstage.business.card
+ * description: 卡流水号处理业务
+ * 每天定时生成可用的卡流水号并写入缓存,发卡时顺序获取
+ * date: 2024-09-12 20:34:45 20:34
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+@RequiredArgsConstructor
+@Service
+@Slf4j
+public class CardNoBusiness implements CommandLineRunner {
+    private final IPtCardService ptCardService;
+
+    private static final LinkedBlockingQueue<Integer> concurrentLinkedQueue = new LinkedBlockingQueue<Integer>();
+
+    @Scheduled(cron = "0 0 1 * * ?")
+    public void setCardNo() {
+        synchronized (concurrentLinkedQueue) {
+            concurrentLinkedQueue.clear();
+            long maxCardNo = 100;
+            Long dbCardNo = ptCardService.getMaxCardNo();
+            maxCardNo = maxCardNo > dbCardNo ? maxCardNo : dbCardNo;
+            for (long i = maxCardNo+1; i < maxCardNo+10000; i++) {
+                concurrentLinkedQueue.add(Math.toIntExact(i));
+            }
+        }
+    }
+    public Long getCardNo() {
+        synchronized (concurrentLinkedQueue) {
+            return Long.valueOf(Objects.requireNonNull(concurrentLinkedQueue.poll()));
+        }
+    }
+
+    @Override
+    public void run(String... args) throws Exception {
+        setCardNo();
+    }
+}

+ 0 - 5
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/domain/bo/PtCardBo.java

@@ -25,7 +25,6 @@ public class PtCardBo extends BaseEntity {
     /**
      * 卡片Id,主键
      */
-    @NotNull(message = "卡片Id,主键不能为空", groups = { EditGroup.class })
     private Long cardId;
 
     /**
@@ -37,7 +36,6 @@ public class PtCardBo extends BaseEntity {
     /**
      * 卡流水号
      */
-    @NotNull(message = "卡流水号不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long cardNo;
 
     /**
@@ -55,19 +53,16 @@ public class PtCardBo extends BaseEntity {
     /**
      * 物理卡号
      */
-    @NotNull(message = "物理卡号不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long factoryId;
 
     /**
      * 是否主卡,见sys_yes_no字典类别
      */
-    @NotBlank(message = "是否主卡,见sys_yes_no字典类别不能为空", groups = { AddGroup.class, EditGroup.class })
     private String mainCard;
 
     /**
      * 卡片状态,见KZT字典类别
      */
-    @NotBlank(message = "卡片状态,见KZT字典类别不能为空", groups = { AddGroup.class, EditGroup.class })
     private String status;
 
     /**

+ 6 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/IPtCardService.java

@@ -134,4 +134,10 @@ public interface IPtCardService {
      * @return 卡片信息
      */
     PtCardVo queryCardByCardNo(Long cardNo);
+
+    /**
+     * 获取已有的最大卡流水号
+     * @return 最大卡流水号
+     */
+    Long getMaxCardNo();
 }

+ 23 - 7
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/cardCenter/service/impl/PtCardServiceImpl.java

@@ -3,6 +3,7 @@ package org.dromara.backstage.cardCenter.service.impl;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -18,8 +19,8 @@ import org.dromara.backstage.cardCenter.service.IPtCardService;
 import org.dromara.backstage.payment.domain.bo.PtBagBo;
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.enums.CardOpenEnum;
 import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -209,15 +210,15 @@ public class PtCardServiceImpl implements IPtCardService {
     public String selectAccountCardByIds(String userIds) {
         List<String> list = new ArrayList<>();
         for (Long id : StringUtils.splitTo(userIds, Convert::toLong)) {
-            PtCardBo bo = new PtCardBo();
-            bo.setStatus("1");
-            bo.setUserId(id);
+            LambdaQueryWrapper<PtCard> lqw = new LambdaQueryWrapper<>();
+            lqw.eq(PtCard::getUserId, id);
+            lqw.in(PtCard::getStatus,"1","2","7");
 
-            List<PtCardVo> listVo = SpringUtils.getAopProxy(this).queryList(bo);
+            List<PtCardVo> listVo = baseMapper.selectVoList(lqw,PtCardVo.class);
             if (listVo.isEmpty()) {
-                list.add("未发卡");
+                list.add(CardOpenEnum.NO.message());
             } else {
-                String cardInfo = listVo.stream().anyMatch(p -> p.getFactoryId() == 0) ? "虚拟卡" : "实体卡";
+                String cardInfo = listVo.stream().anyMatch(p -> p.getFactoryId() == 0) ? CardOpenEnum.VIRTUAL.message() : CardOpenEnum.ENTITY.message();
                 list.add(cardInfo);
             }
         }
@@ -326,4 +327,19 @@ public class PtCardServiceImpl implements IPtCardService {
         }
         return null;
     }
+
+    /**
+     * 获取已有的最大卡流水号
+     * @return 最大卡流水号
+     */
+    @Override
+    public Long getMaxCardNo() {
+        QueryWrapper<PtCard> lqw = new QueryWrapper<>();
+        lqw.select("max(card_no) as card_no");
+        lqw.in("status", "1","2","7");
+        lqw.eq("tenant_id", "20200813044411");
+        PtCard card = baseMapper.selectOne(lqw);
+
+        return card.getCardNo();
+    }
 }

+ 16 - 10
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/dubbo/RemoteUserAccountServiceImpl.java

@@ -1,9 +1,14 @@
 package org.dromara.backstage.payment.dubbo;
 
+import cn.hutool.core.bean.BeanUtil;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.backstage.api.RemoteUserAccountService;
+import org.dromara.backstage.api.domain.bo.RemoteUserAccountBo;
+import org.dromara.backstage.business.accouunt.UserAccountBusiness;
+import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.service.IPtUserAccountService;
+import org.dromara.common.core.domain.R;
 import org.springframework.stereotype.Service;
 
 /**
@@ -21,6 +26,7 @@ import org.springframework.stereotype.Service;
 @DubboService
 public class RemoteUserAccountServiceImpl implements RemoteUserAccountService {
     private final IPtUserAccountService userAccountService;
+    private final UserAccountBusiness userAccountBusiness;
     /**
      * 根据人员账户Id获取账户的卡类
      *
@@ -32,15 +38,15 @@ public class RemoteUserAccountServiceImpl implements RemoteUserAccountService {
         return userAccountService.queryById(userId).getCardType();
     }
 
-    //@Override
-    //public void insertByBo(RemoteUserAccountBo bo) {
-    //    PtUserAccountBo ptUserAccountBo = BeanUtil.copyProperties(bo, PtUserAccountBo.class);
-    //    userAccountService.insertByBo(ptUserAccountBo);
-    //}
+    @Override
+    public void insertByBo(RemoteUserAccountBo bo) {
+        PtUserAccountBo ptUserAccountBo = BeanUtil.copyProperties(bo, PtUserAccountBo.class);
+        userAccountService.insertByBo(ptUserAccountBo);
+    }
 
-    //@Override
-    //public void openAccount(RemoteUserAccountBo bo) {
-    //    PtUserAccountBo ptUserAccountBo = BeanUtil.copyProperties(bo, PtUserAccountBo.class);
-    //    userAccountService.openAccount(ptUserAccountBo);
-    //}
+    @Override
+    public R<String> openAccount(RemoteUserAccountBo bo) {
+        PtUserAccountBo ptUserAccountBo = BeanUtil.copyProperties(bo, PtUserAccountBo.class);
+        return userAccountBusiness.openAccount(ptUserAccountBo);
+    }
 }

+ 27 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/mapper/PtUserAccountMapper.java

@@ -1,15 +1,25 @@
 package org.dromara.backstage.payment.mapper;
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
+import org.apache.poi.ss.formula.functions.T;
+import org.checkerframework.checker.units.qual.C;
 import org.dromara.backstage.basics.domain.PtOperator;
 import org.dromara.backstage.basics.domain.vo.PtOperatorVo;
 import org.dromara.backstage.payment.domain.PtUserAccount;
 import org.dromara.backstage.payment.domain.vo.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
+import java.util.List;
+
 /**
  * 一卡通账户Mapper接口
  *
@@ -20,4 +30,21 @@ public interface PtUserAccountMapper extends BaseMapperPlus<PtUserAccount, PtUse
 
     Page<PtUserAccount4SelectVo> customPageList(@Param("page") Page<PtUserAccount> page, @Param("ew") Wrapper<PtUserAccount> wrapper);
 
+    @Override
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+    })
+    List<PtUserAccount> selectList(@Param(Constants.WRAPPER) Wrapper<PtUserAccount> queryWrapper);
+
+    default Page<PtUserAccountVo>customSelectVoPage(Page<PtUserAccount> page, Wrapper<PtUserAccount> wrapper){
+        // 根据条件分页查询实体对象列表
+        List<PtUserAccount> list = this.selectList(page, wrapper);
+        // 创建一个新的VO对象分页列表,并设置分页信息
+        Page<PtUserAccountVo> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
+        if (CollUtil.isEmpty(list)) {
+            return voPage;
+        }
+        voPage.setRecords(MapstructUtils.convert(list, PtUserAccountVo.class));
+        return voPage;
+    }
 }

+ 3 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/service/IPtUserAccountService.java

@@ -3,6 +3,7 @@ package org.dromara.backstage.payment.service;
 import org.dromara.backstage.payment.domain.vo.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.springframework.web.multipart.MultipartFile;
@@ -136,10 +137,11 @@ public interface IPtUserAccountService {
 
     /**
      * 开户
+     *
      * @param bo 账户业务对象
      * @return 开户结果
      */
-    int openAccount(PtUserAccountBo bo);
+    R<String> openAccount(PtUserAccountBo bo);
     /*
      * 销户
      *

+ 13 - 3
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/service/impl/PtUserAccountServiceImpl.java

@@ -1,14 +1,17 @@
 package org.dromara.backstage.payment.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.lang.UUID;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.backstage.cardCenter.domain.bo.PtCardBo;
 import org.dromara.backstage.cardCenter.service.IPtCardService;
 import org.dromara.backstage.payment.domain.vo.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.service.IPtBagService;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.file.FileUtils;
@@ -30,6 +33,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.text.MessageFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -47,6 +51,7 @@ public class PtUserAccountServiceImpl implements IPtUserAccountService {
     private final PtUserAccountMapper baseMapper;
     private final IPtCardService ptCardService;
     private final IPtBagService bagService;
+    //private final CardBusiness cardBusiness;
 
     @DubboReference
     private final RemoteDeptService remoteDeptService;
@@ -79,7 +84,8 @@ public class PtUserAccountServiceImpl implements IPtUserAccountService {
         LambdaQueryWrapper<PtUserAccount> lqw = buildQueryWrapper(bo);
         lqw.orderByAsc(PtUserAccount::getDeptId)
             .orderByAsc(PtUserAccount::getRealName);
-        Page<PtUserAccountVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        //Page<PtUserAccountVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        Page<PtUserAccountVo> result = baseMapper.customSelectVoPage(pageQuery.build(), lqw);
         return TableDataInfo.build(result);
     }
 
@@ -329,11 +335,12 @@ public class PtUserAccountServiceImpl implements IPtUserAccountService {
     }
     /**
      * 开户
+     *
      * @param bo 账户业务对象
      * @return 开户结果
      */
     @Override
-    public int openAccount(PtUserAccountBo bo) {
+    public R<String> openAccount(PtUserAccountBo bo) {
         PtUserAccount add = MapstructUtils.convert(bo, PtUserAccount.class);
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;
@@ -342,8 +349,11 @@ public class PtUserAccountServiceImpl implements IPtUserAccountService {
                 bo.setUserId(add.getUserId());
             }
             bagService.initAccountBag(bo.getUserId());
+            PtCardBo cardBo = BeanUtil.copyProperties(add, PtCardBo.class);
+            //return cardBusiness.openVirtualCard(cardBo);
+
         }
-        return 0;
+        return R.fail(MessageFormat.format("[一卡通开户]-[失败]-[写账户表失败,开户Id:{0}]",bo.getUserId()));
     }
 
     /*

+ 2 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java

@@ -71,10 +71,10 @@ public class SysProfileController extends BaseController {
         SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
         user.setUserId(LoginHelper.getUserId());
         String username = LoginHelper.getUsername();
-        if (StringUtils.isNotEmpty(user.getPhone()) && !userService.checkPhoneUnique(user)) {
+        if (StringUtils.isNotEmpty(user.getPhone()) && userService.checkPhoneUnique(user)) {
             return R.fail("修改用户'" + username + "'失败,手机号码已存在");
         }
-        if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+        if (StringUtils.isNotEmpty(user.getEmail()) && userService.checkEmailUnique(user)) {
             return R.fail("修改用户'" + username + "'失败,邮箱账号已存在");
         }
         if (userService.updateUserProfile(user) > 0) {

+ 7 - 10
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java

@@ -154,18 +154,17 @@ public class SysUserController extends BaseController {
     @PostMapping
     public R<Void> add(@Validated @RequestBody SysUserBo user) {
         deptService.checkDeptDataScope(user.getDeptId());
-        if (!userService.checkUserNameUnique(user)) {
+        if (userService.checkUserNameUnique(user)) {
             return R.fail("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
-        } else if (StringUtils.isNotEmpty(user.getPhone()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
-        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
+        } else if (StringUtils.isNotEmpty(user.getUserNumb()) && userService.checkUserNumbUnique(user)) {
+            return R.fail("新增用户'" + user.getUserName() + "'失败,学/工号已存在");
         }
         if (TenantHelper.isEnable()) {
             if (!tenantService.checkAccountBalance(TenantHelper.getTenantId())) {
                 return R.fail("当前租户下用户名额不足,请联系管理员");
             }
         }
+        user.setNickName(user.getRealName());
         user.setPassword(BCrypt.hashpw(user.getPassword()));
         return toAjax(userService.insertUser(user));
     }
@@ -180,12 +179,10 @@ public class SysUserController extends BaseController {
         userService.checkUserAllowed(user.getUserId());
         userService.checkUserDataScope(user.getUserId());
         deptService.checkDeptDataScope(user.getDeptId());
-        if (!userService.checkUserNameUnique(user)) {
+        if (userService.checkUserNameUnique(user)) {
             return R.fail("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
-        } else if (StringUtils.isNotEmpty(user.getPhone()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
-        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
+        } else if (StringUtils.isNotEmpty(user.getUserNumb()) && userService.checkUserNumbUnique(user)) {
+            return R.fail("修改用户'" + user.getUserName() + "'失败,学/工号已存在");
         }
         return toAjax(userService.updateUser(user));
     }

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java

@@ -66,6 +66,7 @@ public class SysUser extends TenantEntity {
     /**
      * 身份证号
      */
+    @EncryptField(algorithm = AlgorithmType.BASE64)
     private String idNumber;
 
     /**

+ 19 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java

@@ -3,15 +3,20 @@ package org.dromara.system.domain.bo;
 import io.github.linpeilie.annotations.AutoMapper;
 import jakarta.validation.constraints.Email;
 import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.core.xss.Xss;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.system.domain.SysUser;
 
+import java.util.Date;
+
 /**
  * 用户信息业务对象 sys_user
  *
@@ -118,6 +123,20 @@ public class SysUserBo extends BaseEntity {
      */
     private Long roleId;
 
+    /**
+     * 账户卡片类型
+     */
+    private Long cardType;
+
+    /**
+     * 账户有效期
+     */
+    private Date lifespan;
+
+    /**
+     * 身份证号
+     */
+    private String idNumber;
     /**
      * 排除不查询的用户(工作流用)
      */

+ 5 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java

@@ -77,7 +77,7 @@ public class SysUserVo implements Serializable {
     /**
      * 用户邮箱
      */
-    @Sensitive(strategy = SensitiveStrategy.EMAIL)
+    //@Sensitive(strategy = SensitiveStrategy.EMAIL,perms = "system:user:query")
     private String email;
 
     /**
@@ -91,6 +91,10 @@ public class SysUserVo implements Serializable {
      */
     private String sex;
 
+    /**
+     * 身份证号
+     */
+    private String idNumber;
     /**
      * 头像地址
      */

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java

@@ -115,6 +115,13 @@ public interface ISysUserService {
      */
     boolean checkEmailUnique(SysUserBo user);
 
+    /**
+     * 校验学/工号是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    boolean checkUserNumbUnique(SysUserBo user);
     /**
      * 校验用户是否允许操作
      *

+ 44 - 20
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

@@ -18,8 +18,12 @@ import org.dromara.backstage.api.RemotePtParameterService;
 import org.dromara.backstage.api.RemoteUserAccountService;
 import org.dromara.backstage.api.domain.bo.RemoteUserAccountBo;
 import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.HttpStatus;
 import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.domain.R;
 import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.exception.user.UserException;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StreamUtils;
@@ -73,7 +77,7 @@ public class SysUserServiceImpl implements ISysUserService {
 
     @Override
     public TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery) {
-        Page<SysUserVo> page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user));
+        Page<SysUserVo> page = baseMapper.selectVoPage(pageQuery.build(), this.buildQueryWrapper(user));
         return TableDataInfo.build(page);
     }
 
@@ -91,24 +95,24 @@ public class SysUserServiceImpl implements ISysUserService {
     private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
         Map<String, Object> params = user.getParams();
         QueryWrapper<SysUser> wrapper = Wrappers.query();
-        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
-            .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
-            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
-            .like(StringUtils.isNotBlank(user.getRealName()), "u.real_name", user.getRealName())
-            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
-            .like(StringUtils.isNotBlank(user.getPhone()), "u.phone", user.getPhone())
+        wrapper.eq("del_flag", UserConstants.USER_NORMAL)
+            .eq(ObjectUtil.isNotNull(user.getUserId()), "user_id", user.getUserId())
+            .like(StringUtils.isNotBlank(user.getUserName()), "user_name", user.getUserName())
+            .like(StringUtils.isNotBlank(user.getRealName()), "real_name", user.getRealName())
+            .eq(StringUtils.isNotBlank(user.getStatus()), "status", user.getStatus())
+            .like(StringUtils.isNotBlank(user.getPhone()), "phone", user.getPhone())
             .between(params.get("beginTime") != null && params.get("endTime") != null,
-                "u.create_time", params.get("beginTime"), params.get("endTime"))
+                "create_time", params.get("beginTime"), params.get("endTime"))
             .and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
                 List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                     .select(SysDept::getDeptId)
                     .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors")));
                 List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
                 ids.add(user.getDeptId());
-                w.in("u.dept_id", ids);
-            }).orderByAsc("u.user_id");
+                w.in("dept_id", ids);
+            }).orderByAsc("user_id");
         if (StringUtils.isNotBlank(user.getExcludeUserIds())) {
-            wrapper.notIn("u.user_id", StringUtils.splitList(user.getExcludeUserIds()));
+            wrapper.notIn("user_id", StringUtils.splitList(user.getExcludeUserIds()));
         }
         return wrapper;
     }
@@ -247,7 +251,7 @@ public class SysUserServiceImpl implements ISysUserService {
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getUserName, user.getUserName())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
+        return exist;
     }
 
     /**
@@ -257,10 +261,9 @@ public class SysUserServiceImpl implements ISysUserService {
      */
     @Override
     public boolean checkPhoneUnique(SysUserBo user) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
+        return baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getPhone, user.getPhone())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
     }
 
     /**
@@ -273,7 +276,19 @@ public class SysUserServiceImpl implements ISysUserService {
         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
             .eq(SysUser::getEmail, user.getEmail())
             .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
-        return !exist;
+        return exist;
+    }
+
+    /**
+     * 校验学/工号是否唯一
+     *
+     * @param user 用户信息
+     */
+    @Override
+    public boolean checkUserNumbUnique(SysUserBo user) {
+        return baseMapper.exists(new LambdaQueryWrapper<SysUser>()
+            .eq(SysUser::getUserNumb, user.getUserNumb())
+            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
     }
 
     /**
@@ -325,14 +340,23 @@ public class SysUserServiceImpl implements ISysUserService {
          insertUserDept(user);
         // 新增用户与角色管理
         insertUserRole(user, false);
+        //一卡通账户处理
         String autoUserAccount = remotePtParameterService.getPtParameterByKey("AUTO_CREATE_BAG");
         RemoteUserAccountBo remoteUserAccountBo = BeanUtil.copyProperties(user, RemoteUserAccountBo.class);
-        //if("1".equals(autoUserAccount)){
-        //
-        //} else {
+        if(Constants.AUTO_USER_ACCOUNT.equals(autoUserAccount)){
+            //自动开通一卡通账户
+            remoteUserAccountBo.setAccountStatus("1");
+            R<String> result = remoteUserAccountService.openAccount(remoteUserAccountBo);
+            if(result.getCode()== HttpStatus.SUCCESS){
+                return rows;
+            } else {
+                throw new UserException(result.getMsg());
+            }
+        } else {
+            //不自动开通
           remoteUserAccountBo.setAccountStatus("0");
-          //remoteUserAccountService.insertByBo(remoteUserAccountBo);
-        //}
+          remoteUserAccountService.insertByBo(remoteUserAccountBo);
+        }
         return rows;
     }