diff --git a/agileboot-admin/src/main/java/com/agileboot/admin/controller/ab98/Ab98UserController.java b/agileboot-admin/src/main/java/com/agileboot/admin/controller/ab98/Ab98UserController.java index aba26a9..4da3d9b 100644 --- a/agileboot-admin/src/main/java/com/agileboot/admin/controller/ab98/Ab98UserController.java +++ b/agileboot-admin/src/main/java/com/agileboot/admin/controller/ab98/Ab98UserController.java @@ -56,6 +56,13 @@ public class Ab98UserController extends BaseController { return ResponseDTO.ok(page); } + @Operation(summary = "带微信信息的用户列表") + @GetMapping("/withWx") + public ResponseDTO> listWithWx(SearchAb98UserQuery query) { + PageDTO page = userApplicationService.getUserListWithWx(query); + return ResponseDTO.ok(page); + } + @Operation(summary = "用户详情") @GetMapping("/detail/{id}") public ResponseDTO detail(@PathVariable Long id, String corpid) { diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/Ab98UserApplicationService.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/Ab98UserApplicationService.java index 6a0ac32..5c75d4f 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/Ab98UserApplicationService.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/Ab98UserApplicationService.java @@ -55,6 +55,14 @@ public class Ab98UserApplicationService { return new PageDTO<>(dtoList, page.getTotal()); } + public PageDTO getUserListWithWx(SearchAb98UserQuery query) { + Page page = userService.getUserListWithWx(query); + List dtoList = page.getRecords().stream() + .map(Ab98UserDTO::new) + .collect(Collectors.toList()); + return new PageDTO<>(dtoList, page.getTotal()); + } + public void addUser(AddAb98UserCommand command) { Ab98UserModel model = userModelFactory.create(); model.loadAddCommand(command); diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserEntity.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserEntity.java index c807527..414c9ea 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserEntity.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserEntity.java @@ -91,6 +91,18 @@ public class Ab98UserEntity extends BaseEntity { @TableField(exist = false) private Long balanceLimit; + @ApiModelProperty("微信用户ID") + @TableField(exist = false) + private Long wxUserId; + + @ApiModelProperty("微信用户openid") + @TableField(exist = false) + private String wxUserOpenid; + + @ApiModelProperty("微信用户昵称") + @TableField(exist = false) + private String wxNickName; + @Override public Serializable pkVal() { diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserMapper.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserMapper.java index 7c6c07b..adf830f 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserMapper.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserMapper.java @@ -60,6 +60,23 @@ public interface Ab98UserMapper extends BaseMapper { @Param(Constants.WRAPPER) Wrapper queryWrapper ); + @Select("SELECT * FROM (" + + "SELECT DISTINCT u.ab98_user_id, u.openid, u.userid, u.qy_user_id, u.name, u.tel, u.idnum, u.sex, u.face_img, u.idcard_front, u.idcard_back, u.address, u.registered, u.creator_id, u.create_time, u.updater_id, u.update_time, u.deleted, u.ab98_balance, ub.balance, ub.use_balance, ub.balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name " + + "FROM ab98_user u " + + "LEFT JOIN ab98_user_tag t ON u.ab98_user_id = t.ab98_user_id " + + "LEFT JOIN user_balance ub ON u.ab98_user_id = ub.ab98_user_id " + + "LEFT JOIN wx_user w ON u.ab98_user_id = w.ab98_user_id " + + "${ew.customSqlSegment}" + + " UNION ALL " + + "SELECT NULL as ab98_user_id, NULL as openid, NULL as userid, NULL as qy_user_id, NULL as name, NULL as tel, NULL as idnum, NULL as sex, NULL as face_img, NULL as idcard_front, NULL as idcard_back, NULL as address, NULL as registered, NULL as creator_id, w.create_time as create_time, NULL as updater_id, w.update_time as update_time, NULL as deleted, NULL as ab98_balance, NULL as balance, NULL as use_balance, NULL as balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name " + + "FROM wx_user w " + + "WHERE w.ab98_user_id IS NULL" + + ") t ORDER BY create_time DESC") + Page getUserListWithWx( + Page page, + @Param(Constants.WRAPPER) Wrapper queryWrapper + ); + @Select("SELECT DISTINCT u.*, ub.balance, ub.use_balance, ub.balance_limit " + "FROM ab98_user u " + "LEFT JOIN user_balance ub ON u.ab98_user_id = ub.ab98_user_id " + diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserService.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserService.java index 2142e20..26f4eb9 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserService.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserService.java @@ -20,6 +20,8 @@ import java.util.List; public interface Ab98UserService extends IService { Page getUserListWithTagFilter(AbstractPageQuery query); + Page getUserListWithWx(AbstractPageQuery query); + List getUserListWithBalance(Wrapper wrapper); List selectAll(); diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserServiceImpl.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserServiceImpl.java index b3ae24d..e84e73c 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserServiceImpl.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/db/Ab98UserServiceImpl.java @@ -26,6 +26,11 @@ public class Ab98UserServiceImpl extends ServiceImpl getUserListWithWx(AbstractPageQuery query) { + return baseMapper.getUserListWithWx(query.toPage(), query.toQueryWrapper()); + } + @Override public List selectAll() { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/dto/Ab98UserDTO.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/dto/Ab98UserDTO.java index d62187d..5a79bf5 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/dto/Ab98UserDTO.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/dto/Ab98UserDTO.java @@ -16,11 +16,30 @@ public class Ab98UserDTO { if (entity != null) { BeanUtil.copyProperties(entity, this); - this.registeredStatus = entity.getRegistered() ? "已注册" : "未注册"; + this.registeredStatus = entity.getRegistered() != null && entity.getRegistered() ? "已注册" : "未注册"; - // 处理身份证号码,隐藏中间8位 - if (this.idnum != null && this.idnum.length() >= 10) { - this.idnum = this.idnum.substring(0, 6) + "********" + this.idnum.substring(this.idnum.length() - 4); + // 处理身份证号码,隐藏除前4位和后2位之外的所有字符 + if (this.idnum != null && this.idnum.length() >= 6) { + int hiddenLength = this.idnum.length() - 6; // 需要隐藏的字符数 + if (hiddenLength > 0) { + StringBuilder stars = new StringBuilder(); + for (int i = 0; i < hiddenLength; i++) { + stars.append("*"); + } + this.idnum = this.idnum.substring(0, 4) + stars.toString() + this.idnum.substring(this.idnum.length() - 2); + } + } + + // 处理手机号码,隐藏除前3位和后2位之外的所有字符 + if (this.tel != null && this.tel.length() >= 5) { + int hiddenLength = this.tel.length() - 5; // 需要隐藏的字符数 + if (hiddenLength > 0) { + StringBuilder stars = new StringBuilder(); + for (int i = 0; i < hiddenLength; i++) { + stars.append("*"); + } + this.tel = this.tel.substring(0, 3) + stars.toString() + this.tel.substring(this.tel.length() - 2); + } } } } @@ -70,6 +89,15 @@ public class Ab98UserDTO { @ExcelColumn(name = "余额限制(user_balance表,单位:分)") private Long balanceLimit; + @ExcelColumn(name = "微信用户ID") + private Long wxUserId; + + @ExcelColumn(name = "微信用户openid") + private String wxUserOpenid; + + @ExcelColumn(name = "微信用户昵称") + private String wxNickName; + @ExcelColumn(name = "注册状态") private String registeredStatus; diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/query/SearchAb98UserQuery.java b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/query/SearchAb98UserQuery.java index dd47cb5..ed97692 100644 --- a/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/query/SearchAb98UserQuery.java +++ b/agileboot-domain/src/main/java/com/agileboot/domain/ab98/user/query/SearchAb98UserQuery.java @@ -23,6 +23,7 @@ public class SearchAb98UserQuery extends AbstractPageQuery { private Date endTime; private String tagName; private String corpid; + private String wxUserOpenid; @Override public QueryWrapper addQueryCondition() { @@ -41,6 +42,11 @@ public class SearchAb98UserQuery extends AbstractPageQuery { .eq(StrUtil.isNotEmpty(corpid), "ub.corpid", corpid) .between(startTime != null && endTime != null, "u.create_time", startTime, endTime); + // 添加微信用户openid查询条件 + if (StrUtil.isNotEmpty(wxUserOpenid)) { + queryWrapper.apply("wx_user_openid = {0}", wxUserOpenid); + } + this.timeRangeColumn = "create_time"; return queryWrapper; diff --git a/doc/sql/wxUser.sql b/doc/sql/wxUser.sql new file mode 100644 index 0000000..ae315f0 --- /dev/null +++ b/doc/sql/wxUser.sql @@ -0,0 +1,91 @@ +-- wxshop.ab98_user definition + +CREATE TABLE `ab98_user` ( + `ab98_user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'openid', + `userid` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '汇邦云用户唯一ID', + `qy_user_id` bigint DEFAULT NULL COMMENT '企业用户id', + `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '真实姓名', + `tel` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '手机号码', + `idnum` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '身份证号码', + `sex` char(8) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '性别(男 女)', + `face_img` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '人脸照片地址', + `idcard_front` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '身份证正面地址', + `idcard_back` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '身份证背面地址', + `address` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '身份证登记地址', + `registered` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已注册(0未注册 1已注册)', + `creator_id` bigint DEFAULT '0' COMMENT '创建者ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater_id` bigint DEFAULT '0' COMMENT '更新者ID', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)', + `ab98_balance` int NOT NULL DEFAULT '0' COMMENT '用户余额(单位:分)', + PRIMARY KEY (`ab98_user_id`), + UNIQUE KEY `uk_idnum` (`idnum`), + KEY `idx_openid` (`openid`), + KEY `idx_tel` (`tel`), + KEY `idx_name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=87 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='汇邦云用户信息表'; + + +-- wxshop.user_balance definition + +CREATE TABLE `user_balance` ( + `user_balance_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `corpid` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业微信id', + `openid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'openid', + `ab98_user_id` bigint NOT NULL COMMENT '汇邦云用户ID', + `qy_user_id` bigint DEFAULT NULL COMMENT '企业用户id', + `balance` bigint NOT NULL DEFAULT '0' COMMENT '用户余额(单位:分)', + `use_balance` bigint NOT NULL DEFAULT '0' COMMENT '用户余额(单位:分)', + `balance_limit` bigint NOT NULL DEFAULT '0' COMMENT '用户余额(单位:分)', + `creator_id` bigint DEFAULT '0' COMMENT '创建者ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater_id` bigint DEFAULT '0' COMMENT '更新者ID', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)', + PRIMARY KEY (`user_balance_id`), + UNIQUE KEY `uk_corpid_user` (`corpid`,`ab98_user_id`), + KEY `idx_openid` (`openid`), + KEY `idx_ab98_user_id` (`ab98_user_id`), + KEY `idx_corpid` (`corpid`) +) ENGINE=InnoDB AUTO_INCREMENT=137 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户余额表'; + + +-- wxshop.wx_user definition + +CREATE TABLE `wx_user` ( + `wx_user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `openid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'openid', + `ab98_user_id` bigint DEFAULT NULL COMMENT '汇邦云用户ID', + `qy_user_id` bigint DEFAULT NULL COMMENT '企业用户id', + `nick_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '昵称', + `tel` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号码', + `wx_balance` int NOT NULL DEFAULT '0' COMMENT '用户余额(单位:分)', + `creator_id` bigint DEFAULT '0' COMMENT '创建者ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater_id` bigint DEFAULT '0' COMMENT '更新者ID', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)', + PRIMARY KEY (`wx_user_id`), + KEY `idx_openid` (`openid`), + KEY `idx_tel` (`tel`), + KEY `idx_nick_name` (`nick_name`) +) ENGINE=InnoDB AUTO_INCREMENT=151 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='微信用户信息表'; + + +-- wxshop.ab98_user_tag definition + +CREATE TABLE `ab98_user_tag` ( + `tag_id` bigint NOT NULL AUTO_INCREMENT COMMENT '标签ID', + `ab98_user_id` bigint NOT NULL COMMENT '关联用户ID', + `tag_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '标签名称', + `creator_id` bigint DEFAULT '0' COMMENT '创建者ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater_id` bigint DEFAULT '0' COMMENT '更新者ID', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志(0存在 1删除)', + PRIMARY KEY (`tag_id`), + KEY `idx_user` (`ab98_user_id`), + CONSTRAINT `fk_tag_user` FOREIGN KEY (`ab98_user_id`) REFERENCES `ab98_user` (`ab98_user_id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户标签表'; \ No newline at end of file