人员更新

This commit is contained in:
Paidax
2025-06-05 15:06:31 +08:00
parent 07300ed9bc
commit ba4642dcce
26 changed files with 550 additions and 421 deletions
@@ -45,8 +45,8 @@ public class SysDataUserPullController {
cnd.and(Cnd.likeEX(Sys_user_source::getLoginname, pageForm.getLoginName()));
cnd.andEX(Sys_user_source::getUnitName, "=", pageForm.getUnitName());
cnd.andEX(Sys_user_source::getUserState, "=", pageForm.getUserState());
cnd.andEX(Sys_user_source::getEmploymentType, "=", pageForm.getEmploymentType());
cnd.andEX(Sys_user_source::getStaffType, "=", pageForm.getStaffType());
cnd.andEX(Sys_user_source::getPreparedBy, "=", pageForm.getPreparedBy());
cnd.andEX(Sys_user_source::getPersonType, "=", pageForm.getPersonType());
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
@@ -139,23 +139,8 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("来校时间")
@ColDefine(type = ColType.DATE)
private Date arrivalAtSchoolDate;
@Column
@Comment("教职工类别")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String staffCategory;
@Column
@Comment("教职工类别")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String staffType;
@Column
@Comment("聘用方式")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String employmentType;
@ColDefine(type = ColType.VARCHAR, width = 10)
private String arrivalAtSchoolDate;
@Column
@Comment("身份类型")
@@ -167,6 +152,16 @@ public class Sys_user extends BaseModel implements Serializable {
@ColDefine(type = ColType.VARCHAR, width = 30)
private String userState;
@Column
@Comment("人员类别")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String personType;
@Column
@Comment("聘用方式")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String preparedBy;
@Column
@Comment("退休时间")
@ColDefine(type = ColType.DATE)
@@ -6,6 +6,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import java.io.Serializable;
import java.util.Date;
@@ -185,6 +186,16 @@ public class Sys_user_history extends BaseModel implements Serializable {
@ColDefine(type = ColType.VARCHAR, width = 20)
private String changeOrigin;
@Column
@Comment("详细变更记录,用于查询、列表展示")
@ColDefine(type = ColType.MYSQL_JSON)
private List<NutMap> changeInfos;
@Column
@Comment("详细变更记录,文本类型,可用于导出")
@ColDefine(type = ColType.TEXT)
private String changeInfosStr;
@Column
@Comment("变更原因")
@ColDefine(type = ColType.VARCHAR, width = 100)
@@ -28,9 +28,9 @@ public class SysDataUserPullPageForm extends PageForm<Sys_user_source> {
private String userState;
@ApiModelProperty("教职工类别")
private String staffType;
private String personType;
@ApiModelProperty("用人方式")
private String employmentType;
private String preparedBy;
}
@@ -2,6 +2,8 @@ package com.budwk.app.sys.services.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
@@ -13,73 +15,65 @@ import com.budwk.app.base.utils.PwdUtil;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.param.SysDataUserUpdateParam;
import com.budwk.app.sys.services.SysDataUserUpdateService;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysRoleService;
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.member.service.MemberManageService;
import com.budwk.app.zhgh.staffmanage.specialstaff.model.SpecialStaff;
import lombok.extern.slf4j.Slf4j;
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.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.Mvcs;
import org.springframework.beans.BeanUtils;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
/**
* 全量更新系统用户数据
*/
@Slf4j
@IocBean
public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService {
@Inject
private Dao dao;
@Inject
private SysDictService sysDictService;
@Inject
private SysRoleService sysRoleService;
@Inject
private SysUserService sysUserService;
@Inject
private ManyAddOrRenewUtil manyAddOrRenewUtil;
@Inject
private MemberManageService memberManageService;
@Inject
private ManyAddOrRenewUtil manyAddOrRenewUtil;
private static final String[] INFO_CENTER_PUSH_FIELDS = {
"username",
"userState",
"preparedBy",
"personType",
"comeSchoolDate",
"birthday",
"governmentPosition",
"technicalTitle",
"nation",
"sex",
"nationality",
"idCard",
"education",
"academicDegree"
};
private static final Map<String, String> DICT_MAP = new HashMap<>() {{
put("username", "姓名");
put("userState", "在职状态");
put("preparedBy", "人事编制");
put("personType", "人员类型");
put("comeSchoolDate", "来校年月");
put("birthday", "出生日期");
put("governmentPosition", "党政职务");
put("technicalTitle", "技术职称");
put("nation", "民族");
put("sex", "性别");
put("nationality", "国籍");
put("idCard", "身份证号");
put("education", "学历");
put("academicDegree", "学位");
}};
/**
* 是会员的在职状态
*/
private final List<String> MEMBER_USER_STATE = List.of("在岗");
/**
* 是会员的编制类型,博士后满两年退出会员
*/
private final List<String> MEMBER_PREPARED_BY = List.of("新人事代理", "校聘合同制", "事业编制", "博士后");
/**
@@ -89,193 +83,310 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
* @return
*/
@Override
@Aop(TransAop.READ_COMMITTED)
public String update(SysDataUserUpdateParam updateParam) {
Date nowDate = new Date();
// 获取角色信息
Sys_role publicRole = sysRoleService.getByCode(RoleConstant.PUBLIC);
Sys_role memberRole = sysRoleService.getByCode(RoleConstant.MEMBER);
//查询数据源
List<Sys_user_source> sysUserSources = dao.query(Sys_user_source.class, Cnd.where(Sys_user_source::getPullTime, "=", updateParam.getPullTime()).groupBy("loginname"));
List<Sys_user_source> sources = dao.query(Sys_user_source.class, Cnd.where(Sys_user_source::getPullTime, "=", updateParam.getPullTime()).groupBy("loginname"));
//查询系统用户
List<Sys_user> sysUsers = dao.query(Sys_user.class, Cnd.NEW().groupBy("loginname"));
Map<String, Sys_user> sysUserMap = sysUsers.stream().collect(Collectors.toMap(Sys_user::getLoginname, sysUser -> sysUser));
// 查询特别人员中的多单位人员
// List<SpecialStaff> specialStaffList = dao.query(SpecialStaff.class, Cnd.where("isManyUnit", "=", true));
// Set<String> manyUnitUserIds = specialStaffList.stream().map(SpecialStaff::getUserId).collect(Collectors.toSet());
//新入职的用户
List<Sys_user> newUsers = new ArrayList<>();
//基本信息异动的用户变更后的数据
List<Sys_user> basicAfterChangeUsers = new ArrayList<>();
//基本信息异动的用户变更前的数据
List<Sys_user> basicBeforeChangeUsers = new ArrayList<>();
//基本信息异动用户的类型 loginName对应changeTypes
Map<String, Set<String>> basicChangeUserMap = new HashMap<>();
// 存储基本信息、单位异动的user,去和sys_user_history对比出变更记录
Map<String, Sys_user> userMap = new HashMap<>();
// 存储单位异动的人员,发送订阅,修改业务数据的信息
List<String> userIdList = new ArrayList<>();
Map<String, Sys_user> userMap = sysUsers.stream().collect(Collectors.toMap(Sys_user::getLoginname, sysUser -> sysUser));
//判断是否有新入职用户 单位异动的用户 基本信息异动用户
for (Sys_user_source sysUserSource : sysUserSources) {
// 如果是多单位人员,那就不做更新单位的操作
// if (manyUnitUserIds.contains(sysUserSource.getId())) {
// sysUserSource.setUnitId(null);
// }
sysUserSource.setMember(null);
sysUserSource.setWelfareMember(null);
if (sysUserMap.containsKey(sysUserSource.getLoginname())) {
// 系统用户
Sys_user sysUser = sysUserMap.get(sysUserSource.getLoginname());
// 异动类型
Set<String> changeTypes = new HashSet<>();
// 判断是否单位异动
String sysUserSourceUnitId = sysUserSource.getUnitId();
String sysUserUnitId = sysUser.getUnitId();
if (StrUtil.isNotBlank(sysUserSourceUnitId) && !sysUserSourceUnitId.equals(sysUserUnitId)) {
changeTypes.add(MemberChangeType.UNIT_CHANGE.name());
sysUserSource.setId(sysUser.getId());
Sys_user user = BeanUtil.copyProperties(sysUserSource, Sys_user.class);
basicAfterChangeUsers.add(user);
basicBeforeChangeUsers.add(sysUser);
userMap.put(sysUser.getLoginname(), user);
userIdList.add(user.getId());
// 要修改的用户表
List<Sys_user> needDoUpdateList = new CopyOnWriteArrayList<>();
// 要新增的用户
List<Sys_user> needInitUserList = new CopyOnWriteArrayList<>();
// 存储人员变更记录的表
List<Sys_user_history> histories = new CopyOnWriteArrayList<>();
// 添加会员角色
List<String> addMemberUserIds = new CopyOnWriteArrayList<>();
// 移除会员角色
List<String> removeMemberUserIds = new CopyOnWriteArrayList<>();
// 获取允许变更的字段,同时再加上单位字段
List<Sys_dict> dictList = sysDictService.getSubListByCode("MEMBER_ALLOW_CHANGES_FIELD");
Set<String> allowChangeFieldNames = dictList.stream().map(Sys_dict::getCode).collect(Collectors.toSet());
allowChangeFieldNames.add("member");
Map<String, String> dictMap = dictList.stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName));
dictMap.put("member", "会员状态");
// 创建线程开始更新
int numberOfThreads = Runtime.getRuntime().availableProcessors() * 2;
List<CompletableFuture<Void>> futures = new CopyOnWriteArrayList<>();
// 每批处理的数据量,可以根据实际情况调整
int batchSize = 200;
for (int i = 0; i < sources.size(); i += batchSize) {
final int end = Math.min(i + batchSize, sources.size());
List<Sys_user_source> batch = sources.subList(i, end);
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
for (Sys_user_source source : batch) {
// 获取系统用户
Sys_user user = userMap.get(source.getLoginname());
// 进入系统的人
boolean isEnterUser = StrUtil.isNotBlank(source.getPreparedBy()) && MEMBER_PREPARED_BY.contains(source.getPreparedBy())
&& StrUtil.isNotBlank(source.getUserState()) && MEMBER_USER_STATE.contains(source.getUserState());
// 去校验是不是会员
judgeMember(source, user, addMemberUserIds, removeMemberUserIds, isEnterUser);
// 中间对象u
Sys_user u = new Sys_user();
BeanUtils.copyProperties(source, u);
if (user == null && isEnterUser) {
// 新增教工,去初始化数据
String salt = R.UU32();
u.setSalt(salt);
u.setPassword(PwdUtil.getPassword(R.UU32(), salt));
u.setLoginCount(0);
} else if (user != null){
// 修改数据
u.setId(user.getId());
needDoUpdateList.add(u);
}
Sys_user_history history = createHistory(source, user, dictMap, allowChangeFieldNames);
if (Lang.isEmpty(history)) {
continue;
}
// 在系统里的人,创建人员变更记录
if (user != null) {
histories.add(history);
} else {
// 要进系统的,是新入职的也要创建变更记录
if (isEnterUser && Lang.isNotEmpty(history.getChangeTypes()) && history.getChangeTypes().contains(MemberChangeType.NEW.name())) {
histories.add(history);
needInitUserList.add(u);
}
}
}
}, Executors.newFixedThreadPool(numberOfThreads));
futures.add(future);
}
// 确保线程完全走完
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
// 判断是否基本信息异动
for (String field : INFO_CENTER_PUSH_FIELDS) {
// 反射获取字段值
Object sysUserSourceValue = Convert.toStr(BeanUtil.getProperty(sysUserSource, field), "");
Object sysUserValue = Convert.toStr(BeanUtil.getProperty(sysUser, field), "");
if (!Objects.equals(sysUserSourceValue, sysUserValue)) {
changeTypes.add(MemberChangeType.BASIC_CHANGE.name());
sysUserSource.setId(sysUser.getId());
Sys_user user = BeanUtil.copyProperties(sysUserSource, Sys_user.class);
basicAfterChangeUsers.add(user);
basicBeforeChangeUsers.add(sysUser);
basicChangeUserMap.putIfAbsent(sysUserSource.getLoginname(), changeTypes);
userMap.put(sysUser.getLoginname(), user);
break;
//如果有新用户,增加到用户表同时增加角色
if (Lang.isNotEmpty(needInitUserList)) {
sysUserService.fastInsert(needInitUserList);
List<Sys_user_role> roleList = needInitUserList.stream().map(item -> {
Sys_user_role userRole = new Sys_user_role();
userRole.setRoleId(publicRole.getId());
userRole.setUserId(item.getId());
return userRole;
}).toList();
manyAddOrRenewUtil.asyncExecuteFastInsert(roleList, 200);
}
// 更新需要变更的用户
manyAddOrRenewUtil.asyncExecuteUpdateIgnoreNull(needDoUpdateList, 200);
// 添加历史记录
manyAddOrRenewUtil.asyncExecuteFastInsert(histories, 200);
// 设置和移除会员角色
if (Lang.isNotEmpty(addMemberUserIds)) {
List<Sys_user_role> roleList = addMemberUserIds.stream().map(v -> {
Sys_user_role role = new Sys_user_role();
role.setRoleId(memberRole.getId());
role.setUserId(v);
return role;
}).toList();
manyAddOrRenewUtil.asyncExecuteInsert(roleList, 200);
// dao.update(Sys_user.class, Chain.make("member", true), Cnd.where("id", "in", addMemberUserIds));
}
if (Lang.isNotEmpty(removeMemberUserIds)) {
dao.update(Sys_user.class, Chain.make("member", false), Cnd.where("id", "in", removeMemberUserIds));
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", removeMemberUserIds).and("roleId", "=", memberRole.getId()));
}
return "";
}
/**
* 构建变更的历史数据
* @param source
* @param user
* @param dictMap
* @param allowChangeFieldNames
* @return
*/
private Sys_user_history createHistory(Sys_user_source source, Sys_user user, Map<String, String> dictMap, Set<String> allowChangeFieldNames) {
List<String> changeTypes = new ArrayList<>();
Sys_user_history history = new Sys_user_history();
BeanUtil.copyProperties(user, history);
history.setId(R.UU32());
history.setChangeTime(DateUtil.date());
history.setChangeOrigin(MemberChangeOrigin.SYSTEM.name());
if (user == null) {
changeTypes.add(MemberChangeType.NEW.name());
history.setChangeTypes(changeTypes);
return history;
}
// 获取变更记录
NutMap newMap = Lang.obj2nutmap(source);
NutMap sourceMap = Lang.obj2nutmap(user);
List<NutMap> changeList = new ArrayList<>();
for (String fieldName : allowChangeFieldNames) {
if (List.of("retireDate", "welfareStopDate").contains(fieldName)) {
continue;
}
memberManageService.extractChange(newMap, sourceMap, fieldName, dictMap, changeList);
}
if (Lang.isEmpty(changeList)) {
return null;
}
String changeInfos = changeList.stream().map(v -> {
return v.getString("name") + "" + HtmlUtil.cleanHtmlTag(v.getString("value")) + "—>" + HtmlUtil.cleanHtmlTag(v.getString("newValue"));
}).collect(Collectors.joining(""));
// 比较变更数据
commonCompareChange(source, user, changeTypes);
history.setChangeTypes(changeTypes);
history.setChangeInfos(changeList);
history.setChangeInfosStr(changeInfos);
return history;
}
/**
* 比较变更类型公共方法
* @param source
* @param user
* @param changeTypes
*/
private void commonCompareChange(Sys_user_source source, Sys_user user, List<String> changeTypes){
changeTypes.add(MemberChangeType.BASIC_CHANGE.name());
// if (!ObjectUtil.equals(user.getUserState(), source.getUserState())) {
// List<MemberChangeType> list = Arrays.stream(MemberChangeType.values())
// .filter(v -> v.getChangeTypeName().equals(source.getUserState())).toList();
// if (Lang.isNotEmpty(list)) {
// changeTypes.add(list.get(0).getType());
// }
// }
if (!ObjectUtil.equals(user.getMember(), source.getMember())){
if (source.getMember()) {
changeTypes.add(MemberChangeType.RESTORE.name());
} else {
changeTypes.add(MemberChangeType.WITHDRAWAL.name());
}
}
if (!ObjectUtil.equals(user.getUnitId(), source.getUnitId())) {
changeTypes.add(MemberChangeType.UNIT_CHANGE.name());
}
}
/**
* 判断是否是会员
* @param source
* @param user
*/
private void judgeMember(Sys_user_source source, Sys_user user, List<String> addMemberUserIds, List<String> removeMemberUserIds, boolean isEligibleForMember){
// 根据上面定义final常量 在职状态、编制类型去判断是不是会员
if (user == null && isEligibleForMember) {
addMemberUserIds.add(source.getId());
} else {
if (user == null) {
return;
}
boolean isUserMember = user.getMember();
// 判断博士后
if ("博士后".equals(source.getPreparedBy())) {
if (isUserMember) {
String arrivalDateStr = source.getArrivalAtSchoolDate();
// 将字符串转换为 DateTime 对象
DateTime arrivalDate = DateUtil.parse(arrivalDateStr, "yyyy-MM");
// 获取当前日期
DateTime currentDate = DateUtil.date();
// 计算两个日期之间的差异(单位:年)
long yearsDifference = DateUtil.betweenYear(arrivalDate, currentDate, false);
// 判断是否已经过去了两年
if (yearsDifference >= 2) {
removeMemberUserIds.add(user.getId());
source.setMember(false);
}
} else {
if (isEligibleForMember) {
addMemberUserIds.add(user.getId());
source.setMember(true);
}
}
} else {
// 新增用户
Sys_user user = BeanUtil.copyProperties(sysUserSource, Sys_user.class);
//重新设置
user.setId(R.UU32());
//密码设置 都走单点登录
user.setPassword(R.UU32());
String salt = R.UU32();
user.setSalt(salt);
user.setPassword(PwdUtil.getPassword(user.getPassword(), salt));
user.setLoginCount(0);
newUsers.add(user);
}
}
//添加新入职用户
if (ObjectUtil.isNotEmpty(newUsers)) {
SysRoleServiceImpl sysRoleService = Mvcs.getIoc().get(SysRoleServiceImpl.class);
Sys_role publicRole = sysRoleService.getByCode(RoleConstant.PUBLIC);
dao.fastInsert(newUsers);
//新增用户添加公共角色
List<Sys_user_role> sysUserRoles = newUsers.stream().map(user -> {
Sys_user_role sysUserRole = new Sys_user_role();
sysUserRole.setUserId(user.getId());
sysUserRole.setRoleId(publicRole.getId());
return sysUserRole;
}).toList();
dao.insert(sysUserRoles);
sysRoleService.clearCache();
//新增用户加入到变更记录表
List<Sys_user_history> sysUserHistories = newUsers.stream().map(user -> {
Sys_user_history history = BeanUtil.copyProperties(user, Sys_user_history.class);
history.setChangeTypes(List.of(MemberChangeType.NEW.name()));
history.setChangeTime(nowDate);
history.setChangeOrigin(MemberChangeOrigin.SYSTEM.name());
return history;
}).collect(Collectors.toList());
dao.fastInsert(sysUserHistories);
}
//修改基本信息异动的用户 单位异动的用户
if (ObjectUtil.isNotEmpty(basicAfterChangeUsers)) {
Set<String> allowChangeFieldNames = new HashSet<>(Arrays.asList(INFO_CENTER_PUSH_FIELDS));
//更新信息
manyAddOrRenewUtil.asyncExecuteUpdateIgnoreNull(basicAfterChangeUsers, 200);
// dao.updateIgnoreNull(basicAfterChangeUsers);
List<String> removeMemberRoleUserIds = new ArrayList<>();
//变更记录
List<Sys_user_history> sysUserHistories = basicBeforeChangeUsers.stream().map(user -> {
if (List.of("辞职", "离职", "退休", "调出", "死亡", "退休死亡", "解聘", "长病假").contains(user.getUserState())) {
removeMemberRoleUserIds.add(user.getId());
if (isUserMember && !isEligibleForMember) {
removeMemberUserIds.add(user.getId());
source.setMember(false);
} else if (!isUserMember && isEligibleForMember) {
addMemberUserIds.add(user.getId());
source.setMember(true);
}
Sys_user_history history = BeanUtil.copyProperties(user, Sys_user_history.class);
history.setId(R.UU32());
history.setChangeTypes(basicChangeUserMap.get(user.getLoginname()).stream().toList());
}
}
}
history.setChangeTime(nowDate);
history.setChangeOrigin(MemberChangeOrigin.SYSTEM.name());
return history;
}).collect(Collectors.toList());
// manyAddOrRenewUtil.asyncExecuteFastInsert(sysUserHistories, 200);
dao.fastInsert(sysUserHistories);
// 存储在职状态变为退休 的人员id
Set<String> retireUserIds = new HashSet<>();
// 将变更详情记录,新增用户由于没有任何变更,直接摒弃
List<Sys_user_change_info> userChangeInfoList = sysUserHistories.stream().map(previous -> {
// 当前的数据,上面已经更改了sys_user,那么最新的数据就是从source中获取
Sys_user sysUser = userMap.get(previous.getLoginname());
Sys_user_history current = BeanUtil.copyProperties(sysUser, Sys_user_history.class);
// 比较出变更了的字段,记录变更数据
List<NutMap> changeInfos = memberManageService.compareChange(current, previous, allowChangeFieldNames, DICT_MAP);
// str 类型的 变更记录,可便于导出和直接展示
String changeInfoStr = changeInfos.stream().map(v -> {
// 记录在职状态 变成退休的人的id
if ("userState".equals(v.getString("fieldName")) && "退休".equals(v.getString("newValue"))) {
retireUserIds.add(sysUser.getId());
/**
* 数据大批量更新
* @param needDoUpdateList 需要更新的数据
*/
private void massUpdatesAsync(List<Sys_user> needDoUpdateList) {
// 线程去更新
int numberOfThreads = Runtime.getRuntime().availableProcessors() * 2;
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(executorService);
int batchSize = 200;
// 共享锁
Lock lock = new ReentrantLock();
try {
for (int i = 0; i < needDoUpdateList.size(); i += batchSize) {
final int end = Math.min(i + batchSize, needDoUpdateList.size());
List<Sys_user> batch = needDoUpdateList.subList(i, end);
ecs.submit(() -> {
lock.lock();
try {
dao.updateIgnoreNull(batch);
} finally {
lock.unlock();
}
return "(变更字段:" + v.getString("name") + ",变更前:" + HtmlUtil.cleanHtmlTag(v.getString("value")) + ",变更后:" + HtmlUtil.cleanHtmlTag(v.getString("newValue")) + ")";
}).collect(Collectors.joining(""));
// 上面变更的字段和数据,就直接记录在这张表里
Sys_user_change_info info = new Sys_user_change_info();
info.setUserId(sysUser.getId());
info.setLoginname(current.getLoginname());
info.setUsername(current.getUsername());
info.setUserHistoryId(previous.getId());
info.setChangeTime(nowDate);
info.setChangeOrigin(previous.getChangeOrigin());
info.setChangeInfos(changeInfos);
info.setChangeInfosStr(changeInfoStr);
return info;
}).toList();
manyAddOrRenewUtil.asyncExecuteFastInsert(userChangeInfoList, 200);
return null;
});
}
if (Lang.isNotEmpty(retireUserIds)) {
// 是否有退休用户,有:存储当前的退休时间,删除会员角色
Sql sql = Sqls.create("update sys_user set retireDate = now() where id in (@userId)").setParam("userId", retireUserIds);
dao.execute(sql);
removeMemberRoleUserIds.addAll(retireUserIds);
// 删除会员角色
Sys_role role = dao.fetch(Sys_role.class, Cnd.where("`code`", "=", RoleConstant.MEMBER.name()));
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", removeMemberRoleUserIds).and("roleId", "=", role.getId()));
dao.update(Sys_user.class, Chain.make("member", false), Cnd.where("id", "in", removeMemberRoleUserIds));
for (int i = 0; i < needDoUpdateList.size(); i += batchSize) {
try {
Future<Void> future = ecs.take();
future.get();
} catch (InterruptedException | ExecutionException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Error during batch update", e);
}
}
} catch (Exception e) {
log.error("Error in massUpdatesAsync", e);
throw new RuntimeException("Error in massUpdatesAsync", e);
} finally {
executorService.shutdown();
try {
if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
if (Lang.isNotEmpty(userIdList)) {
// 删除有关单位的角色
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", userIdList)
.and(Cnd.exps("unitId", "is not", null).or("unionId", "is not", null)));
// 单位异动人员发送订阅
MemberChangeType unitChange = MemberChangeType.UNIT_CHANGE;
for (String userId : userIdList) {
SysUserPublisher.notify(SysUserEvent.builder().memberChangeType(unitChange).userId(userId).build());
}
}
return "";
}
}
@@ -88,7 +88,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
Sys_user_source sysUser = new Sys_user_source();
sysUser.setLoginname(jsonObject.getStr("zgh"));
sysUser.setUsername(jsonObject.getStr("xm"));
sysUser.setSex(jsonObject.getStr("xbmc"));
sysUser.setSex(StrUtil.equals("男性", jsonObject.getStr("xbmc")) ? "" : StrUtil.equals("女性", jsonObject.getStr("xbmc")) ? "" : null);
sysUser.setBirthday(jsonObject.getDate("csrq"));
sysUser.setNativePlace(jsonObject.getStr("jgmc"));
sysUser.setNationality(jsonObject.getStr("gjdqmc"));
@@ -99,19 +99,18 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
sysUser.setUnitName(jsonObject.getStr("dwmc"));
sysUser.setUnitId(jsonObject.getStr("dwdm"));
sysUser.setUserState(jsonObject.getStr("jzgdqztmc"));
sysUser.setEmploymentType(jsonObject.getStr("yrfsmc"));
sysUser.setPreparedBy(jsonObject.getStr("yrfsmc"));
sysUser.setPersonType(jsonObject.getStr("jzglbmc"));
sysUser.setEducation(jsonObject.getStr("zgxlmc"));
sysUser.setAcademicDegree(jsonObject.getStr("zgxwmc"));
sysUser.setMobile(jsonObject.getStr("sjh"));
sysUser.setStaffCategory(jsonObject.getStr("jzglbmc"));
sysUser.setStaffType(jsonObject.getStr("jzglbmc"));
sysUser.setJoinPartyDate(jsonObject.getDate("rdsj"));
sysUser.setTechnicalTitle(jsonObject.getStr("zyjszwmc"));
sysUser.setTechnicalTitleLevel(jsonObject.getStr("zyjszwjbmc"));
sysUser.setPosition(jsonObject.getStr("gbzw"));
sysUser.setPositionLevel(jsonObject.getStr("gbzwjbmc"));
sysUser.setEmployeeLevel(jsonObject.getStr("zydjmc"));
sysUser.setArrivalAtSchoolDate(jsonObject.getDate("lxny"));
sysUser.setArrivalAtSchoolDate(jsonObject.getStr("lxny"));
sysUser.setRetireDate(jsonObject.getDate("yjtxrq"));
sysUser.setIdentityType(jsonObject.getStr("grsfmc"));
sysUser.setPullTime(nowDate);
@@ -161,7 +160,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
//判断是否要更新学位字典
List<String> sourceAcademicDegrees = userSources.stream().map(Sys_user::getAcademicDegree).filter(StrUtil::isNotBlank).distinct().toList();
//判断是否要更新教职工类别字典
List<String> sourceStaffTypes = userSources.stream().map(Sys_user::getStaffType).filter(StrUtil::isNotBlank).distinct().toList();
List<String> personTypes = userSources.stream().map(Sys_user::getPersonType).filter(StrUtil::isNotBlank).distinct().toList();
//判断是否要更新身份类型字典
List<String> sourceIdentityTypes = userSources.stream().map(Sys_user::getIdentityType).filter(StrUtil::isNotBlank).distinct().toList();
@@ -270,27 +269,27 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
SELECT
unitName,
userState,
employmentType,
staffType
preparedBy,
personType
FROM
sys_user_source
GROUP BY
unitName,
userState,
employmentType,
staffType
preparedBy,
personType
""");
List<NutMap> list = listMap(sql);
List<String> unitNames = list.stream().map(user -> user.getString("unitName")).distinct().toList();
List<String> userStates = list.stream().map(user -> user.getString("userState")).distinct().toList();
List<String> preparedBys = list.stream().map(user -> user.getString("employmentType")).distinct().toList();
List<String> personTypes = list.stream().map(user -> user.getString("staffType")).distinct().toList();
List<String> preparedBys = list.stream().map(user -> user.getString("preparedBy")).distinct().toList();
List<String> personTypes = list.stream().map(user -> user.getString("personType")).distinct().toList();
return NutMap.NEW()
.addv("unitNames", unitNames)
.addv("userStates", userStates)
.addv("employmentTypes", preparedBys)
.addv("staffTypes", personTypes);
.addv("preparedBys", preparedBys)
.addv("personTypes", personTypes);
}
@Override
@@ -90,10 +90,10 @@ public class View_user {
private Date arrivalAtSchoolDate;
@Column
private String staffType;
private String personType;
@Column
private String employmentType;
private String preparedBy;
@Column
private String identityType;
@@ -173,7 +173,7 @@ public class BenefitProjectServiceImpl extends BaseServiceImpl<BenefitProject> i
benefitUser.setLoginName(v.getLoginname());
benefitUser.setUnionId(v.getUnionId());
benefitUser.setUnitId(v.getUnitId());
benefitUser.setPersonType(v.getStaffType());
benefitUser.setPersonType(v.getPersonType());
benefitUser.setUserState(v.getUserState());
if (project.getProvideMode().equals("BENEFIT_PROVIDE_MODE_ONE") && !project.getSignMode().equals("BENEFIT_SIGN_MODE_TWO")) {
//如果发放模式为统一发放并且不需要签字的话,默认设置为已签收
@@ -115,7 +115,7 @@ public class BenefitUserServiceImpl extends BaseServiceImpl<BenefitUser> impleme
benefitUser.setLoginName(v.getLoginname());
benefitUser.setUnionId(v.getUnionId());
benefitUser.setUnitId(v.getUnitId());
benefitUser.setPersonType(v.getStaffType());
benefitUser.setPersonType(v.getPersonType());
benefitUser.setUserState(v.getUserState());
return benefitUser;
}).collect(Collectors.toList());
@@ -153,7 +153,7 @@ public class BenefitUserServiceImpl extends BaseServiceImpl<BenefitUser> impleme
benefitUser.setBenefitId(businessId);
benefitUser.setUnionId(user.getUnionId());
benefitUser.setUnitId(user.getUnitId());
benefitUser.setPersonType(user.getStaffType());
benefitUser.setPersonType(user.getPersonType());
benefitUser.setUserState(user.getUserState());
benefitUser.setLoginName(user.getLoginname());
benefitUser.setUserName(user.getUsername());
@@ -133,7 +133,6 @@ public class MemberBranchVerificationCheckController {
Sys_user user = BeanUtil.copyProperties(history, Sys_user.class);
user.setId(record.getUserId());
dao.update(user);
dao.clear(Sys_user_change_info.class, Cnd.where("userHistoryId", "=", history.getId()));
}
}
dao.insertOrUpdate(record);
@@ -35,9 +35,9 @@ public class MemberStatisticsPageForm extends PageForm {
private List<String> unionGroupId;
private List<String> staffTypes;
private List<String> personTypes;
private List<String> employmentTypes;
private List<String> preparedBys;
private List<String> userStates;
@@ -81,6 +81,16 @@ public interface MemberManageService extends BaseService<Sys_user> {
void compareMemberChangeInfoAndUpdateUser(MemberApplyRecord record);
/**
* 比较两个对象,并记录变更的字段工具
*
* @param newMap 新数据
* @param sourceMap 原数据
* @param fieldsMap 变更字段
* @param changeList 变更集合
*/
void extractChange(NutMap newMap, NutMap sourceMap, String fieldName, Map<String, String> fieldsMap, List<NutMap> changeList);
/**
* 获取会员变更信息,memberApplyRecord表中名单核对事项人员与sys_user表中人员对比
* @param userId
@@ -295,11 +295,11 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
*/
@Override
public List<NutMap> compareMemberChangeInfo(Sys_user_history history) {
Sys_user_change_info info = dao().fetch(Sys_user_change_info.class, Cnd.where("userHistoryId", "=", history.getId()));
if (ObjectUtil.isEmpty(info)) {
List<NutMap> infos = history.getChangeInfos();
if (ObjectUtil.isEmpty(infos)) {
throw new BaseException("获取变更记录失败");
}
return info.getChangeInfos();
return infos;
}
/**
@@ -414,7 +414,7 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
chain.add("member", record.getMember());
chain.add("welfareMember", record.getWelfareMember());
dao().insert(history);
Sys_role memberRole = dao().fetch(Sys_role.class, Cnd.where("`code`", "=", "MEMBER"));
dao().clear(Sys_user_role.class, Cnd.where("userId", "=", user.getId()).and("roleId","=", memberRole.getId()));
@@ -434,18 +434,10 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
return "(变更字段:" + v.getString("name") + ",变更前:" + HtmlUtil.cleanHtmlTag(v.getString("value")) + ",变更后:" + HtmlUtil.cleanHtmlTag(v.getString("newValue")) + ")";
}).collect(Collectors.joining(""));
record.setChangeInfos(changeInfos);
// dao().updateIgnoreNull(record);
Sys_user_change_info userChangeInfo = new Sys_user_change_info();
userChangeInfo.setUserId(record.getUserId());
userChangeInfo.setLoginname(record.getLoginname());
userChangeInfo.setUsername(record.getUsername());
userChangeInfo.setUserHistoryId(history.getId());
userChangeInfo.setChangeTime(nowDate);
userChangeInfo.setChangeOrigin(history.getChangeOrigin());
userChangeInfo.setChangeInfos(changeList);
userChangeInfo.setChangeInfosStr(changeInfos);
dao().insert(userChangeInfo);
history.setChangeInfos(changeList);
history.setChangeInfosStr(changeInfos);
dao().insert(history);
dao().update(Sys_user.class, chain, Cnd.where("loginname", "=", record.getLoginname()));
} else {
@@ -489,7 +481,8 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
* @param dictMap 字典数据
* @param changeList 变更集合
*/
private void extractChange(NutMap current, NutMap previous, String fieldName, Map<String, String> dictMap, List<NutMap> changeList) {
@Override
public void extractChange(NutMap current, NutMap previous, String fieldName, Map<String, String> dictMap, List<NutMap> changeList) {
try {
Object currentValue = this.booleanVerification(current.get(fieldName));
Object previousValue = this.booleanVerification(previous.get(fieldName));
@@ -527,10 +520,13 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
return ((Boolean) value) ? "" : "";
}
// 处理数值类型
if (value instanceof Number && List.of(0,1).contains((Integer) value)) {
if (value instanceof Number && List.of(0, 1).contains((Integer) value)) {
return ((Number) value).intValue() != 0 ? "" : "";
}
// 其他对象,返回其字符串表示
if (value instanceof Date) {
return DateUtil.format((Date) value, "yyyy-MM-dd");
}
return value.toString();
}
}
@@ -87,8 +87,8 @@ public class MemberStatisticsServiceImpl extends BaseServiceImpl<Sys_user> imple
try {
handleField("unionId", pageForm.getUnionId(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("unitId", pageForm.getUnitId(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("staffType", pageForm.getStaffTypes(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("employmentType", pageForm.getEmploymentTypes(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("personType", pageForm.getPersonTypes(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("preparedBy", pageForm.getPreparedBys(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("userState", pageForm.getUserStates(), reverseSelection, IN_OR_NIN_OP, cnd);
handleField("sex", pageForm.getSexTypes(), reverseSelection, IN_OR_NIN_OP, cnd);
cnd.andEX("sur.roleId", IN_OR_NIN_OP, pageForm.getRoleIds());
@@ -137,11 +137,10 @@ public class MemberStatisticsServiceImpl extends BaseServiceImpl<Sys_user> imple
u.positionLevel,
u.employeeLevel,
u.arrivalAtSchoolDate,
u.staffCategory,
u.employmentType,
u.personType,
u.preparedBy,
u.identityType,
u.userState,
u.staffType,
u.unionName,
u.unitName,
u.member
@@ -275,7 +275,7 @@ public class WelfareListController {
list.setWelfareUnitId(user.getUnionId());
list.setProjectId(businessId);
list.setWelfareSecondLevelUnitId(user.getUnitId());
list.setPersonType(user.getStaffType());
list.setPersonType(user.getPersonType());
list.setUserState(user.getUserState());
welfareLists.add(list);
} else {
@@ -367,7 +367,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
welfareList.setUserId(v.getId());
welfareList.setWelfareUnitId(v.getUnionId());
welfareList.setWelfareSecondLevelUnitId(v.getUnitId());
welfareList.setPersonType(v.getStaffType());
welfareList.setPersonType(v.getPersonType());
welfareList.setUserState(v.getUserState());
return welfareList;
}).collect(Collectors.toList());
@@ -15,7 +15,6 @@
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="是否会员">{{ viewData.member ? "是" : "否" }}</el-descriptions-item>
<el-descriptions-item label="是否福利会员">{{ viewData.welfareMember ? "是" : "否" }}</el-descriptions-item>
<el-descriptions-item label="是否重疾互助会会员">{{ viewData.wantJoinLoveMutualAidAssociation ? "是" : "否" }}</el-descriptions-item>
<el-descriptions-item label="所属工会、工作部门(学院)及职务" span="3">
<template slot="label">工作部门学院及岗位</template>
<div class="text-left">
@@ -38,13 +38,13 @@ layout("/layouts/platform.html"){
</el-select>
</search-item>
<search-item label="用人方式">
<el-select v-model="pageForm.employmentType" clearable filterable>
<el-option v-for="item in employmentTypeOptions" :label="item" :value="item"></el-option>
<el-select v-model="pageForm.preparedBy" clearable filterable>
<el-option v-for="item in preparedByOptions" :label="item" :value="item"></el-option>
</el-select>
</search-item>
<search-item label="教职工类别">
<el-select v-model="pageForm.staffType" clearable filterable>
<el-option v-for="item in staffTypeOptions" :label="item" :value="item"></el-option>
<el-select v-model="pageForm.personType" clearable filterable>
<el-option v-for="item in personTypeOptions" :label="item" :value="item"></el-option>
</el-select>
</search-item>
</search>
@@ -64,8 +64,8 @@ layout("/layouts/platform.html"){
<el-table-column prop="mobile" label="手机号" width="120"></el-table-column>
<el-table-column prop="birthday" label="生日" sortable width="120"></el-table-column>
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
<el-table-column prop="employmentType" label="用人方式" sortable width="120"></el-table-column>
<el-table-column prop="staffType" label="教职工类别" sortable width="120"></el-table-column>
<el-table-column prop="preparedBy" label="用人方式" sortable width="120"></el-table-column>
<el-table-column prop="personType" label="教职工类别" sortable width="120"></el-table-column>
<el-table-column prop="comeSchoolDate" label="来校年月" sortable width="120"></el-table-column>
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<el-table-column prop="position" label="干部职务" sortable width="120" show-overflow-tooltip></el-table-column>
@@ -103,8 +103,8 @@ layout("/layouts/platform.html"){
return {
unitNameOptions: [],
userStateOptions: [],
employmentTypeOptions:[],
staffTypeOptions: [],
preparedByOptions:[],
personTypeOptions: [],
pullTimeOptions: false,
sourceTime: null,
pullTimeDialogVisible: false
@@ -133,8 +133,8 @@ layout("/layouts/platform.html"){
if (resp.code === 0) {
this.unitNameOptions = resp.data.unitNames
this.userStateOptions = resp.data.userStates
this.staffTypeOptions = resp.data.staffTypes
this.employmentTypeOptions = resp.data.employmentTypes
this.personTypeOptions = resp.data.personTypes
this.preparedByOptions = resp.data.preparedBys
}
})
},
@@ -62,7 +62,7 @@ layout("/layouts/platform.html"){
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
<el-table-column prop="preparedBy" label="人事编制" sortable width="120"></el-table-column>
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
<el-table-column prop="comeSchoolDate" label="来校年月" sortable width="120"></el-table-column>
<el-table-column prop="arrivalAtSchoolDate" label="来校年月" sortable width="120"></el-table-column>
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<el-table-column prop="governmentPosition" label="党政职务" sortable width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="education" label="学历" show-overflow-tooltip sortable width="120"></el-table-column>
@@ -28,9 +28,6 @@ const MEMBER_AUDIT_CHANGE_INFO = {
<el-descriptions-item label="是否会员">{{ viewData.member ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否福利会员">{{ viewData.welfareMember ? '是' : '否' }}
</el-descriptions-item>
<el-descriptions-item label="是否重疾互助会会员">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' : '否'
}}
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="所属工会、工作部门(学院)及职务" span="3">
<template slot="label">工作部门学院及岗位</template>
@@ -22,7 +22,6 @@ const MEMBER_CHANGE_INFO = {
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="是否会员">{{ viewData.member ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否福利会员">{{ viewData.welfareMember ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否重疾互助会会员">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="所属工会、工作部门(学院)及职务" span="3">
<template slot="label">工作部门学院及岗位</template>
@@ -17,8 +17,8 @@
<el-descriptions-item label="入党时间">{{ viewData.joinPartyDate ? $moment(viewData.joinPartyDate).format('YYYY-MM-DD') : null }}</el-descriptions-item>
<el-descriptions-item label="来校时间">{{ viewData.arrivalAtSchoolDate ? $moment(viewData.arrivalAtSchoolDate).format('YYYY-MM-DD') : null}}</el-descriptions-item>
<el-descriptions-item label="身份类别">{{ viewData.identityType }}</el-descriptions-item>
<el-descriptions-item label="聘用方式">{{ viewData.employmentType }}</el-descriptions-item>
<el-descriptions-item label="教职工类别">{{ viewData.staffType }}</el-descriptions-item>
<el-descriptions-item label="聘用方式">{{ viewData.preparedBy }}</el-descriptions-item>
<el-descriptions-item label="教职工类别">{{ viewData.personType }}</el-descriptions-item>
<el-descriptions-item label="在职状态">{{ viewData.userState }}</el-descriptions-item>
<el-descriptions-item label="预计离退休时间">{{ viewData.retireDate ?
$moment(viewData.retireDate).format('YYYY-MM-DD') : null }}
@@ -28,9 +28,6 @@
<el-descriptions-item label="是否会员">{{ viewData.member ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否福利会员">{{ viewData.welfareMember ? '是' : '否' }}
</el-descriptions-item>
<el-descriptions-item label="是否重疾互助会会员">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' :
'否' }}
</el-descriptions-item>
</el-descriptions>
<div class="process-title">学历信息</div>
@@ -19,7 +19,6 @@ const MEMBER_VERIFICATION_CHANGE = {
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
<el-descriptions-item label="是否会员">{{ viewData.member ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否福利会员">{{ viewData.welfareMember ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="是否重疾互助会会员">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<el-descriptions-item label="所属工会、工作部门(学院)及职务" span="3">
<template slot="label">工作部门学院及岗位</template>
@@ -10,34 +10,48 @@ layout("/layouts/platform.html"){
/*color: #ff0000;*/
margin-bottom: 10px;
}
.query-row {
height: 55px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.query-row:not(:last-child) {
border-bottom: 1px dashed rgb(230, 230, 230);
border-bottom: 1px dashed rgb(230, 230, 230);
}
.el-divider__text {
position: absolute;
background-color: var(--color-white);
padding: 0 !important;
font-weight: 500;
color: var(--color-text-primary);
font-size: 14px;
}
/*.query-row:not(:last-child,:first-child) {*/
/* height: 70px;*/
/*}*/
.query-row-title {
width: 120px;
width: 120px;
}
.query-row > .query-title {
width: 100px;
max-width: 100px;
min-width: 100px;
overflow: hidden;
}
.query-row > .query-content {
min-width: 200px;
overflow: hidden;
}
.query-row > .query-content > .el-tag {
margin-bottom: 5px;
margin-top: 5px;
}
@media screen and (max-width: 992px) {
.query-row:nth-child(4) .query-content .el-col:not(:last-child) {
margin-bottom: 5px;
}
.query-title {
display: none;
}
}
</style>
<div id="app" v-cloak>
@@ -64,79 +78,83 @@ layout("/layouts/platform.html"){
</search-item>
</search>
</el-card>
<el-card shadow="never" style="margin-top: 10px">
<el-row type="flex" align="middle" class="query-row">
<el-col class="query-row-title">人员类型</el-col>
<el-col class="query-row-content">
<el-tag
style="margin-right: 10px;cursor: pointer"
v-for="item in personTypeOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.personTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('personTypes',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="personTypeOptions.length&&pageForm.personTypes.length"
:underline="false"
@click="pageForm.personTypes=[];doSearch()">清空
</el-link>
</el-col>
</el-row>
<el-row type="flex" align="middle" class="query-row">
<el-col class="query-row-title">人事编制:</el-col>
<el-col class="query-row-content">
<el-tag
style="margin-right: 10px;cursor: pointer"
v-for="item in preparedByOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.preparedBys.includes(item.name)?'dark':'plain'"
@click="tagClick('preparedBys',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="preparedByOptions.length&&pageForm.preparedBys.length"
:underline="false"
@click="pageForm.preparedBys=[];doSearch()">清空
</el-link>
</el-col>
</el-row>
<el-row type="flex" align="middle" class="query-row">
<el-col class="query-row-title">在职状态:</el-col>
<el-col class="query-row-content">
<el-tag
style="margin-right: 10px;cursor: pointer"
v-for="item in userStateOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.userStates.includes(item.name)?'dark':'plain'"
@click="tagClick('userStates',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="userStateOptions.length&&pageForm.userStates.length"
:underline="false"
@click="pageForm.userStates=[];doSearch()">清空
</el-link>
</el-col>
</el-row>
<el-row type="flex" align="middle" class="query-row">
<el-col class="query-row-title">模糊查询:</el-col>
<el-col class="query-row-content">
<member-cnd @cnd="(v)=>pageForm={...pageForm,...v}"></member-cnd>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" class="mt10">
<el-row type="flex" align="middle" class="query-row" style="height: unset;padding: 10px 0">
<el-col class="query-row-title">在职状态</el-col>
<el-col class="query-row-content" style="display: flex;flex-wrap: wrap;gap: 5px">
<el-tag
style="margin:0;cursor: pointer"
v-for="item in userStateOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.userStates.includes(item.name)?'dark':'plain'"
@click="tagClick('userStates',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="userStateOptions.length&&pageForm.userStates.length"
:underline="false"
@click="pageForm.userStates=[];doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.userStates=userStateOptions.map(p=>p.code);doSearch()"
type="success">全部
</el-link>
</el-col>
</el-row>
<el-row type="flex" align="middle" class="query-row" style="height: unset;padding: 10px 0">
<el-col class="query-row-title">教职工类别:</el-col>
<el-col class="query-row-content" style="display: flex;flex-wrap: wrap;gap: 5px">
<el-tag
style="margin:0;cursor: pointer"
v-for="item in personTypeOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.personTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('personTypes',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="personTypeOptions.length&&pageForm.personTypes.length"
:underline="false"
@click="pageForm.personTypes=[];doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.personTypes=personTypeOptions.map(p=>p.code);doSearch()"
type="success">全部
</el-link>
</el-col>
</el-row>
<el-row type="flex" align="middle" class="query-row" style="height: unset;padding: 10px 0">
<el-col class="query-row-title">聘用方式:</el-col>
<el-col class="query-row-content" style="display: flex;flex-wrap: wrap;gap: 5px">
<el-tag
style="margin:0;cursor: pointer"
v-for="item in preparedByOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.preparedBys.includes(item.name)?'dark':'plain'"
@click="tagClick('preparedBys',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="preparedByOptions.length&&pageForm.preparedBys.length"
:underline="false"
@click="pageForm.preparedBys=[];doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.preparedBys=preparedByOptions.map(p=>p.code);doSearch()"
type="success">全部
</el-link>
</el-col>
</el-row>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="会员列表">
@@ -293,8 +311,8 @@ layout("/layouts/platform.html"){
this.unions = await this.$businessTool.listUnion(store?.state.user.union.id)
this.units = await this.$businessTool.listUnit(store?.state.user.union.id)
}
this.personTypeOptions = await this.$businessTool.getDictOptions('PERSON_TYPE')
this.preparedByOptions = await this.$businessTool.getDictOptions('PREPARED_BY')
this.personTypeOptions = await this.$businessTool.getDictOptions('USER_STAFF_TYPE')
this.preparedByOptions = await this.$businessTool.getDictOptions('USER_EMPLOYMENT_TYPE')
this.userStateOptions = await this.$businessTool.getDictOptions('USER_STATE')
},
async flushUnits() {
@@ -145,8 +145,8 @@ layout("/layouts/platform.html"){
{prop: 'idCardType', label: '证件类型'},
{prop: 'idCard', label: '证件号码', width: 180},
{prop: 'userState', label: '在职状态', sortable: true},
{prop: 'staffType', label: '教职工类别', sortable: true},
{prop: 'employmentType', label: '聘用方式', sortable: true},
{prop: 'personType', label: '教职工类别', sortable: true},
{prop: 'preparedBy', label: '聘用方式', sortable: true},
{prop: 'identityType', label: '身份类型', sortable: true},
{prop: 'unionName', label: '所属工会', sortable: true},
{prop: 'unitName', label: '所属单位', sortable: true},
@@ -99,21 +99,21 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
<el-col class="query-row-content" style="display: flex;flex-wrap: wrap;gap: 5px">
<el-tag
style="margin:0;cursor: pointer"
v-for="item in staffTypeOptions"
v-for="item in personTypeOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.staffTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('staffTypes',item.name)">
:effect="pageForm.personTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('personTypes',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="staffTypeOptions.length&&pageForm.staffTypes.length"
v-if="personTypeOptions.length&&pageForm.personTypes.length"
:underline="false"
@click="pageForm.staffTypes=[];doSearch()">清空
@click="pageForm.personTypes=[];doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.staffTypes=staffTypeOptions.map(p=>p.code);doSearch()"
@click="pageForm.personTypes=personTypeOptions.map(p=>p.code);doSearch()"
type="success">全部
</el-link>
</el-col>
@@ -124,21 +124,21 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
<el-col class="query-row-content" style="display: flex;flex-wrap: wrap;gap: 5px">
<el-tag
style="margin:0;cursor: pointer"
v-for="item in employmentTypeOptions"
v-for="item in preparedByOptions"
:key="item.code"
:type="item.name"
:effect="pageForm.employmentTypes.includes(item.name)?'dark':'plain'"
@click="tagClick('employmentTypes',item.name)">
:effect="pageForm.preparedBys.includes(item.name)?'dark':'plain'"
@click="tagClick('preparedBys',item.name)">
{{ item.name }}
</el-tag>
<el-link type="danger"
v-if="employmentTypeOptions.length&&pageForm.employmentTypes.length"
v-if="preparedByOptions.length&&pageForm.preparedBys.length"
:underline="false"
@click="pageForm.employmentTypes=[];doSearch()">清空
@click="pageForm.preparedBys=[];doSearch()">清空
</el-link>
<el-link :underline="false"
@click="pageForm.employmentTypes=employmentTypeOptions.map(p=>p.code);doSearch()"
@click="pageForm.preparedBys=preparedByOptions.map(p=>p.code);doSearch()"
type="success">全部
</el-link>
</el-col>
@@ -210,8 +210,8 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
unionGroupId: [],
threeUnitId: [],
searchName: "username",
staffTypes: [],
employmentTypes: [],
personTypes: [],
preparedBys: [],
userStates: [],
memberStatus: [],
year: moment().format("YYYY"),
@@ -226,8 +226,8 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
startDate: "",
endDate: ""
},
staffTypeOptions: [],
employmentTypeOptions: [],
personTypeOptions: [],
preparedByOptions: [],
userStateOptions: [],
memberStatusOptions: [],
unions: [],
@@ -275,11 +275,11 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
this.doSearch()
},
/*checkPersonType(type) {
let idx = this.pageForm.staffTypes.indexOf(type)
let idx = this.pageForm.personTypes.indexOf(type)
if (idx !== -1) {
this.pageForm.staffTypes.splice(idx, 1)
this.pageForm.personTypes.splice(idx, 1)
} else {
this.pageForm.staffTypes.push(type)
this.pageForm.personTypes.push(type)
}
this.doSearch()
},*/
@@ -313,8 +313,8 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
this.pageForm.userId = []
this.pageForm.memberTypes = []
this.pageForm.sexTypes = []
this.pageForm.staffTypes = []
this.pageForm.employmentTypes = []
this.pageForm.personTypes = []
this.pageForm.preparedBys = []
this.pageForm.memberStatus = []
this.pageForm.userStates = []
this.pageForm.unionId = []
@@ -352,10 +352,10 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
this.units = await this.$businessTool.listUnit(this.$store.state.user.union.id)
}
this.$businessTool.getDictOptions("USER_STAFF_TYPE").then((data) => {
this.staffTypeOptions = data
this.personTypeOptions = data
})
this.$businessTool.getDictOptions("USER_EMPLOYMENT_TYPE").then((data) => {
this.employmentTypeOptions = data
this.preparedByOptions = data
})
this.$businessTool.getDictOptions("USER_STATE").then((data) => {
this.userStateOptions = data
@@ -385,8 +385,8 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
pageForm.unitId = JSON.stringify(this.pageForm.unitId)
pageForm.sexTypes = JSON.stringify(this.pageForm.sexTypes)
pageForm.memberTypes = JSON.stringify(this.pageForm.memberTypes)
pageForm.staffTypes = JSON.stringify(this.pageForm.staffTypes)
pageForm.employmentTypes = JSON.stringify(this.pageForm.employmentTypes)
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
pageForm.memberStatus = JSON.stringify(this.pageForm.memberStatus)
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
this.$axios.post("/platform/member/statistics/comprehensive/pageData", pageForm).then((data) => {