diff --git a/src/main/java/com/budwk/app/sys/models/Sys_user_history.java b/src/main/java/com/budwk/app/sys/models/Sys_user_history.java index 0522a724..f0b60c5e 100644 --- a/src/main/java/com/budwk/app/sys/models/Sys_user_history.java +++ b/src/main/java/com/budwk/app/sys/models/Sys_user_history.java @@ -51,11 +51,6 @@ public class Sys_user_history extends Sys_user { @Comment("变更原因") private String changeReason; - @Column - @ColDefine(type = ColType.VARCHAR, customType = "text") - @Comment("备注") - private String remark; - @Column @Comment("会员变更表记录id") @ColDefine(type = ColType.VARCHAR, width = 32) diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysDataUserAllUpdateServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysDataUserAllUpdateServiceImpl.java index 243b121c..d3448941 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysDataUserAllUpdateServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysDataUserAllUpdateServiceImpl.java @@ -22,11 +22,12 @@ import com.budwk.app.sys.services.SysUserService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig; import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeOrigin; import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType; -import com.budwk.app.zhgh.staffmanage.sourcechange.service.PendingUserHistoryService; import lombok.extern.slf4j.Slf4j; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -51,6 +52,10 @@ import java.util.stream.Collectors; @IocBean public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService { private static final int BATCH_SIZE = 500; + /** 不需要人工确认。 */ + private static final int PENDING_CONFIRM_STATUS_NONE = 0; + /** 数据源缺失,等待人工确认。 */ + private static final int PENDING_CONFIRM_STATUS_PENDING = 1; @Inject private Dao dao; @@ -62,8 +67,6 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService private SysUserService sysUserService; @Inject private ThreadPoolTaskExecutor executorService; - @Inject - private PendingUserHistoryService pendingUserHistoryService; private static Map unitIdNameMap; @@ -177,7 +180,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService * 全量更新已有用户时置空,避免 updateIgnoreNull 把已迁移的基金会员标识覆盖为非会员。 */ u.setAidFundMember(null); - + u.setPersonType(null); needDoUpdateList.add(u); } @@ -292,12 +295,6 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService return "更新失败: " + e.getMessage(); } - /* - * 用户及普通变更记录完成后,再以本次完整源数据校正待确认人员。 - * 该步骤仅存在于 ALL 实现中,增量更新不会误判未包含在增量数据中的系统用户。 - */ - int pendingConfirmCount = pendingUserHistoryService.reconcile(sysUsers, sources); - /* // 4. 异步添加会员角色 - 不等待完成 if (Lang.isNotEmpty(addMemberUserIds)) { executorService.execute(() -> { @@ -355,14 +352,63 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService RoleEventPublisher.broadcast(new RoleEventMsg(unitId, RoleConstant.PROPOSAL_BRANCH_SCHOOL_LEADER.name(), RoleEventMsg.RENEW_ROLE)); } + /* + * 所有异步用户更新完成后再校正待确认状态,避免主事务提前锁定 sys_user, + * 导致异步更新线程等待主事务释放行锁而形成相互等待。 + */ + reconcilePendingConfirmStatus(updateParam.getPullTime()); + long endTime = System.currentTimeMillis(); log.info("全量更新用户数据完成,耗时: {} 毫秒", (endTime - startTime)); - if (needInitUserList.isEmpty() && histories.isEmpty() && pendingConfirmCount == 0) { + if (needInitUserList.isEmpty() && histories.isEmpty()) { return "本次没有可更新的数据。"; } return "更新完成: 新增用户 " + needInitUserList.size() + " 个, 有效变更 " + histories.size() - + " 条, 新增待确认人员 " + pendingConfirmCount + " 人"; + + " 条"; + } + + /** + * 根据指定批次的完整数据源校正系统用户待确认状态。 + * 已人工确认且仍未重新出现的人员保持已确认状态,避免每次全量更新重复转为待确认。 + * + * @param pullTime 本次全量数据的拉取时间 + */ + private void reconcilePendingConfirmStatus(String pullTime) { + Sql resetStatusSql = Sqls.create(""" + UPDATE sys_user userInfo + SET userInfo.pendingConfirmStatus = @noneStatus + WHERE userInfo.personType IN ('教职工', '劳务派遣人员') + AND userInfo.pendingConfirmStatus <> @noneStatus + AND EXISTS ( + SELECT 1 + FROM sys_user_source sourceInfo + WHERE sourceInfo.pullTime = @pullTime + AND sourceInfo.loginname = userInfo.loginname + AND sourceInfo.personType IN ('教职工', '劳务派遣人员') + ) + """); + resetStatusSql.setParam("noneStatus", PENDING_CONFIRM_STATUS_NONE); + resetStatusSql.setParam("pullTime", pullTime); + dao.execute(resetStatusSql); + + Sql pendingStatusSql = Sqls.create(""" + UPDATE sys_user userInfo + SET userInfo.pendingConfirmStatus = @pendingStatus + WHERE userInfo.personType IN ('教职工', '劳务派遣人员') + AND IFNULL(userInfo.pendingConfirmStatus, @noneStatus) = @noneStatus + AND NOT EXISTS ( + SELECT 1 + FROM sys_user_source sourceInfo + WHERE sourceInfo.pullTime = @pullTime + AND sourceInfo.loginname = userInfo.loginname + AND sourceInfo.personType IN ('教职工', '劳务派遣人员') + ) + """); + pendingStatusSql.setParam("pendingStatus", PENDING_CONFIRM_STATUS_PENDING); + pendingStatusSql.setParam("noneStatus", PENDING_CONFIRM_STATUS_NONE); + pendingStatusSql.setParam("pullTime", pullTime); + dao.execute(pendingStatusSql); } /** diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/member/constant/MemberChangeType.java b/src/main/java/com/budwk/app/zhgh/staffmanage/member/constant/MemberChangeType.java index 04404360..48e80c5f 100644 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/member/constant/MemberChangeType.java +++ b/src/main/java/com/budwk/app/zhgh/staffmanage/member/constant/MemberChangeType.java @@ -17,7 +17,6 @@ import lombok.Getter; public enum MemberChangeType { //变更类型 - PENDING_CONFIRM("PENDING_CONFIRM", "待确认"), NEW("NEW", "新入职"), RESTORE("RESTORE", "入会"), WITHDRAWAL("WITHDRAWAL", "退会"), diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeApplyController.java b/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeApplyController.java index e813fca0..9135d09e 100644 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeApplyController.java +++ b/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeApplyController.java @@ -156,7 +156,12 @@ public class MemberChangeApplyController { * @return */ @At - @SaCheckPermission(value = {"member.change.branchUnion.audit","member.change.schoolUnion.audit", "member.change.unionGroup.audit"}, mode = SaMode.OR) + @SaCheckPermission(value = { + "member.change.branchUnion.audit", + "member.change.schoolUnion.audit", + "member.change.unionGroup.audit", + "staff.sourcechange.pending" + }, mode = SaMode.OR) public Result getUserByIdForMemberChange(String userId){ View_user user = dao.fetch(View_user.class, Cnd.where("id", "=", userId)); NutMap nutMap = Lang.obj2nutmap(user); diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeManageController.java b/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeManageController.java index f9c472ae..f1d05b87 100644 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeManageController.java +++ b/src/main/java/com/budwk/app/zhgh/staffmanage/member/controller/change/MemberChangeManageController.java @@ -36,6 +36,7 @@ import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType; import com.budwk.app.zhgh.staffmanage.member.models.MemberChangeRecord; import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberManagePageForm; import com.budwk.app.zhgh.staffmanage.member.service.MemberCommonService; +import com.budwk.app.zhgh.staffmanage.sourcechange.service.PendingConfirmUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -79,6 +80,8 @@ public class MemberChangeManageController { private CommonService commonService; @Inject private MemberCommonService memberCommonService; + @Inject + private PendingConfirmUserService pendingConfirmUserService; @At("") @Ok("beetl:/platform/zhgh/staffmanage/member/change/manage/index.html") @@ -101,7 +104,11 @@ public class MemberChangeManageController { @RepeatSubmit @Aop(TransAop.READ_COMMITTED) @SLog(tag = "会员高级管理-会员变更", msg = "分工会/校工会会员管理员提交变更") - @SaCheckPermission(value = {"member.change.mange", "staff.member.change.mange"}, mode = SaMode.OR) + @SaCheckPermission(value = { + "member.change.mange", + "staff.member.change.mange", + "staff.sourcechange.pending" + }, mode = SaMode.OR) public Result doSubmitChange(MemberChangeRecord record){ // 检验是否有变更 if (Lang.isEmpty(record)) { @@ -162,6 +169,8 @@ public class MemberChangeManageController { if (schoolRoleBool) { memberCommonService.compareChangeInfoAndUpdateMember(record); } + // 待确认人员完成变更提交后转为已确认;普通人员调用时不会产生状态变化。 + pendingConfirmUserService.markConfirmed(record.getUserId()); return Result.success(); } @@ -171,8 +180,7 @@ public class MemberChangeManageController { @SaCheckPermission(value = { "member.change.mange", "staff.member.change.mange", - "staff.sourcechange.manage", - "staff.sourcechange.pending" + "staff.sourcechange.manage" }, mode = SaMode.OR) public Result getAllChangeMemberInfo(String userId){ List mapList = memberCommonService.getAllChangeInfo(userId); diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/member/service/impl/MemberManageServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffmanage/member/service/impl/MemberManageServiceImpl.java index f37c65d9..6bc1cbbd 100644 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/member/service/impl/MemberManageServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffmanage/member/service/impl/MemberManageServiceImpl.java @@ -441,12 +441,8 @@ public class MemberManageServiceImpl extends BaseServiceImpl implement MemberChangeRecord record = dao().fetch(MemberChangeRecord.class, Cnd.where("userId", "=", userId).desc("applyDateTime")); - /* - * 待确认人员来自全量数据差异校正,没有常规的字段前后值 changeInfos。 - * 此处保留该人员的全部历史,再在组装时间线时仅接纳普通变更或待确认记录。 - */ - List historyList = dao().query(Sys_user_history.class, - Cnd.where("loginname", "=", loginName).desc("changeTime")); + List historyList = dao().query(Sys_user_history.class, Cnd.where("loginname", "=", loginName) + .and("changeInfos", "is not", null).desc("changeTime")); List recordList = historyList.stream().map(Sys_user_history::getRecordId).toList(); @@ -459,25 +455,11 @@ public class MemberManageServiceImpl extends BaseServiceImpl implement resultMapList.add(map); } for (Sys_user_history history : historyList) { - boolean pendingConfirm = Lang.isNotEmpty(history.getChangeTypes()) - && history.getChangeTypes().contains(MemberChangeType.PENDING_CONFIRM.name()); - if (Lang.isEmpty(history.getChangeInfos()) && !pendingConfirm) { - continue; - } NutMap map = NutMap.NEW(); List changeInfos = history.getChangeInfos(); - if (pendingConfirm) { - // 待确认记录没有人工异动表,使用差异校正原因构造可阅读的变更说明。 - changeInfos = List.of(NutMap.NEW() - .setv("field", "pendingConfirm") - .setv("fieldName", "人员状态") - .setv("sourceValue", "系统用户中存在") - .setv("newValue", StrUtil.blankToDefault(history.getChangeReason(), "本次全量人员数据中不存在"))); - } map.put("changeInfos", changeInfos); map.put("timestamp", DateUtil.format(history.getChangeTime(), "yyyy-MM-dd HH:mm:ss")); - String changeOriginName = MemberChangeOrigin.valueOf(MemberChangeOrigin.class, history.getChangeOrigin()).changeOriginName; - map.put("changeOriginName", pendingConfirm ? changeOriginName + "(待确认)" : changeOriginName); + map.put("changeOriginName", MemberChangeOrigin.valueOf(MemberChangeOrigin.class, history.getChangeOrigin()).changeOriginName); resultMapList.add(map); } return resultMapList; diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/controller/PendingSourceChangeController.java b/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/controller/PendingSourceChangeController.java deleted file mode 100644 index c93ebc81..00000000 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/controller/PendingSourceChangeController.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.budwk.app.zhgh.staffmanage.sourcechange.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import com.budwk.app.base.annotation.SLog; -import com.budwk.app.base.result.Result; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.PendingUserConfirmParam; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.SourceChangePageForm; -import com.budwk.app.zhgh.staffmanage.sourcechange.service.PendingUserHistoryService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.nutz.ioc.loader.annotation.Inject; -import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.mvc.annotation.At; -import org.nutz.mvc.annotation.Ok; -import org.nutz.mvc.annotation.Param; - -import javax.validation.Valid; - -/** - * 待确认人员记录页面及接口。 - */ -@IocBean -@At("/platform/sourcechange/pending") -@Ok("json") -@Api(tags = "待确认人员记录") -public class PendingSourceChangeController { - - @Inject - private PendingUserHistoryService pendingUserHistoryService; - - /** - * 打开待确认人员记录页面。 - */ - @At("") - @Ok("beetl:/platform/zhgh/staffmanage/sourcechange/pending/index.html") - @SaCheckPermission("staff.sourcechange.pending") - public void index() { - } - - /** - * 分页查询当前仍需人工确认的人员记录。 - * - * @param pageForm 变更记录通用查询条件 - * @return 分页结果 - */ - @At - @ApiOperation("分页查询待确认人员") - @SaCheckPermission("staff.sourcechange.pending") - public Result pageData(SourceChangePageForm pageForm) { - return Result.success(pendingUserHistoryService.listPage(pageForm)); - } - - /** - * 将待确认人员记录确认成最终异动类型。 - * - * @param confirmParam 异动类型及备注 - * @return 处理结果 - */ - @At - @ApiOperation("确认待确认人员") - @SLog(tag = "待确认人员记录", msg = "确认人员") - @SaCheckPermission("staff.sourcechange.pending") - public Result confirm(@Valid @Param("data") PendingUserConfirmParam confirmParam) { - try { - pendingUserHistoryService.confirm(confirmParam); - return Result.success(); - } catch (IllegalArgumentException | IllegalStateException e) { - return Result.error(e.getMessage()); - } - } -} diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/param/PendingUserConfirmParam.java b/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/param/PendingUserConfirmParam.java deleted file mode 100644 index 9e13dbcd..00000000 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/param/PendingUserConfirmParam.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.budwk.app.zhgh.staffmanage.sourcechange.param; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; - -/** - * 待确认人员确认参数。 - */ -@Data -@ApiModel("待确认人员确认参数") -public class PendingUserConfirmParam { - - @NotBlank(message = "待确认记录不能为空") - @ApiModelProperty("sys_user_history 记录ID") - private String id; - - @NotBlank(message = "请选择异动类型") - @ApiModelProperty("最终异动类型") - private String changeType; - - @Size(max = 1000, message = "备注不能超过1000个字符") - @ApiModelProperty("确认备注") - private String remark; -} diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/PendingUserHistoryService.java b/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/PendingUserHistoryService.java deleted file mode 100644 index d65981c3..00000000 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/PendingUserHistoryService.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.budwk.app.zhgh.staffmanage.sourcechange.service; - -import com.budwk.app.base.page.Pagination; -import com.budwk.app.sys.models.Sys_user; -import com.budwk.app.sys.models.Sys_user_source; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.PendingUserConfirmParam; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.SourceChangePageForm; - -import java.util.List; - -/** - * 待确认人员历史记录业务服务。 - */ -public interface PendingUserHistoryService { - - /** - * 根据变更记录页面的查询条件分页查询待确认人员。 - * - * @param pageForm 查询及分页参数 - * @return 待确认人员分页数据 - */ - Pagination listPage(SourceChangePageForm pageForm); - - /** - * 将待确认记录更新为人工选择的最终异动类型并保存备注。 - * - * @param confirmParam 确认参数 - */ - void confirm(PendingUserConfirmParam confirmParam); - - /** - * 依据本次全量源数据校正待确认记录:缺失人员补充记录,重新出现人员删除待确认记录。 - * - * @param systemUsers 更新开始时系统中已有的用户 - * @param sourceUsers 本次全量拉取的用户 - * @return 本次新增的待确认记录数量 - */ - int reconcile(List systemUsers, List sourceUsers); -} diff --git a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/impl/PendingUserHistoryServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/impl/PendingUserHistoryServiceImpl.java deleted file mode 100644 index 58f31706..00000000 --- a/src/main/java/com/budwk/app/zhgh/staffmanage/sourcechange/service/impl/PendingUserHistoryServiceImpl.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.budwk.app.zhgh.staffmanage.sourcechange.service.impl; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; -import com.budwk.app.base.page.Pagination; -import com.budwk.app.base.utils.PageUtil; -import com.budwk.app.sys.models.Sys_user; -import com.budwk.app.sys.models.Sys_user_history; -import com.budwk.app.sys.models.Sys_user_source; -import com.budwk.app.sys.services.SysUserService; -import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeOrigin; -import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.PendingUserConfirmParam; -import com.budwk.app.zhgh.staffmanage.sourcechange.param.SourceChangePageForm; -import com.budwk.app.zhgh.staffmanage.sourcechange.service.PendingUserHistoryService; -import org.nutz.aop.interceptor.ioc.TransAop; -import org.nutz.dao.Chain; -import org.nutz.dao.Cnd; -import org.nutz.dao.Dao; -import org.nutz.dao.Sqls; -import org.nutz.dao.sql.Sql; -import org.nutz.dao.util.cri.SqlExpressionGroup; -import org.nutz.dao.util.cri.Static; -import org.nutz.ioc.aop.Aop; -import org.nutz.ioc.loader.annotation.Inject; -import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.json.Json; -import org.nutz.lang.random.R; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * 待确认人员历史记录业务实现。 - */ -@IocBean -public class PendingUserHistoryServiceImpl implements PendingUserHistoryService { - - private static final int BATCH_SIZE = 500; - - @Inject - private Dao dao; - - @Inject - private SysUserService sysUserService; - - /** - * 查询待确认人员,查询字段与人员变更记录页面保持一致,但未选择日期时查询全部待确认数据。 - */ - @Override - public Pagination listPage(SourceChangePageForm pageForm) { - Sql sql = Sqls.create(""" - SELECT - his.id, - his.loginname, - his.username, - COALESCE(u.sex, his.sex) AS sex, - COALESCE(u.unitName, his.unitName) AS unitName, - COALESCE(u.unionName, his.unionName) AS unionName, - his.userState, - his.personType, - his.preparedBy, - his.changeTime, - his.changeTypes, - his.changeOrigin, - his.remark, - u.id AS userId - FROM sys_user_history his - LEFT JOIN vw_user u ON his.loginname = u.loginname - $condition - """); - Cnd cnd = Cnd.NEW(); - - // 待确认页面固定限定待确认类型,避免已处理记录继续出现在列表中。 - cnd.and(new Static("JSON_CONTAINS(his.changeTypes, JSON_QUOTE('" + MemberChangeType.PENDING_CONFIRM.name() + "'), '$')")); - if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - SqlExpressionGroup keywordGroup = new SqlExpressionGroup(); - keywordGroup.orLike("his.username", pageForm.getSearchKeyword()); - keywordGroup.orLike("his.loginname", pageForm.getSearchKeyword()); - cnd.and(keywordGroup); - } - cnd.andEX("u.unionId", "=", pageForm.getUnionId()); - cnd.andEX("u.unitId", "=", pageForm.getUnitId()); - cnd.andEX("u.sex", "=", pageForm.getSex()); - cnd.andEX("his.personType", "=", pageForm.getPersonType()); - cnd.andEX("his.preparedBy", "=", pageForm.getPreparedBy()); - cnd.andEX("his.userState", "=", pageForm.getUserState()); - cnd.andEX("his.changeOrigin", "=", pageForm.getChangeOrigin()); - - // 日期范围使用参数化条件,结束日期按次日零点前处理,包含所选结束日期的全部数据。 - if (StrUtil.isAllNotBlank(pageForm.getChangeDateBefore(), pageForm.getChangeDateEnd())) { - Date startDate = DateUtil.parseDate(pageForm.getChangeDateBefore()); - Date endDateExclusive = DateUtil.offsetDay(DateUtil.parseDate(pageForm.getChangeDateEnd()), 1); - cnd.and("his.changeTime", ">=", startDate); - cnd.and("his.changeTime", "<", endDateExclusive); - } - if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { - cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); - } else { - cnd.desc("his.changeTime"); - } - sql.setCondition(cnd); - return sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - } - - /** - * 确认待确认人员记录,异动类型只允许选择已定义且非待确认的最终类型。 - */ - @Override - @Aop(TransAop.READ_COMMITTED) - public void confirm(PendingUserConfirmParam confirmParam) { - MemberChangeType selectedType; - try { - selectedType = MemberChangeType.valueOf(confirmParam.getChangeType()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("异动类型不存在"); - } - if (MemberChangeType.PENDING_CONFIRM == selectedType) { - throw new IllegalArgumentException("请选择最终异动类型"); - } - - // 更新条件同时校验记录仍处于待确认状态,防止重复确认覆盖已经处理的数据。 - Cnd cnd = Cnd.where("id", "=", confirmParam.getId()) - .and(new Static("JSON_CONTAINS(changeTypes, JSON_QUOTE('" + MemberChangeType.PENDING_CONFIRM.name() + "'), '$')")); - Chain chain = Chain.make("changeTypes", Json.toJson(List.of(selectedType.name()))) - .add("remark", StrUtil.trim(confirmParam.getRemark())); - int updated = dao.update(Sys_user_history.class, chain, cnd); - if (updated == 0) { - throw new IllegalStateException("待确认记录不存在或已被处理"); - } - } - - /** - * 根据本次全量源数据双向校正待确认历史:源数据重新出现则删除,源数据缺失则幂等新增。 - */ - @Override - @Aop(TransAop.READ_COMMITTED) - public int reconcile(List systemUsers, List sourceUsers) { - Set sourceLoginNames = sourceUsers.stream() - .map(Sys_user_source::getLoginname) - .filter(StrUtil::isNotBlank) - .collect(Collectors.toSet()); - List pendingHistories = dao.query(Sys_user_history.class, pendingCondition()); - - // 已重新出现在完整源数据中的人员不再需要人工确认,仅删除尚未处理的待确认记录。 - List recoveredPendingIds = pendingHistories.stream() - .filter(history -> sourceLoginNames.contains(history.getLoginname())) - .map(Sys_user_history::getId) - .toList(); - for (List idBatch : ListUtil.split(recoveredPendingIds, BATCH_SIZE)) { - dao.clear(Sys_user_history.class, Cnd.where("id", "in", idBatch)); - } - - Set existingPendingLoginNames = pendingHistories.stream() - .filter(history -> !sourceLoginNames.contains(history.getLoginname())) - .map(Sys_user_history::getLoginname) - .filter(StrUtil::isNotBlank) - .collect(Collectors.toCollection(HashSet::new)); - List historiesToInsert = new ArrayList<>(); - - // 同一工号最多保留一条待确认记录,重复执行全部更新不会重复生成数据。 - for (Sys_user user : systemUsers) { - String loginname = user.getLoginname(); - if (StrUtil.isBlank(loginname) - || sourceLoginNames.contains(loginname) - || !existingPendingLoginNames.add(loginname)) { - continue; - } - Sys_user_history history = new Sys_user_history(); - BeanUtil.copyProperties(user, history); - history.setId(R.UU32()); - history.setChangeTime(DateUtil.date()); - history.setChangeTypes(List.of(MemberChangeType.PENDING_CONFIRM.name())); - history.setChangeOrigin(MemberChangeOrigin.SYSTEM.name()); - history.setChangeReason("全量人员数据中不存在"); - historiesToInsert.add(history); - } - - for (List historyBatch : ListUtil.split(historiesToInsert, BATCH_SIZE)) { - dao.fastInsert(historyBatch); - } - return historiesToInsert.size(); - } - - /** - * 构造待确认 JSON 类型条件,供查询及差异校正统一使用。 - */ - private Cnd pendingCondition() { - return Cnd.where(new Static("JSON_CONTAINS(changeTypes, JSON_QUOTE('" + MemberChangeType.PENDING_CONFIRM.name() + "'), '$')")); - } -} diff --git a/src/main/resources/db/menu/init_pending_source_change_menu.sql b/src/main/resources/db/menu/init_pending_source_change_menu.sql index d129ece9..d0b09792 100644 --- a/src/main/resources/db/menu/init_pending_source_change_menu.sql +++ b/src/main/resources/db/menu/init_pending_source_change_menu.sql @@ -28,7 +28,7 @@ SELECT 1, 0, 'staff.sourcechange.pending', - '全量人员数据差异待人工确认记录', + '系统用户待确认和已确认人员记录', source_menu.location + 1, 0, '', @@ -49,7 +49,7 @@ WHERE source_menu.permission = 'staff.sourcechange.manage' FROM (SELECT id FROM sys_menu WHERE permission = 'staff.sourcechange.pending') existing_menu ); --- 原先能够查看“变更记录”的角色默认拥有“待确认人员记录”权限,避免新页面上线后无人可见。 +-- 原先能够查看“变更记录”的角色默认拥有待确认人员记录权限。 INSERT INTO sys_role_menu (roleId, menuId) SELECT source_role.roleId, pending_menu.id FROM sys_role_menu source_role diff --git a/src/main/resources/db/sys_user_history_pending_confirm.sql b/src/main/resources/db/sys_user_history_pending_confirm.sql deleted file mode 100644 index 99446437..00000000 --- a/src/main/resources/db/sys_user_history_pending_confirm.sql +++ /dev/null @@ -1,18 +0,0 @@ --- 待确认人员人工确认备注字段。已有字段的环境重复执行不会改变表结构。 -SET @pending_remark_column_count = ( - SELECT COUNT(*) - FROM information_schema.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'sys_user_history' - AND COLUMN_NAME = 'remark' -); - -SET @pending_remark_ddl = IF( - @pending_remark_column_count = 0, - 'ALTER TABLE sys_user_history ADD COLUMN remark TEXT NULL COMMENT ''备注'' AFTER changeReason', - 'SELECT 1' -); - -PREPARE pending_remark_stmt FROM @pending_remark_ddl; -EXECUTE pending_remark_stmt; -DEALLOCATE PREPARE pending_remark_stmt; diff --git a/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/memberChange.js b/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/memberChange.js index a321f2f0..9f6663e2 100644 --- a/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/memberChange.js +++ b/src/main/resources/views/platform/zhgh/staffmanage/member/change/common/memberChange.js @@ -1,7 +1,7 @@ const MEMBER_CHANGE = { template: /*language=HTML*/ ` - + @@ -155,12 +155,12 @@ const MEMBER_CHANGE = { style="width: 100%"> - - - - - + + + + + +