拉取人员接口:18开头的工号 且 人员类型为空 且 人员类型不为“非合同制”的人员,将这些人的人员类型改为“合同制”且设置为会员

会员档案查询:分工会主席只能查询当前分工会的人员的数据
This commit is contained in:
2026-10-21 09:28:49 +08:00
parent 243460df36
commit c8c432c7df
3 changed files with 85 additions and 14 deletions
@@ -20,6 +20,7 @@ import io.v.nutz.zhgh.data.model.UserSource;
import io.v.nutz.zhgh.data.service.HistoryUserService; import io.v.nutz.zhgh.data.service.HistoryUserService;
import io.v.nutz.zhgh.data.service.SourceUserService; import io.v.nutz.zhgh.data.service.SourceUserService;
import io.v.nutz.base.lang.Enum; import io.v.nutz.base.lang.Enum;
import io.v.nutz.zhgh.member.MemberMode;
import io.v.nutz.zhgh.member.UserMode; import io.v.nutz.zhgh.member.UserMode;
import io.v.nutz.base.service.AsyncService; import io.v.nutz.base.service.AsyncService;
import io.v.nutz.base.service.impl.ViServiceImpl; import io.v.nutz.base.service.impl.ViServiceImpl;
@@ -67,6 +68,9 @@ import java.util.stream.Collectors;
@CacheDefaults(cacheName = "user_source") @CacheDefaults(cacheName = "user_source")
@Slf4j @Slf4j
public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements SourceUserService { public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements SourceUserService {
private static final String CONTRACT_PERSON_TYPE = "合同制";
private static final String NON_CONTRACT_PERSON_TYPE = "非合同制";
public SourceUserServiceImpl(Dao dao) { public SourceUserServiceImpl(Dao dao) {
super(dao); super(dao);
} }
@@ -96,9 +100,25 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
public void pullSourceData(Boolean isIncrement) { public void pullSourceData(Boolean isIncrement) {
Date now = new Date(); Date now = new Date();
List<UserSource> users = SourceData.users(); List<UserSource> users = SourceData.users();
// 正式用户已明确标记为非合同制时,不能因数据中心人员类型为空而被改为合同制或自动入会。
Set<String> nonContractLoginNames = sysUserService.query(Cnd.where("personType", "=", NON_CONTRACT_PERSON_TYPE))
.stream()
.map(Sys_user::getLoginname)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
asyncService.exe2(users, (user) -> { asyncService.exe2(users, (user) -> {
user.setPullTime(now); user.setPullTime(now);
UserMode.initUser(user); UserMode.initUser(user);
// 数据中心人员类型为空且工号以 18 开头时,仅非“非合同制”人员按合同制会员处理。
if (isContractMemberCandidate(user)) {
if (nonContractLoginNames.contains(user.getLoginname())) {
// 使用 null 避免后续 updateIgnoreNull 将正式用户已有的“非合同制”覆盖为空字符串。
user.setPersonType(null);
} else {
user.setPersonType(CONTRACT_PERSON_TYPE);
user.setMember(MemberMode.NORMAL.getCode());
}
}
}); });
dao().insert(users); dao().insert(users);
} }
@@ -149,6 +169,8 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
List<Sys_user> unitChangeUserList = new CopyOnWriteArrayList<>(); List<Sys_user> unitChangeUserList = new CopyOnWriteArrayList<>();
// 删除博士后出站的会员和福利会员角色 // 删除博士后出站的会员和福利会员角色
List<String> deleteLeavingStationUserIdList = new CopyOnWriteArrayList<>(); List<String> deleteLeavingStationUserIdList = new CopyOnWriteArrayList<>();
// 拉取时识别出的合同制人员,在正式用户保存后统一补充会员字段及会员角色。
List<String> addContractMemberUserIdList = new CopyOnWriteArrayList<>();
// 创建一个固定大小的线程池 可以根据服务器性能调整线程池大小 // 创建一个固定大小的线程池 可以根据服务器性能调整线程池大小
@@ -171,9 +193,11 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
continue; continue;
} }
boolean shouldAddContractMember = isPulledContractMember(source);
source.setMember(null); source.setMember(null);
source.setWelfareMember(null); source.setWelfareMember(null);
Sys_user user = userMap.get(source.getLoginname()); Sys_user user = userMap.get(source.getLoginname());
Sys_user systemUser = user;
UserChangeType changeType = getChangeType(source, user); UserChangeType changeType = getChangeType(source, user);
@@ -214,12 +238,14 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
unitChangeUserList.add(u); unitChangeUserList.add(u);
} }
boolean includedInUpdate = user == null;
switch (sourceType) { switch (sourceType) {
case "all" -> { case "all" -> {
//复制属性到一个新的user对象 //复制属性到一个新的user对象
u.setId(user == null ? source.getId() : user.getId()); u.setId(user == null ? source.getId() : user.getId());
if (user != null) { if (user != null) {
needDoUpdateList.add(u); needDoUpdateList.add(u);
includedInUpdate = true;
} }
} }
case "add" -> { case "add" -> {
@@ -234,6 +260,7 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
} }
if (Strings.isNotBlank(finalUserPartMap.get(u.getLoginname())) && user != null) { if (Strings.isNotBlank(finalUserPartMap.get(u.getLoginname())) && user != null) {
needDoUpdateList.add(u); needDoUpdateList.add(u);
includedInUpdate = true;
} }
} }
} }
@@ -256,6 +283,12 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
histories.add(createUserHistory(user, changeTypes)); histories.add(createUserHistory(user, changeTypes));
} }
// 仅对本次实际新增或更新、且尚未入会的人员执行会员初始化,避免重复覆盖原入会时间。
if (shouldAddContractMember && includedInUpdate
&& !ObjectUtil.equal(systemUser != null ? systemUser.getMember() : null, MemberMode.NORMAL.getCode())) {
addContractMemberUserIdList.add(systemUser == null ? u.getId() : systemUser.getId());
}
} }
}, Executors.newFixedThreadPool(numberOfThreads)); }, Executors.newFixedThreadPool(numberOfThreads));
futures.add(future); futures.add(future);
@@ -277,6 +310,10 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
massUpdatesAsync(needDoUpdateList, false, null); massUpdatesAsync(needDoUpdateList, false, null);
} }
if (Lang.isNotEmpty(addContractMemberUserIdList)) {
UserMode.addMemberRole(addContractMemberUserIdList.toArray(new String[0]));
}
if (Lang.isNotEmpty(deleteLeavingStationUserIdList)) { if (Lang.isNotEmpty(deleteLeavingStationUserIdList)) {
dao().clear(Sys_user_role.class, Cnd.where("userId", "in", deleteLeavingStationUserIdList).and("roleId", "=", Roles.MEMBER)); dao().clear(Sys_user_role.class, Cnd.where("userId", "in", deleteLeavingStationUserIdList).and("roleId", "=", Roles.MEMBER));
dao().update(Sys_user.class, Chain.make("member", 0).add("welfareMember", 0), Cnd.where("id", "in", deleteLeavingStationUserIdList)); dao().update(Sys_user.class, Chain.make("member", 0).add("welfareMember", 0), Cnd.where("id", "in", deleteLeavingStationUserIdList));
@@ -377,6 +414,33 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
dao().clear(UserSource.class, Cnd.where("DATE(pullTime)", "<", formatAgoWeekDate)); dao().clear(UserSource.class, Cnd.where("DATE(pullTime)", "<", formatAgoWeekDate));
} }
/**
* 判断数据中心人员是否需要按合同制会员初始化。
*
* @param user 数据中心返回的人员;工号需以 18 开头且人员类型为空
* @return true 表示需要补充“合同制”人员类型并设置为会员
*/
private boolean isContractMemberCandidate(Sys_user user) {
return user != null
&& user.getLoginname() != null
&& user.getLoginname().startsWith("18")
&& StrUtil.isBlank(user.getPersonType());
}
/**
* 判断暂存人员是否为拉取阶段标记的合同制会员。
*
* @param source 人员拉取暂存数据
* @return true 表示人员类型及会员标记均符合自动入会条件
*/
private boolean isPulledContractMember(UserSource source) {
return source != null
&& source.getLoginname() != null
&& source.getLoginname().startsWith("18")
&& CONTRACT_PERSON_TYPE.equals(source.getPersonType())
&& ObjectUtil.equal(source.getMember(), MemberMode.NORMAL.getCode());
}
private UserChangeType getChangeType(Sys_user source, Sys_user user) { private UserChangeType getChangeType(Sys_user source, Sys_user user) {
//新入职 //新入职
if (user == null) { if (user == null) {
@@ -2,6 +2,7 @@ package io.v.nutz.zhgh.member.controller.info;
import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import io.v.nutz.base.annontation.ViReturn; import io.v.nutz.base.annontation.ViReturn;
@@ -153,16 +154,15 @@ public class MemberGroupInfoController {
cnd.where().andLike("jobTitle", jobTitle); cnd.where().andLike("jobTitle", jobTitle);
} }
if (!ShiroUtil.hasAnyRoles("sysadmin,H03,A06")) { // 分工会主席可能同时具有校会员管理员角色,除系统管理员和校级管理员外,必须优先限制为当前分工会。
if (ShiroUtil.hasRole("H04")) { if (ShiroUtil.hasRole("H04") && !ShiroUtil.hasAnyRoles("sysadmin,A06")) {
cnd.and("unionId", "=", Vi.getUnionId()); cnd.and("unionId", "=", Vi.getUnionId());
} else if (ShiroUtil.hasRole("ghxzzz")) { } else if (!ShiroUtil.hasAnyRoles("sysadmin,H03,A06") && ShiroUtil.hasRole("ghxzzz")) {
cnd.and("unionId", "=", Vi.getUnionId()); cnd.and("unionId", "=", Vi.getUnionId());
SqlExpressionGroup seg = new SqlExpressionGroup(); SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("unionGroupId", "in", io.v.nutz.web.commons.utils.ShiroUtil.getUnionGroupIds()); seg.or("unionGroupId", "in", io.v.nutz.web.commons.utils.ShiroUtil.getUnionGroupIds());
seg.or("unionGroupId", "is", null); seg.or("unionGroupId", "is", null);
cnd.and(seg); cnd.and(seg);
}
} }
@@ -249,7 +249,7 @@ public class MemberGroupInfoController {
@Param(value = "memberSearchName", required = false) String memberSearchName, @Param(value = "memberSearchName", required = false) String memberSearchName,
@Param(value = "memberSearchKeyWord", required = false) String memberSearchKeyWord) { @Param(value = "memberSearchKeyWord", required = false) String memberSearchKeyWord) {
try { try {
ViTool.excelResponse(response, "会员名单.xls"); ViTool.excelResponse(response, "会员名单.xlsx");
List<NutMap> dataList = memberService.listMap(dataSql(pageForm, unionId, unitId, threeUnitId, unionGroupId, Json.fromJsonAsArray(String.class, personTypes), Json.fromJsonAsArray(String.class, userStates), campus, sex, memberStatus, position, jobTitle, memberSearchName, memberSearchKeyWord)); List<NutMap> dataList = memberService.listMap(dataSql(pageForm, unionId, unitId, threeUnitId, unionGroupId, Json.fromJsonAsArray(String.class, personTypes), Json.fromJsonAsArray(String.class, userStates), campus, sex, memberStatus, position, jobTitle, memberSearchName, memberSearchKeyWord));
List<ExcelExportEntity> entityList = new ArrayList<>(); List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10); ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
@@ -260,7 +260,9 @@ public class MemberGroupInfoController {
propMap.forEach((k, v) -> { propMap.forEach((k, v) -> {
entityList.add(new ExcelExportEntity(v, k, 20)); entityList.add(new ExcelExportEntity(v, k, 20));
}); });
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, dataList); ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, dataList);
workbook.write(response.getOutputStream()); workbook.write(response.getOutputStream());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@@ -560,7 +560,12 @@ layout("/layouts/platform.html"){
}, },
async created() { async created() {
this.pageData(); this.pageData();
if ("${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')||@shiro.hasRole('H03')}" === 'true') { // 分工会主席可能兼具 H03 角色,需优先按当前分工会加载查询选项。
if ("${@shiro.hasRole('H04')&&!(@shiro.hasRole('sysadmin')||@shiro.hasRole('A06'))}" === 'true') {
this.unions = await getUnions(null, true)
this.$set(this.pageForm, 'unionId', this.unions ? this.unions[0].id : null)
this.flushUnits()
} else if ("${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')||@shiro.hasRole('H03')}" === 'true') {
this.unions = await getUnions(null, false) this.unions = await getUnions(null, false)
} else { } else {
this.unions = await getUnions(null, true) this.unions = await getUnions(null, true)