This commit is contained in:
那些花儿
2025-06-13 17:41:22 +08:00
parent 1f763c6f5f
commit 96a9b8aa27
26 changed files with 1154 additions and 522 deletions
@@ -116,8 +116,8 @@ public class MainLauncher {
try {
Daos.createTablesInPackage(dao, "com.budwk", false);
//通过POJO类修改表结构
// Daos.migration(dao, "com.budwk", true, false);
Daos.migration(dao, "com.budwk", true, false, false);
Daos.migration(dao, "com.budwk", true, false);
// Daos.migration(dao, "com.budwk", true, false, false);
} catch (Exception e) {
e.printStackTrace();
}
@@ -0,0 +1,21 @@
package com.budwk.app.sys.annotation;
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DataCenterColumn {
/*
* 列名
*/
String name();
/*
* 列key
*/
String key();
}
@@ -37,6 +37,7 @@ public class SysDataUserPullController {
@At
@SaCheckPermission("sys.data.user.pull")
@Ok("json:{dateFormat:'yyyy-MM-dd'}")
@ApiOperation("分页数据")
public Result pageData(@Valid SysDataUserPullPageForm pageForm) {
Cnd cnd = Cnd.NEW();
@@ -29,6 +29,7 @@ import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.util.Comparator;
@@ -105,7 +106,7 @@ public class SysDataUserUpdateController {
@SaCheckPermission("sys.data.user.pull")
@SLog(tag = "更新系统用户数据", msg = "更新数据")
@ApiOperation("更新数据")
public Result updateUserFormSource(@Valid SysDataUserUpdateParam updateParam) {
public Result updateUserFormSource(@Valid @Param("param") SysDataUserUpdateParam updateParam) {
SysDataUpdateMode updateMode = EnumUtil.getBy(SysDataUpdateMode.class, (val) -> val.name().equals(updateParam.getUpdateMode()));
if (ObjectUtil.isNull(updateMode)) {
return Result.error("更新模式错误,请传入正确的更新模式。");
@@ -2,6 +2,7 @@ package com.budwk.app.sys.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.sys.annotation.DataCenterColumn;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@@ -24,7 +25,6 @@ import java.util.List;
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_USER_LOGINNAMAE", fields = {"loginname"})})
public class Sys_user extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Name
@Comment("ID")
@@ -33,18 +33,21 @@ public class Sys_user extends BaseModel implements Serializable {
private String id;
@Column
@Comment("用户名")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 120)
@DataCenterColumn(name = "工号", key = "zgh")
private String loginname;
@Column
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
@DataCenterColumn(name = "姓名", key = "xm")
private String username;
@Column
@Comment("性别")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "性别", key = "xbmc")
private String sex;
@Column
@@ -60,106 +63,127 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("出生日期")
@ColDefine(type = ColType.DATE)
@DataCenterColumn(name = "出生日期", key = "csrq")
private Date birthday;
@Column
@Comment("政治面貌")
@ColDefine(type = ColType.VARCHAR, width = 100)
@DataCenterColumn(name = "政治面貌", key = "zzmmmc")
private String political;
@Column
@ColDefine(type = ColType.DATE)
@Comment("入党时间")
@DataCenterColumn(name = "入党时间", key = "rdsj")
private Date joinPartyDate;
@Column
@Comment("民族")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "民族", key = "mzmc")
private String nation;
@Column
@Comment("籍贯")
@ColDefine(type = ColType.VARCHAR, width = 100)
@DataCenterColumn(name = "籍贯", key = "jgmc")
private String nativePlace;
@Column
@Comment("国籍")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "国籍", key = "gjdqmc")
private String nationality;
@Column
@Comment("证件类型")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "证件类型", key = "sfzjlxmc")
private String idCardType;
@Column
@Comment("证件号码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "证件号码", key = "sfzjh")
private String idCard;
@Column
@Comment("手机号码")
@ColDefine(type = ColType.VARCHAR, width = 32)
@DataCenterColumn(name = "手机号码", key = "sjh")
private String mobile;
@Column
@Comment("学历")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "学历", key = "zgxlmc")
private String education;
@Column
@Comment("学位")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "学位", key = "zgxwmc")
private String academicDegree;
@Column
@Comment("技术职称")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "技术职称", key = "zyjszwmc")
private String technicalTitle;
@Column
@Comment("技术职称级别")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "技术职称级别", key = "zyjszwjbmc")
private String technicalTitleLevel;
@Column
@Comment("职务")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "职务", key = "gbzw")
private String position;
@Column
@Comment("职务级别")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "职务级别", key = "gbzwjbmc")
private String positionLevel;
@Column
@Comment("职员级别")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "职员级别", key = "zydjmc")
private String employeeLevel;
@Column
@Comment("来校时间")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "来校时间", key = "lxny")
private String arrivalAtSchoolDate;
@Column
@Comment("身份类型")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "身份类型", key = "grsfmc")
private String identityType;
@Column
@Comment("在职状态")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "在职状态", key = "jzgdqztmc")
private String userState;
@Column
@Comment("人员类别")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "人员类别", key = "jzglbmc")
private String personType;
@Column
@Comment("聘用方式")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "聘用方式", key = "yrfsmc")
private String preparedBy;
@Column
@@ -170,6 +194,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("博士后进站时间")
@ColDefine(type = ColType.DATE)
@DataCenterColumn(name = "博士后进站时间", key = "bhzjzsj")
private Date postDoctoralJoinDate;
@Column
@@ -10,7 +10,10 @@ import java.util.Date;
@Table("sys_user_source")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_USER_SOURCE_LOGINNAMAE", fields = {"loginname"}, unique = false)})
@TableIndexes({
@Index(name = "INDEX_SYS_USER_SOURCE_LOGINNAMAE", fields = {"loginname"}, unique = false),
@Index(name = "INDEX_SYS_USER_SOURCE_PULLTIME", fields = {"pullTime"}, unique = false)
})
@Comment("系统用户拉取数据表")
@Data
@EqualsAndHashCode(callSuper = true)
@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Data
@ApiModel("用户数据更新参数")
@@ -18,4 +19,36 @@ public class SysDataUserUpdateParam {
@NotBlank(message = "更新方式不能为空")
private String updateMode;
@ApiModelProperty("条件组 (可选)")
private ConditionGroup conditionGroup;
/**
* 条件组,支持嵌套的与或非逻辑
*/
@Data
public static class ConditionGroup {
@ApiModelProperty("逻辑类型:AND, OR")
private String logic = "AND";
@ApiModelProperty("条件列表")
private List<Condition> conditions;
@ApiModelProperty("嵌套条件组")
private List<ConditionGroup> groups;
}
/**
* 单个条件
*/
@Data
public static class Condition {
@ApiModelProperty("字段名")
private String field;
@ApiModelProperty("操作符: =, !=, >, <, >=, <=, LIKE, IN, NOT IN, IS NULL, IS NOT NULL")
private String operator;
@ApiModelProperty("字段值")
private Object value;
}
}
@@ -29,6 +29,7 @@ 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.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -75,6 +76,147 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
*/
private final List<String> MEMBER_PREPARED_BY = List.of("新人事代理", "校聘合同制", "事业编制", "博士后");
/**
* 处理条件组,将条件组转换为Cnd条件
*
* @param cnd 原始条件
* @param group 条件组
* @return 处理后的条件
*/
private Cnd applyConditionGroup(Cnd cnd, SysDataUserUpdateParam.ConditionGroup group) {
if (group == null) {
return cnd;
}
SqlExpressionGroup expGroup = new SqlExpressionGroup();
// 处理条件列表
if (group.getConditions() != null && !group.getConditions().isEmpty()) {
for (SysDataUserUpdateParam.Condition condition : group.getConditions()) {
expGroup = applyCondition(expGroup, condition, group.getLogic());
}
}
// 处理嵌套条件组
if (group.getGroups() != null && !group.getGroups().isEmpty()) {
for (SysDataUserUpdateParam.ConditionGroup nestedGroup : group.getGroups()) {
// 创建子条件
Cnd subCnd = Cnd.NEW();
subCnd = applyConditionGroup(subCnd, nestedGroup);
// 将子条件的表达式组添加到当前表达式组
if ("OR".equalsIgnoreCase(group.getLogic())) {
expGroup.or(subCnd.where());
} else {
expGroup.and(subCnd.where());
}
}
}
// 将表达式组添加到主条件
cnd.and(expGroup);
return cnd;
}
/**
* 处理单个条件
*
* @param expGroup 表达式组
* @param condition 条件
* @param logic 逻辑类型 (AND/OR)
* @return 处理后的表达式组
*/
private SqlExpressionGroup applyCondition(SqlExpressionGroup expGroup, SysDataUserUpdateParam.Condition condition, String logic) {
String field = condition.getField();
String operator = condition.getOperator();
Object value = condition.getValue();
// 根据操作符处理条件
switch (operator.toUpperCase()) {
case "=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "=", value);
} else {
expGroup.and(field, "=", value);
}
break;
case "!=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "!=", value);
} else {
expGroup.and(field, "!=", value);
}
break;
case ">":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, ">", value);
} else {
expGroup.and(field, ">", value);
}
break;
case "<":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "<", value);
} else {
expGroup.and(field, "<", value);
}
break;
case ">=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, ">=", value);
} else {
expGroup.and(field, ">=", value);
}
break;
case "<=":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "<=", value);
} else {
expGroup.and(field, "<=", value);
}
break;
case "LIKE":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "LIKE", "%" + value + "%");
} else {
expGroup.and(field, "LIKE", "%" + value + "%");
}
break;
case "IN":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IN", value);
} else {
expGroup.and(field, "IN", value);
}
break;
case "NOT IN":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "NOT IN", value);
} else {
expGroup.and(field, "NOT IN", value);
}
break;
case "IS NULL":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IS", null);
} else {
expGroup.and(field, "IS", null);
}
break;
case "IS NOT NULL":
if ("OR".equalsIgnoreCase(logic)) {
expGroup.or(field, "IS NOT", null);
} else {
expGroup.and(field, "IS NOT", null);
}
break;
default:
log.warn("不支持的操作符: {}", operator);
}
return expGroup;
}
/**
* 全量更新用户数据, 很慢、优化一下
@@ -89,23 +231,27 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
Sys_role publicRole = sysRoleService.getByCode(RoleConstant.PUBLIC);
Sys_role memberRole = sysRoleService.getByCode(RoleConstant.MEMBER);
//查询数据源
List<Sys_user_source> sources = dao.query(Sys_user_source.class, Cnd.where(Sys_user_source::getPullTime, "=", updateParam.getPullTime()).groupBy("loginname"));
//查询系统用户
// 查询数据源
Cnd cnd = Cnd.where(Sys_user_source::getPullTime, "=", updateParam.getPullTime());
// 处理复杂条件
if (updateParam.getConditionGroup() != null) {
cnd = applyConditionGroup(cnd, updateParam.getConditionGroup());
}
List<Sys_user_source> sources = dao.query(Sys_user_source.class, cnd.groupBy("loginname"));
log.info("符合条件的数据源记录数: {}", sources.size());
// 查询系统用户
List<Sys_user> sysUsers = dao.query(Sys_user.class, Cnd.NEW().groupBy("loginname"));
Map<String, Sys_user> userMap = sysUsers.stream().collect(Collectors.toMap(Sys_user::getLoginname, sysUser -> sysUser));
// 要修改的用户表
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_user> needDoUpdateList = new ArrayList<>();
List<Sys_user> needInitUserList = new ArrayList<>();
List<Sys_user_history> histories = new ArrayList<>();
List<String> addMemberUserIds = new ArrayList<>();
List<String> removeMemberUserIds = new ArrayList<>();
// 获取允许变更的字段,同时再加上单位字段
List<Sys_dict> dictList = sysDictService.getSubListByCode("MEMBER_ALLOW_CHANGES_FIELD");
@@ -114,104 +260,86 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
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);
// 处理每条数据
for (Sys_user_source source : sources) {
Sys_user user = userMap.get(source.getLoginname());
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
for (Sys_user_source source : batch) {
// 获取系统用户
Sys_user user = userMap.get(source.getLoginname());
// 创建用户对象
Sys_user u = new Sys_user();
BeanUtils.copyProperties(source, u);
// 进入系统的人
boolean isEnterUser = StrUtil.isNotBlank(source.getPreparedBy()) && MEMBER_PREPARED_BY.contains(source.getPreparedBy())
&& StrUtil.isNotBlank(source.getUserState()) && MEMBER_USER_STATE.contains(source.getUserState());
if (user == null) {
// 新增用户,初始化数据
String salt = R.UU32();
u.setSalt(salt);
u.setPassword(PwdUtil.getPassword(R.captchaNumber(6), salt));
needInitUserList.add(u);
} else {
// 修改现有用户
u.setId(user.getId());
needDoUpdateList.add(u);
}
// 去校验是不是会员
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);
// 随机密码
String pwd = R.captchaNumber(6);
u.setPassword(PwdUtil.getPassword(pwd, 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);
}
}
// 创建历史记录
Sys_user_history history = createHistory(source, user, dictMap, allowChangeFieldNames);
if (Lang.isNotEmpty(history)) {
if (user != null) {
histories.add(history);
} else if (Lang.isNotEmpty(history.getChangeTypes()) && history.getChangeTypes().contains(MemberChangeType.NEW.name())) {
histories.add(history);
}
}, Executors.newFixedThreadPool(numberOfThreads));
futures.add(future);
}
}
// 确保线程完全走完
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//如果有新用户,增加到用户表同时增加角色
// 处理结果
// 1. 新增用户并分配公共角色
if (Lang.isNotEmpty(needInitUserList)) {
sysUserService.fastInsert(needInitUserList);
log.info("新增用户: {} 个", needInitUserList.size());
dao.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);
dao.insert(roleList);
}
// 更新需要变更的用户
manyAddOrRenewUtil.asyncExecuteUpdateIgnoreNull(needDoUpdateList, 200);
// 添加历史记录
manyAddOrRenewUtil.asyncExecuteFastInsert(histories, 200);
// 2. 更新现有用户
if (Lang.isNotEmpty(needDoUpdateList)) {
log.info("更新用户: {} 个", needDoUpdateList.size());
dao.updateIgnoreNull(needDoUpdateList);
}
// 设置和移除会员角色
// 3. 添加历史记录
if (Lang.isNotEmpty(histories)) {
log.info("添加历史记录: {} 条", histories.size());
dao.fastInsert(histories);
}
// 4. 添加会员角色
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;
log.info("添加会员角色: {} 个", addMemberUserIds.size());
List<Sys_user_role> roleList = addMemberUserIds.stream().map(id -> {
Sys_user_role userRole = new Sys_user_role();
userRole.setRoleId(memberRole.getId());
userRole.setUserId(id);
return userRole;
}).toList();
manyAddOrRenewUtil.asyncExecuteInsert(roleList, 200);
// dao.update(Sys_user.class, Chain.make("member", true), Cnd.where("id", "in", addMemberUserIds));
dao.insert(roleList);
}
// 5. 移除会员角色
if (Lang.isNotEmpty(removeMemberUserIds)) {
log.info("移除会员角色: {} 个", removeMemberUserIds.size());
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 "";
return "更新完成: 新增用户 " + needInitUserList.size() + " 个, 更新用户 " + needDoUpdateList.size() + "";
}
/**
* 构建变更的历史数据
*
@@ -247,9 +375,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
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(""));
String changeInfos = changeList.stream().map(v -> v.getString("name") + "" + HtmlUtil.cleanHtmlTag(v.getString("value")) + "—>" + HtmlUtil.cleanHtmlTag(v.getString("newValue"))).collect(Collectors.joining(""));
// 比较变更数据
commonCompareChange(source, user, changeTypes);
@@ -269,15 +395,6 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
*/
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());
@@ -290,109 +407,4 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
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 {
if (isUserMember && !isEligibleForMember) {
removeMemberUserIds.add(user.getId());
source.setMember(false);
} else if (!isUserMember && isEligibleForMember) {
addMemberUserIds.add(user.getId());
source.setMember(true);
}
}
}
}
/**
* 数据大批量更新
*
* @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 null;
});
}
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();
}
}
}
}
@@ -25,10 +25,105 @@ import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
* 量更新系统用户数据
* 量更新系统用户数据
*/
@IocBean
public class SysDataUserIncrUpdateServiceImpl implements SysDataUserUpdateService {
/**
* 构建条件SQL
* @param group 条件组
* @return SQL条件字符串
*/
private String buildConditionSql(SysDataUserUpdateParam.ConditionGroup group) {
if (group == null) {
return "";
}
StringBuilder sql = new StringBuilder();
// 处理条件列表
if (group.getConditions() != null && !group.getConditions().isEmpty()) {
for (int i = 0; i < group.getConditions().size(); i++) {
SysDataUserUpdateParam.Condition condition = group.getConditions().get(i);
if (i > 0) {
sql.append(" ").append(group.getLogic()).append(" ");
}
sql.append(buildSingleConditionSql(condition));
}
}
// 处理嵌套条件组
if (group.getGroups() != null && !group.getGroups().isEmpty()) {
if (sql.length() > 0 && !group.getGroups().isEmpty()) {
sql.append(" ").append(group.getLogic()).append(" ");
}
for (int i = 0; i < group.getGroups().size(); i++) {
if (i > 0) {
sql.append(" ").append(group.getLogic()).append(" ");
}
sql.append("(").append(buildConditionSql(group.getGroups().get(i))).append(")");
}
}
return sql.toString();
}
/**
* 构建单个条件SQL
* @param condition 条件
* @return SQL条件字符串
*/
private String buildSingleConditionSql(SysDataUserUpdateParam.Condition condition) {
String field = condition.getField();
String operator = condition.getOperator();
Object value = condition.getValue();
StringBuilder sql = new StringBuilder();
sql.append(field);
switch (operator.toUpperCase()) {
case "=":
sql.append(" = '").append(value).append("'");
break;
case "!=":
sql.append(" != '").append(value).append("'");
break;
case ">":
sql.append(" > '").append(value).append("'");
break;
case "<":
sql.append(" < '").append(value).append("'");
break;
case ">=":
sql.append(" >= '").append(value).append("'");
break;
case "<=":
sql.append(" <= '").append(value).append("'");
break;
case "LIKE":
sql.append(" LIKE '%").append(value).append("%'");
break;
case "IN":
sql.append(" IN (").append(value).append(")");
break;
case "NOT IN":
sql.append(" NOT IN (").append(value).append(")");
break;
case "IS NULL":
sql.append(" IS NULL");
break;
case "IS NOT NULL":
sql.append(" IS NOT NULL");
break;
}
return sql.toString();
}
@Inject
private Dao dao;
@@ -37,13 +132,21 @@ public class SysDataUserIncrUpdateServiceImpl implements SysDataUserUpdateServic
@Override
public String update(SysDataUserUpdateParam updateParam) {
Sql sql = Sqls.create("""
StringBuilder sqlBuilder = new StringBuilder("""
SELECT * FROM sys_user_source s
WHERE
s.pullTime = @pullTime
AND s.loginname NOT IN (SELECT loginname FROM sys_user)
GROUP BY s.loginname
""");
// 处理复杂条件
if (updateParam.getConditionGroup() != null) {
sqlBuilder.append(" AND ").append(buildConditionSql(updateParam.getConditionGroup()));
}
sqlBuilder.append(" GROUP BY s.loginname");
Sql sql = Sqls.create(sqlBuilder.toString());
sql.setParam("pullTime", updateParam.getPullTime());
sql.setCallback(Sqls.callback.entities());
sql.setEntity(dao.getEntity(Sys_user_source.class));
@@ -12,6 +12,7 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.annotation.DataCenterColumn;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_source;
@@ -28,6 +29,7 @@ import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@@ -44,13 +46,58 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
super(dao);
}
/**
* 字段映射类,用于缓存反射结果
*/
private static class FieldMapping {
final Field field;
final String key;
FieldMapping(Field field, String key) {
this.field = field;
this.key = key;
field.setAccessible(true);
}
}
/**
* 字段映射缓存
*/
private static List<FieldMapping> fieldMappings;
/**
* 获取字段映射,使用懒加载模式
*/
private static List<FieldMapping> getFieldMappings() {
if (fieldMappings == null) {
synchronized (SysDataUserPullServiceImpl.class) {
if (fieldMappings == null) {
List<FieldMapping> mappings = new ArrayList<>();
Field[] fields = Sys_user.class.getDeclaredFields();
for (Field field : fields) {
DataCenterColumn annotation = field.getAnnotation(DataCenterColumn.class);
if (annotation != null) {
mappings.add(new FieldMapping(field, annotation.key()));
}
}
fieldMappings = mappings;
}
}
}
return fieldMappings;
}
@Override
public void pull() {
try {
// 博士后进站日期数据
Map<String, Date> doctoralData = pullPostDoctoral();
Date nowDate = new Date();
String appId = "1926887238437818370";
String secret = "32df31fcf4fc43f9a647ee1f47134f36";
List<Sys_user_source> latestSourceList = new ArrayList<>();
List<JSONObject> rawDataList = new ArrayList<>();
int skip = 0;
int totalCount = 0;
boolean firstRequest = true;
@@ -68,7 +115,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
reqBody.put("$count", true);
reqBody.put("$skip", skip);
reqBody.put("$top", 1000);
reqBody.put("$filter", "yrfsmc eq '事业编制' or yrfsmc eq '校聘合同制' or yrfsmc eq '新人事代理' or yrfsmc eq '博士后' or yrfsmc eq '劳动合同'");
// reqBody.put("$filter", "yrfsmc eq '事业编制' or yrfsmc eq '校聘合同制' or yrfsmc eq '新人事代理' or yrfsmc eq '博士后' or yrfsmc eq '劳动合同'");
httpRequest.body(JSONUtil.toJsonStr(reqBody));
String resBody = httpRequest.execute().body();
@@ -83,76 +130,63 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
JSONArray value = entries.getJSONArray("value");
if (!value.isEmpty()) {
List<Sys_user_source> list = value.stream().map(v -> {
JSONObject jsonObject = (JSONObject) v;
Sys_user_source sysUser = new Sys_user_source();
sysUser.setLoginname(jsonObject.getStr("zgh"));
sysUser.setUsername(jsonObject.getStr("xm"));
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"));
sysUser.setNation(jsonObject.getStr("mzmc"));
sysUser.setIdCardType(jsonObject.getStr("sfzjlxmc"));
sysUser.setIdCard(jsonObject.getStr("sfzjh"));
sysUser.setPolitical(jsonObject.getStr("zzmmmc"));
sysUser.setUnitName(jsonObject.getStr("dwmc"));
sysUser.setUnitId(jsonObject.getStr("dwdm"));
sysUser.setUserState(jsonObject.getStr("jzgdqztmc"));
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.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.getStr("lxny"));
sysUser.setRetireDate(jsonObject.getDate("yjtxrq"));
sysUser.setIdentityType(jsonObject.getStr("grsfmc"));
sysUser.setPullTime(nowDate);
return sysUser;
}).toList();
latestSourceList.addAll(list);
skip += list.size();
// 先收集所有原始数据
List<JSONObject> currentBatch = value.stream().map(v -> (JSONObject) v).toList();
rawDataList.addAll(currentBatch);
skip += currentBatch.size();
log.info("数据拉取进度: {}/{}", rawDataList.size(), totalCount);
} else {
log.warn("当前批次未获取到数据,skip={}", skip);
break;
}
} while (skip < totalCount);
// 博士后进站日期数据
Map<String, Date> doctoralData = pullPostDoctoral();
// 赋值
List<Sys_user_source> latestSourceList = rawDataList.stream().map(raw -> {
Sys_user_source sysUser = new Sys_user_source();
// 设置博士后的进站日期
for (Sys_user_source sysUserSource : latestSourceList) {
if (doctoralData.containsKey(sysUserSource.getLoginname())) {
sysUserSource.setPostDoctoralJoinDate(doctoralData.get(sysUserSource.getLoginname()));
// 使用缓存的字段映射
for (FieldMapping mapping : getFieldMappings()) {
try {
// 根据字段类型设置值
if (mapping.field.getType() == String.class) {
// 特殊处理性别字段
if (mapping.field.getName().equals("sex")) {
String xbmc = raw.getStr(mapping.key);
mapping.field.set(sysUser, StrUtil.equals("男性", xbmc) ? "" : StrUtil.equals("女性", xbmc) ? "" : null);
} else {
mapping.field.set(sysUser, raw.getStr(mapping.key));
}
} else if (mapping.field.getType() == Date.class) {
mapping.field.set(sysUser, raw.getDate(mapping.key));
}
} catch (IllegalAccessException e) {
log.error("设置字段值失败: {}", mapping.field.getName(), e);
}
}
}
// 设置博士后的进站日期
if (doctoralData.containsKey(sysUser.getLoginname())) {
sysUser.setPostDoctoralJoinDate(doctoralData.get(sysUser.getLoginname()));
}
// 设置单位相关信息
sysUser.setUnitName(raw.getStr("dwmc"));
sysUser.setUnitId(raw.getStr("dwdm"));
sysUser.setPullTime(nowDate);
return sysUser;
}).toList();
log.info("--------------------");
// 插入到数据库
dao().insert(latestSourceList);
//异步插入数据
// List<List<Sys_user_source>> splitLatestSourceList = ListUtil.split(latestSourceList, 500);
// for (List<Sys_user_source> sysUserSources : splitLatestSourceList) {
// threadPoolTaskExecutor.execute(() -> {
// dao().insert(sysUserSources);
// });
// }
} catch (Exception e) {
throw new BaseException("数据拉取失败,{}", e.getMessage());
}
}
@Async
private void updateDict(List<Sys_user_source> userSources){
private void updateDict(List<Sys_user_source> userSources) {
//判断是否要更新在职状态字典
List<String> sourceUserStates = userSources.stream().map(Sys_user::getUserState).filter(StrUtil::isNotBlank).distinct().toList();
//判断是否要更新学历字典
@@ -46,6 +46,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -76,6 +77,9 @@ public class WelfareListController {
@SaCheckPermission("welfare.list.mange")
@Ok("json:{dateFormat:'yyyy-MM-dd'}")
public Result pageData(@Valid @Param("pageForm") WelfareListPageForm pageForm) {
if (StrUtil.isBlank(pageForm.getProjectId())) {
return Result.success(new Pagination<>(1, 10, 0, Collections.emptyList()));
}
Pagination pagination = welfareListService.pageData(pageForm);
return Result.success(pagination);
}
@@ -108,6 +112,15 @@ public class WelfareListController {
return Result.success();
}
@At
@SaCheckPermission("welfare.list.mange")
@ApiOperation("导出")
@Ok("void")
public void exportXlsx(@Param("pageForm") WelfareListPageForm pageForm, HttpServletResponse response) {
welfareListService.exportXlsx(pageForm, response);
}
@At
@SaCheckPermission("welfare.list.mange")
@ApiOperation("编辑备注")
@@ -53,58 +53,12 @@ public class WelfareSelectionSituationController {
@At
@SaCheckPermission("welfare.selection.situation")
@ApiOperation("分页查询")
@Ok("json:{dateFormat:'yyyy-MM-dd'}")
public Result pageData(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm) {
if (StrUtil.isBlank(pageForm.getProjectId())) {
return Result.success(new Pagination<>(1, 10, 0, Collections.emptyList()));
}
Sql sql = Sqls.create("""
SELECT
t1.id,
t1.welfareUnionName,
t1.welfareUnitName,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex
FROM
welfare_list t1
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId AND t2.selectUserId = t1.userId
LEFT JOIN welfare_project_subject_option t3 ON t3.id = t2.selectOptionId
LEFT JOIN sys_user t4 ON t4.id = t1.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", pageForm.getProjectId());
if (StrUtil.isNotBlank(pageForm.getUserName())) {
cnd.where().andLike("t4.username", pageForm.getUserName());
}
if (StrUtil.isNotBlank(pageForm.getLoginName())) {
cnd.where().andLike("t4.loginname", pageForm.getLoginName());
}
cnd.andEX("t1.welfareUnitId", "in", pageForm.getUnitIds());
cnd.andEX("t1.welfareUnionId", "=", pageForm.getUnionId());
if (pageForm.getIsSelect() != null) {
if (pageForm.getIsSelect()) {
cnd.and("t2.id", "IS NOT", null);
} else {
cnd.and("t2.id", "IS", null);
}
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("welfareUnionName");
cnd.asc("welfareUnitName");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t1.id");
sql.setCondition(cnd);
Pagination pagination = welfareListService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
Pagination pagination = situationService.pageData(pageForm);
return Result.success(pagination);
}
@@ -15,6 +15,9 @@ public class WelfareSelectionSituationPageForm extends PageForm {
@ApiModelProperty("福利项目id")
private String projectId;
@ApiModelProperty("福利选项id")
private String welfareOptionId;
@ApiModelProperty("姓名")
private String userName;
@@ -45,4 +45,11 @@ public interface WelfareListService extends BaseService<WelfareList> {
* @param pageForm
*/
void addWelfareUser(WelfareFilterUserPageForm pageForm);
/**
* 导出
* @param pageForm
* @param response
*/
void exportXlsx(WelfareListPageForm pageForm, HttpServletResponse response);
}
@@ -1,5 +1,6 @@
package com.budwk.app.zhgh.welfare.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
@@ -8,6 +9,8 @@ import javax.servlet.http.HttpServletResponse;
public interface WelfareSelectionSituationService extends BaseService<WelfareList> {
Pagination pageData(WelfareSelectionSituationPageForm pageForm);
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
}
@@ -395,7 +395,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId","=",pageForm.getProjectId());
cnd.and("t1.projectId", "=", pageForm.getProjectId());
if (StrUtil.isNotBlank(pageForm.getUserName())) {
cnd.where().andLike("t2.username", pageForm.getUserName());
}
@@ -412,7 +412,12 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
cnd.andEX("t1.personType", "in", pageForm.getPersonTypes());
cnd.andEX("t1.preparedBy", "in", pageForm.getPreparedBys());
cnd.andEX("t1.userState", "in", pageForm.getUserStates());
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("t1.welfareUnionName");
cnd.asc("t1.welfareUnitName");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return pagination;
@@ -543,4 +548,70 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
log.info("选择用户生成福利名单,筛选条件:{},筛选结果条数:{}", Json.toJson(pageForm), welfareList.size());
dao().insert(welfareList);
}
@Override
public void exportXlsx(WelfareListPageForm pageForm, HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
t1.*,
t2.loginname,
t2.username,
t2.sex,
DATE_FORMAT(t2.birthday, '%Y-%m-%d') AS birthday
FROM
`welfare_list` t1
LEFT JOIN sys_user t2 ON t2.id = t1.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", pageForm.getProjectId());
if (StrUtil.isNotBlank(pageForm.getUserName())) {
cnd.where().andLike("t2.username", pageForm.getUserName());
}
if (StrUtil.isNotBlank(pageForm.getLoginName())) {
cnd.where().andLike("t2.loginname", pageForm.getLoginName());
}
cnd.andEX("t2.sex", "=", pageForm.getSex());
cnd.andEX("t2.birthday", "=", pageForm.getBirthday());
if (pageForm.getBirthMonths() != null && pageForm.getBirthMonths().length > 0) {
cnd.andEX("MONTH(t2.birthday)", "in", pageForm.getBirthMonths());
}
cnd.andEX("t1.welfareUnitId", "in", pageForm.getUnitIds());
cnd.andEX("t1.welfareUnionId", "=", pageForm.getUnionId());
cnd.andEX("t1.personType", "in", pageForm.getPersonTypes());
cnd.andEX("t1.preparedBy", "in", pageForm.getPreparedBys());
cnd.andEX("t1.userState", "in", pageForm.getUserStates());
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("t1.welfareUnionName");
cnd.asc("t1.welfareUnitName");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
List<NutMap> list = listMap(sql);
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginname", 20));
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("性别", "sex", 20));
entities.add(new ExcelExportEntity("出生日期", "birthday", 20));
entities.add(new ExcelExportEntity("人员类型", "personType", 20));
entities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
entities.add(new ExcelExportEntity("在职状态", "userState", 20));
entities.add(new ExcelExportEntity("所属工会", "welfareUnionName", 20));
entities.add(new ExcelExportEntity("所属单位", "welfareUnitName", 20));
entities.add(new ExcelExportEntity("备注", "remark", 20));
// 设置导出参数
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
// 导出Excel并下载
try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list)) {
CommonDownloadUtil.download("福利名单.xlsx", workbook, response);
} catch (Exception e) {
log.error("导出Excel失败", e);
}
}
}
@@ -87,13 +87,10 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
@Override
@Aop(TransAop.READ_COMMITTED)
public void deleteWelfare(String id) {
WelfareProjectSubject welfareProjectSubject = dao().fetch(WelfareProjectSubject.class, Cnd.where("projectId", "=", id));
dao().clear(WelfareProjectSubject.class, Cnd.where("projectId", "=", id));
dao().clear(WelfareProjectSubjectOption.class, Cnd.where("subjectId", "=", welfareProjectSubject.getId()));
dao().clear(WelfareUserSelection.class, Cnd.where("welfareId", "=", id));
dao().clear(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", id));
dao().clear(WelfareUserSelection.class, Cnd.where(WelfareUserSelection::getWelfareId, "=", id));
dao().clear(WelfareList.class, Cnd.where(WelfareList::getProjectId, "=", id));
delete(id);
dao().clear(WelfareList.class, Cnd.where("projectId", "=", id));
//删除首页活动
dao().clear(Sys_home_activity.class, Cnd.where("id", "=", id));
}
@@ -5,6 +5,8 @@ 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.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
@@ -31,6 +33,59 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
super(dao);
}
@Override
public Pagination pageData(WelfareSelectionSituationPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
t1.id,
t1.welfareUnionName,
t1.welfareUnitName,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex,
t4.birthday
FROM
welfare_list t1
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId AND t2.selectUserId = t1.userId
LEFT JOIN welfare_project_subject_option t3 ON t3.id = t2.selectOptionId
LEFT JOIN sys_user t4 ON t4.id = t1.userId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", pageForm.getProjectId());
cnd.andEX("t2.selectOptionId", "=", pageForm.getWelfareOptionId());
if (StrUtil.isNotBlank(pageForm.getUserName())) {
cnd.where().andLike("t4.username", pageForm.getUserName());
}
if (StrUtil.isNotBlank(pageForm.getLoginName())) {
cnd.where().andLike("t4.loginname", pageForm.getLoginName());
}
cnd.andEX("t1.welfareUnitId", "in", pageForm.getUnitIds());
cnd.andEX("t1.welfareUnionId", "=", pageForm.getUnionId());
if (pageForm.getIsSelect() != null) {
if (pageForm.getIsSelect()) {
cnd.and("t2.id", "IS NOT", null);
} else {
cnd.and("t2.id", "IS", null);
}
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("welfareUnionName");
cnd.asc("welfareUnitName");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t1.id");
sql.setCondition(cnd);
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
Sql sql = Sqls.create("""
@@ -52,6 +107,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
""");
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", pageForm.getProjectId());
cnd.andEX("t2.selectOptionId", "=", pageForm.getWelfareOptionId());
if (StrUtil.isNotBlank(pageForm.getUserName())) {
cnd.where().andLike("t4.username", pageForm.getUserName());
@@ -7,10 +7,9 @@ layout("/layouts/platform.html"){
width: 100%;
margin-bottom: 10px;
}
.pullTimeRadioGroup .el-radio.is-bordered + .el-radio.is-bordered{
.pullTimeRadioGroup .el-radio.is-bordered + .el-radio.is-bordered {
margin-left: 0;
}
</style>
<div id="app" v-cloak>
@@ -52,10 +51,10 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :label="pageForm.pullTime ? pageForm.pullTime + '数据' : '全部数据'">
<el-button type="primary" size="mini" @click="pull" icon="el-icon-download">拉取信息中心数据</el-button>
<el-button type="primary" size="mini" :loading="pullLoading" @click="pull" icon="el-icon-download">拉取信息中心数据</el-button>
<el-button type="danger" size="mini" @click="openDelete" icon="el-icon-delete">删除本地数据源</el-button>
</table-tool>
<el-table :key="tableKey" :data="tableData" @sort-change="pageOrder" header-align="center">
<el-table :key="tableKey" :data="tableData" @sort-change="pageOrder" header-align="center" v-loading="tableLoading">
<el-table-column type="index" width="70" label="序号" fixed="left"></el-table-column>
<el-table-column prop="pullTime" label="拉取时间" width="170" fixed="left"></el-table-column>
<el-table-column prop="loginname" label="工号" width="100" fixed="left"></el-table-column>
@@ -103,11 +102,12 @@ layout("/layouts/platform.html"){
return {
unitNameOptions: [],
userStateOptions: [],
preparedByOptions:[],
personTypeOptions: [],
preparedByOptions: [],
personTypeOptions: [],
pullTimeOptions: false,
sourceTime: null,
pullTimeDialogVisible: false
pullTimeDialogVisible: false,
pullLoading: false
}
},
methods: {
@@ -118,12 +118,18 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消"
})
.then(() => {
this.$axios.post("/platform/sys/data/user/pull/pullData").then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
}
})
this.pullLoading = true
this.$axios
.post("/platform/sys/data/user/pull/pullData")
.then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
}
})
.finally(() => {
this.pullLoading = false
})
})
.catch(() => {})
},
@@ -7,9 +7,37 @@ layout("/layouts/platform.html"){
width: 100%;
margin-bottom: 10px;
}
.pullTimeRadioGroup .el-radio.is-bordered + .el-radio.is-bordered{
.pullTimeRadioGroup .el-radio.is-bordered + .el-radio.is-bordered {
margin-left: 0;
}
.condition-builder {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
margin-bottom: 10px;
}
.condition-group {
border-left: 2px solid #409eff;
padding-left: 10px;
margin-bottom: 10px;
}
.condition-row {
margin-bottom: 10px;
display: flex;
align-items: center;
}
.condition-row .el-select {
margin-right: 10px;
}
.condition-actions {
margin-top: 10px;
}
</style>
<div id="app" v-cloak>
@@ -50,8 +78,8 @@ layout("/layouts/platform.html"){
<el-table-column prop="username" label="姓名" fixed="left" width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="changeTypes" label="变更类型" width="140">
<template slot-scope="{row}">
<span style="color: #0e78c5;cursor: pointer" @click="openCurrentUserChangeInfo(row)">
{{getChangeTypes(row.changeTypes)}}
<span style="color: #0e78c5; cursor: pointer" @click="openCurrentUserChangeInfo(row)">
{{getChangeTypes(row.changeTypes)}}
</span>
</template>
</el-table-column>
@@ -75,12 +103,8 @@ layout("/layouts/platform.html"){
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
<template #view>
<member-audit-change-info ref="memberAuditChangeInfoRef" is_default_url></member-audit-change-info>
</template>
</guava>
<el-dialog title="选择数据源" :visible.sync="updateDialog" width="50%">
<el-dialog title="选择数据源" :visible.sync="updateDialog" width="70%">
<el-timeline>
<el-timeline-item timestamp="数据源" placement="top">
<el-radio-group v-model="updateFromData.pullTime" style="width: 100%" class="pullTimeRadioGroup">
@@ -101,6 +125,20 @@ layout("/layouts/platform.html"){
</el-row>
</el-radio-group>
</el-timeline-item>
<el-timeline-item timestamp="高级条件筛选" placement="top">
<el-switch v-model="enableAdvancedConditions" active-text="启用高级条件"></el-switch>
<div v-if="enableAdvancedConditions" class="condition-builder">
<!-- 条件构建器组件 -->
<condition-group
:group="updateFromData.conditionGroup"
:field-options="fieldOptions"
:operator-options="operatorOptions"
@remove="removeRootGroup"
></condition-group>
</div>
</el-timeline-item>
</el-timeline>
<span slot="footer" class="dialog-footer" v-loading="updateLoading">
<el-button @click="updateDialog = false" :disabled="updateLoading">取 消</el-button>
@@ -109,8 +147,110 @@ layout("/layouts/platform.html"){
</el-dialog>
</div>
<!-- 条件组组件模板 -->
<script type="text/x-template" id="condition-group-template">
<div class="condition-group">
<div class="condition-row">
<el-select v-model="group.logic" size="small" style="width: 80px">
<el-option label="AND" value="AND"></el-option>
<el-option label="OR" value="OR"></el-option>
</el-select>
<el-button type="danger" size="mini" icon="el-icon-delete" @click="$emit('remove')"
v-if="canRemove"></el-button>
</div>
<!-- 条件列表 -->
<div v-for="(condition, index) in group.conditions" :key="'c-'+index" class="condition-row">
<el-select v-model="condition.field" placeholder="字段" size="small" style="width: 120px">
<el-option v-for="field in fieldOptions" :key="field.value" :label="field.label"
:value="field.value"></el-option>
</el-select>
<el-select v-model="condition.operator" placeholder="操作符" size="small" style="width: 100px">
<el-option v-for="op in operatorOptions" :key="op.value" :label="op.label"
:value="op.value"></el-option>
</el-select>
<el-input v-if="!isNullOperator(condition.operator)" v-model="condition.value" placeholder="值" size="small"
style="width: 150px"></el-input>
<el-button type="danger" size="mini" icon="el-icon-delete" @click="removeCondition(index)"></el-button>
</div>
<!-- 嵌套条件组 -->
<div v-for="(nestedGroup, index) in group.groups" :key="'g-'+index">
<condition-group
:group="nestedGroup"
:field-options="fieldOptions"
:operator-options="operatorOptions"
:can-remove="true"
@remove="removeGroup(index)">
</condition-group>
</div>
<!-- 操作按钮 -->
<div class="condition-actions">
<el-button type="primary" size="mini" @click="addCondition">添加条件</el-button>
<el-button type="success" size="mini" @click="addGroup">添加条件组</el-button>
</div>
</div>
</script>
<script>
<!--#include("../../../zhgh/staffmanage/member/common/audit/memberAuditChangeInfo.js"){}#-->
// 条件组组件
Vue.component("condition-group", {
template: "#condition-group-template",
props: {
group: {
type: Object,
required: true
},
fieldOptions: {
type: Array,
required: true
},
operatorOptions: {
type: Array,
required: true
},
canRemove: {
type: Boolean,
default: false
}
},
methods: {
addCondition() {
if (!this.group.conditions) {
this.$set(this.group, "conditions", [])
}
this.group.conditions.push({
field: "",
operator: "=",
value: ""
})
},
removeCondition(index) {
this.group.conditions.splice(index, 1)
},
addGroup() {
if (!this.group.groups) {
this.$set(this.group, "groups", [])
}
this.group.groups.push({
logic: "AND",
conditions: [],
groups: []
})
},
removeGroup(index) {
this.group.groups.splice(index, 1)
},
isNullOperator(operator) {
return operator === "IS NULL" || operator === "IS NOT NULL"
}
}
})
new Vue({
el: "#app",
dicts: ["MEMBER_CHANGE_TYPE"],
@@ -121,20 +261,51 @@ layout("/layouts/platform.html"){
pullTimeOptions: false,
updateFromData: {
pullTime: null,
updateMode: "all"
updateMode: "ALL",
conditionGroup: {
logic: "AND",
conditions: [],
groups: []
}
},
updateLoading: false,
unitOptions: [],
changeTypeData: [],
enableAdvancedConditions: false,
// 可选字段列表
fieldOptions: [
{ label: "姓名", value: "username" },
{ label: "工号", value: "loginname" },
{ label: "性别", value: "sex" },
{ label: "生日", value: "birthday" },
{ label: "手机号", value: "mobile" },
{ label: "在职状态", value: "userState" },
{ label: "人事编制", value: "preparedBy" },
{ label: "人员类型", value: "personType" },
{ label: "来校年月", value: "arrivalAtSchoolDate" },
{ label: "单位", value: "unitName" },
{ label: "单位编码", value: "unitId" },
{ label: "学历", value: "education" },
{ label: "学位", value: "academicDegree" }
],
// 操作符列表
operatorOptions: [
{ label: "等于", value: "=" },
{ label: "不等于", value: "!=" },
{ label: "大于", value: ">" },
{ label: "小于", value: "<" },
{ label: "大于等于", value: ">=" },
{ label: "小于等于", value: "<=" },
{ label: "包含", value: "LIKE" },
{ label: "为空", value: "IS NULL" },
{ label: "不为空", value: "IS NOT NULL" }
]
}
},
components: {
'member-audit-change-info':MEMBER_AUDIT_CHANGE_INFO
},
methods: {
openCurrentUserChangeInfo(row) {
this.$refs.guava.view(() => {
this.$refs.memberAuditChangeInfoRef.onOpen({userId: row.id, recordId:row.userHistoryId})
this.$refs.memberAuditChangeInfoRef.onOpen({ userId: row.id, recordId: row.userHistoryId })
})
},
getChangeTypes(changeTypes) {
@@ -153,9 +324,15 @@ layout("/layouts/platform.html"){
this.updateLoading = false
this.$nextTick(() => {
this.updateFromData = {
updateMode: null,
pullTime: null
updateMode: "ALL",
pullTime: null,
conditionGroup: {
logic: "AND",
conditions: [],
groups: []
}
}
this.enableAdvancedConditions = false
})
},
getPullTimeOptions() {
@@ -175,6 +352,11 @@ layout("/layouts/platform.html"){
return
}
// 如果未启用高级条件,则移除条件组
if (!this.enableAdvancedConditions) {
this.updateFromData.conditionGroup = null
}
this.$confirm("确定要更新数据吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
@@ -182,12 +364,14 @@ layout("/layouts/platform.html"){
})
.then(() => {
this.updateLoading = true
this.$axios.post("/platform/sys/data/user/update/updateUserFormSource", this.updateFromData).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.updateDialog = false
}
})
this.$axios
.post("/platform/sys/data/user/update/updateUserFormSource", { param: JSON.stringify(this.updateFromData) })
.then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.updateDialog = false
}
})
})
.finally(() => {
this.updateLoading = false
@@ -197,13 +381,21 @@ layout("/layouts/platform.html"){
this.$businessTool.listUnit(this.pageForm.unionId).then((res) => {
this.unitOptions = res
})
},
removeRootGroup() {
// 重置根条件组
this.updateFromData.conditionGroup = {
logic: "AND",
conditions: [],
groups: []
}
}
},
created() {
this.listUnit()
this.getPullTimeOptions()
this.pageData()
this.$businessTool.getAllDictOptions("MEMBER_CHANGE_TYPE").then(data => {
this.$businessTool.getAllDictOptions("MEMBER_CHANGE_TYPE").then((data) => {
this.changeTypeData = data
})
}
@@ -142,7 +142,7 @@ const filterUser = {
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit">确认添加到福利名单</el-button>
<el-button type="primary" @click="onSubmit" :loading="submitLoading">确认添加到福利名单</el-button>
</template>
</el-dialog>
@@ -152,6 +152,7 @@ const filterUser = {
return {
visible: false,
projectId: null,
submitLoading: false,
pageForm: {
birthMonths: [],
userStates: [],
@@ -223,16 +224,21 @@ const filterUser = {
cancelButtonText: "取消",
type: "warning"
}).then(async () => {
const { code, data, msg } = await this.$axios.post("/platform/welfare/project/mange/addWelfareUser", {
pageForm: JSON.stringify(this.pageForm),
projectId: this.projectId
})
if (code === 0) {
this.$message.success(msg)
this.visible = false
this.$emit("refresh")
} else {
this.$message.error(msg)
this.submitLoading = true;
try {
const { code, data, msg } = await this.$axios.post("/platform/welfare/project/mange/addWelfareUser", {
pageForm: JSON.stringify(this.pageForm),
projectId: this.projectId
})
if (code === 0) {
this.$message.success(msg)
this.visible = false
this.$emit("refresh")
} else {
this.$message.error(msg)
}
} finally {
this.submitLoading = false;
}
})
}
@@ -20,7 +20,13 @@ layout("/layouts/platform.html"){
<search-item label="福利项目">
<el-select :clearable="false" filterable placeholder="请选择福利项目" style="width: 100%" v-model="pageForm.projectId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in projectSelectOptions"></el-option>
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in projectOptions"></el-option>
</el-select>
</search-item>
<search-item label="福利选项">
<el-select clearable filterable placeholder="请选择福利选项" style="width: 100%" v-model="pageForm.welfareOptionId">
<el-option :key="item.id" :label="item.optionName" :value="item.id" v-for="item in welfareOptions"></el-option>
</el-select>
</search-item>
@@ -113,11 +119,12 @@ layout("/layouts/platform.html"){
},
unionOptions: [],
unitOptions: [],
projectSelectOptions: [],
projectOptions: [],
tableColumns: [
{ prop: "loginName", label: "工号" },
{ prop: "userName", label: "姓名" },
{ prop: "sex", label: "性别", sortable: true, checked: 0 },
{ prop: "birthday", label: "出生日期", sortable: true, checked: 0 },
{ prop: "welfareUnionName", label: "所属工会", sortable: true },
{ prop: "welfareUnitName", label: "所属单位", sortable: true },
{ prop: "selectedOptions", label: "所选福利", sortable: true },
@@ -125,10 +132,18 @@ layout("/layouts/platform.html"){
]
}
},
computed: {
welfareOptions() {
if (this.pageForm.projectId) {
return this.projectOptions.find((item) => item.id === this.pageForm.projectId).options
}
return []
}
},
methods: {
getWelfareList() {
this.$axios.post("/platform/welfare/common/list", { year: this.pageForm.year }).then((res) => {
this.projectSelectOptions = res.data
this.projectOptions = res.data
if (res.data && res.data.length > 0) {
this.$set(this.pageForm, "projectId", res.data[0].id)
} else {
@@ -25,7 +25,7 @@ layout("/layouts/platform.html"){
</search-item>
<search-item label="所属工会">
<el-select :clearable="clearable" clearable filterable placeholder="所属工会" style="width: 100%" v-model="pageForm.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unions"></el-option>
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unionOptions"></el-option>
</el-select>
</search-item>
</search>
@@ -93,47 +93,16 @@ layout("/layouts/platform.html"){
},
data() {
return {
unions: [],
pageForm: {
searchName: "username",
year: new Date().getFullYear().toString()
},
unionOptions: [],
welfareProjectList: [],
welfareOptions: [],
projectInfo: {},
clearable: false,
tableColumns: [],
receive_tableColumns: [
{ label: "工号", prop: "loginName" },
{ label: "姓名", prop: "userName" },
{ label: "单位", prop: "unitName" },
{ label: "所选福利", prop: "optionName" }
],
receiveTableData: [],
receivePageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: ""
},
unclaimedDialog: false,
unclaimedTableData: [],
unclaimedPageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "",
pageOrderBy: ""
},
unclaimed_tableColumns: [
{ label: "姓名", prop: "userName" },
{ label: "工号", prop: "loginName" },
{ label: "单位", prop: "unitName" },
{ label: "工会", prop: "unionName" }
]
tableColumns: []
}
},
methods: {
@@ -171,15 +140,14 @@ layout("/layouts/platform.html"){
this.tableLoading = false
},
async getWelfareProjectList() {
const resp = await this.$axios.post("/platform/welfare/project/mange/getWelfareList", { year: this.pageForm.year })
this.welfareProjectList = resp.data
if (this.welfareProjectList && this.welfareProjectList.length > 0) {
this.$set(this.pageForm, "projectId", this.welfareProjectList[0].id)
this.getWelfareOptions()
const res = await this.$axios.post("/platform/welfare/project/mange/getWelfareList", { year: this.pageForm.year })
this.welfareProjectList = res.data
if (res.data && res.data.length > 0) {
this.$set(this.pageForm, "projectId", res.data[0].id)
} else {
this.tableData = []
this.tableColumns = []
this.$set(this.pageForm, "projectId", null)
}
this.doSearch()
},
getWelfareOptions() {
const data = this.welfareProjectList.find((p) => p.id === this.pageForm.projectId)
@@ -191,14 +159,13 @@ layout("/layouts/platform.html"){
!this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN", "SCHOOL_UNION_WELFARE_ADMIN"]) &&
this.$auth.hasRoleOr(["BRANCH_UNION_CHAIRMAN"])
) {
this.unions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
this.unionOptions = await this.$businessTool.listUnion(this.$store.state.user.union.id)
this.$set(this.pageForm, "unionId", this.unions[0].id)
this.clearable = true
} else {
this.unions = await this.$businessTool.listUnion()
this.unionOptions = await this.$businessTool.listUnion()
this.clearable = true
}
this.pageForm.year = new Date().getFullYear().toString()
await this.getWelfareProjectList()
await this.pageData()
}
@@ -15,6 +15,7 @@ layout("/layouts/platform.html"){
type="year"
v-model="pageForm.year"
value-format="yyyy"
@change="getWelfareList"
></el-date-picker>
</search-item>
@@ -117,6 +118,9 @@ layout("/layouts/platform.html"){
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="福利名单">
<el-button :disabled="!pageForm.projectId" @click="openExport" icon="el-icon-download" size="small" type="primary">
导出名单
</el-button>
<el-button :disabled="!pageForm.projectId" @click="openImport" icon="el-icon-document-add" size="small" type="primary">
导入名单
</el-button>
@@ -251,10 +255,13 @@ layout("/layouts/platform.html"){
}
},
methods: {
openWelfareListUser() {
this.$refs.addWelfareListUser.welfareListUserDrawer = true
this.$refs.addWelfareListUser.selectNotWelfareList(this.pageForm.projectId)
// 导出名单
openExport() {
this.$downLoad("/platform/welfare/list/mange/exportXlsx", {
pageForm: JSON.stringify(this.pageForm)
})
},
successImport() {
this.doSearch()
this.importDialog = false
@@ -286,7 +293,10 @@ layout("/layouts/platform.html"){
this.projectSelectOptions = res.data
if (res.data && res.data.length > 0) {
this.$set(this.pageForm, "projectId", res.data[0].id)
} else {
this.$set(this.pageForm, "projectId", null)
}
this.doSearch()
})
},
pageData() {
+11 -98
View File
@@ -14,6 +14,7 @@ import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.utils.PwdUtil;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.models.Sys_user;
@@ -94,104 +95,6 @@ public class JugTest {
dao.fastInsert(units);
}
@Test
public void t0002() {
String appId = "1926887238437818370";
String secret = "32df31fcf4fc43f9a647ee1f47134f36";
List<Sys_user_source> allUsers = new ArrayList<>();
int skip = 0;
int totalCount = 0;
boolean firstRequest = true;
do {
long ts = System.currentTimeMillis();
String sign = Base64.encode(DigestUtil.md5Hex(appId + secret + ts, CharsetUtil.CHARSET_UTF_8));
HttpRequest httpRequest = HttpUtil.createPost("https://sjzcpt.nnu.edu.cn/cdsp/data-api/v2/DS0026");
httpRequest.header("Content-Type", "application/json");
httpRequest.header("appId", appId);
httpRequest.header("timestamp", String.valueOf(ts));
httpRequest.header("sign", sign);
HashMap<String, Object> reqBody = new HashMap<>();
reqBody.put("$count", true);
reqBody.put("$skip", skip);
reqBody.put("$top", 1000);
httpRequest.body(JSONUtil.toJsonStr(reqBody));
String resBody = httpRequest.execute().body();
JSONObject entries = JSONUtil.parseObj(resBody);
if (firstRequest) {
totalCount = entries.getInt("@odata.count", 0);
firstRequest = false;
}
JSONArray value = entries.getJSONArray("value");
if (!value.isEmpty()) {
List<Sys_user_source> list = value.stream().map(v -> {
JSONObject jsonObject = (JSONObject) v;
Sys_user_source sysUser = new Sys_user_source();
sysUser.setLoginname(jsonObject.getStr("zgh"));
sysUser.setUsername(jsonObject.getStr("xm"));
sysUser.setSex(jsonObject.getStr("xbmc"));
sysUser.setBirthday(jsonObject.getDate("csrq"));
sysUser.setNativePlace(jsonObject.getStr("jgmc"));
sysUser.setNationality(jsonObject.getStr("gjdqmc"));
sysUser.setNation(jsonObject.getStr("mzmc"));
sysUser.setIdCardType(jsonObject.getStr("sfzjlxmc"));
sysUser.setIdCard(jsonObject.getStr("sfzjh"));
sysUser.setPolitical(jsonObject.getStr("zzmmmc"));
sysUser.setUnitName(jsonObject.getStr("dwmc"));
sysUser.setUnitId(jsonObject.getStr("dwdm"));
sysUser.setUserState(jsonObject.getStr("jzgdqztmc"));
sysUser.setEmploymentType(jsonObject.getStr("yrfsmc"));
sysUser.setEducation(jsonObject.getStr("zgxlmc"));
sysUser.setAcademicDegree(jsonObject.getStr("zgxwmc"));
sysUser.setMobile(jsonObject.getStr("sjh"));
sysUser.setStaffCategory(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.setRetireDate(jsonObject.getDate("yjtxrq"));
sysUser.setIdentityType(jsonObject.getStr("grsfmc"));
return sysUser;
}).toList();
allUsers.addAll(list);
skip += list.size();
} else {
break;
}
} while (skip < totalCount);
System.out.println(1);
// dao.insert(allUsers);
}
@Test
public void t003() {
String s = """
@@ -303,7 +206,17 @@ public class JugTest {
} while (skip < totalCount);
System.out.println(allUsers.size());
}
@Test
public void userPwd(){
List<Sys_user> users = dao.query(Sys_user.class, Cnd.NEW());
String pwd = "1";
for (Sys_user user : users) {
user.setSalt(R.UU32());
user.setPassword(PwdUtil.getPassword(pwd, user.getSalt()));
}
dao.update(users,"password|salt");
}
@@ -0,0 +1,186 @@
package com.budwk.app;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_source;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
import lombok.Data;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nutz.boot.test.junit4.NbJUnit4Runner;
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.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@IocBean
@RunWith(NbJUnit4Runner.class)
public class WelfareTest {
@Inject
private Dao dao;
@Inject
private WelfareProjectService welfareService;
@Test
public void importSelectUser() {
List<SelectUser> list = ExcelImportUtil.importExcel(new File("C:\\Users\\jug\\Desktop\\新建文件夹 (2)\\蛋糕汇总表.xlsx"), SelectUser.class, new ImportParams());
// 福利id
String welfareId = "6b6b438811044d7180b76facaebbe2f3";
// 福利名单
Sql sql = Sqls.create("""
SELECT
u.id,
u.username AS userName,
u.loginname AS loginName,
u.mobile
FROM
`welfare_list` t1
LEFT JOIN sys_user u ON u.id = t1.userId
WHERE
t1.projectId = @projectId
group by u.loginname
""");
sql.setParam("projectId", welfareId);
List<NutMap> welfareLists = welfareService.listMap(sql);
List<String> loginNames = welfareLists.stream().map(v -> v.getString("loginName")).toList();
Map<String, NutMap> loginNameMap = welfareLists.stream().collect(Collectors.toMap(v -> v.getString("loginName"), v -> v));
// 筛选出本次导入的
List<SelectUser> thisList = list.stream().filter(v -> StrUtil.isNotBlank(v.getLoginName()) && loginNames.contains(v.getLoginName()))
.peek(v -> v.setLoginName(v.getLoginName().trim()))
.toList();
System.out.println(thisList.size());
// 福利选项
List<WelfareProjectSubjectOption> options = dao.query(WelfareProjectSubjectOption.class, Cnd.where(WelfareProjectSubjectOption::getWelfareId, "=", welfareId));
List<WelfareUserSelection> selections = thisList.stream().map(v -> {
WelfareUserSelection welfareUserSelection = new WelfareUserSelection();
welfareUserSelection.setSelectTime(new Date());
welfareUserSelection.setSelectUserId(loginNameMap.get(v.getLoginName()).getString("id"));
welfareUserSelection.setSelectNum(1);
if (StrUtil.isNotBlank(v.getMobile())) {
welfareUserSelection.setMobile(v.getMobile());
} else {
welfareUserSelection.setMobile(loginNameMap.get(v.getLoginName()).getString("mobile"));
}
welfareUserSelection.setWelfareId(welfareId);
String optionId = options.stream().filter(option -> option.getOptionName().equals(v.getOptionName())).findFirst().map(option -> option.getId()).orElse(null);
welfareUserSelection.setSelectOptionId(optionId);
return welfareUserSelection;
}).toList();
dao.insert(selections);
}
@Test
public void deleteUser() {
List<SelectUser> list = ExcelImportUtil.importExcel(new File("C:\\Users\\jug\\Desktop\\新建文件夹 (2)\\蛋糕汇总表.xlsx"), SelectUser.class, new ImportParams());
List<String> loginNames = list.stream().map(v -> v.getLoginName()).toList();
Sql sql = Sqls.create("select id from sys_user where loginname in (@loginname)");
sql.setParam("loginname", loginNames);
sql.setCallback(Sqls.callback.strList());
dao.execute(sql);
List<String> ids = sql.getList(String.class);
List<WelfareList> welfareLists = dao.query(WelfareList.class, Cnd.NEW());
List<String> welfareUserIds = welfareLists.stream().map(v -> v.getUserId()).toList();
List<String> list1 = welfareUserIds.stream().filter(v -> !ids.contains(v)).toList();
System.out.println(list1.size());
//dao.clear(WelfareList.class, Cnd.where("userId", "not in", ids.stream().map(v -> v.getString("id")).toList()));
}
@Data
public static class SelectUser {
@Excel(name = "工号")
private String loginName;
@Excel(name = "姓名")
private String userName;
@Excel(name = "手机号码")
private String mobile;
@Excel(name = "选择物品")
private String optionName;
@Excel(name = "出生日期", importFormat = "yyyy-MM-dd", exportFormat = "yyyy-MM-dd")
private Date birthday;
}
@Test
public void fixData() throws IOException {
List<Sys_user_source> users = dao.query(Sys_user_source.class, Cnd.NEW().groupBy(Sys_user::getLoginname));
Map<String, Date> userMap = users.stream().filter(v -> v.getBirthday() != null).collect(Collectors.toMap(v -> v.getLoginname(), v -> v.getBirthday()));
List<SelectUser> allList = ExcelImportUtil.importExcel(new File("C:\\Users\\jug\\Desktop\\南京师范蛋糕卡\\蛋糕汇总表2.xlsx"), SelectUser.class, new ImportParams());
for (SelectUser selectUser : allList) {
if (userMap.containsKey(selectUser.getLoginName())) {
selectUser.setBirthday(userMap.get(selectUser.getLoginName()));
}
}
Workbook workbook = ExcelExportUtil.exportExcel(
new ExportParams("修改后数据", "Sheet1"),
SelectUser.class,
allList
);
FileOutputStream fos = new FileOutputStream("C:\\Users\\jug\\Desktop\\南京师范蛋糕卡\\匹配上生日.xlsx");
workbook.write(fos);
fos.close();
workbook.close();
}
@Test
public void importUser() {
List<SelectUser> allList = ExcelImportUtil.importExcel(new File("C:\\Users\\jug\\Desktop\\南京师范蛋糕卡\\匹配上生日.xlsx"), SelectUser.class, new ImportParams());
List<SelectUser> list = allList.stream().filter(v -> StrUtil.isNotBlank(v.getLoginName())).toList();
// 福利id
String welfareId = "a93b1694e41f49f3b9e6364e36bf48cd";
// 找出月份等于1、2、3的
// list.stream().filter(v -> v.getBirthday().getMonth() + 1 <= 3).map(v -> {
// WelfareList welfareList = new WelfareList();
// welfareList.setProjectId(welfareId);
//
//
//
// })
}
}