代码优化

This commit is contained in:
Administrator 2026-01-02 18:57:27 +08:00
parent 7fd3b2462a
commit b50b21e6a0
25 changed files with 5484 additions and 371 deletions

View File

@ -0,0 +1,78 @@
package com.weaver.seconddev.jcl.organization.controller;
import com.weaver.common.authority.annotation.WeaPermission;
import com.weaver.seconddev.jcl.organization.entity.hldz.Person;
import com.weaver.seconddev.jcl.organization.service.AttendanceReportService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/secondev/jcl/attendanceReport")
public class AttendanceReportController {
private static final Logger log = LoggerFactory.getLogger(AttendanceReportController.class);
@Autowired
private AttendanceReportService attendanceReportService;
/**
* 二开测试接口
* @return
*/
@GetMapping("/test")
@WeaPermission(publicPermission = true)
public String secondTest(@RequestParam("name") String name){
log.error("secondTest.name:{}",name);
return name ;
}
/**
* 考勤报表展示
* @return
*/
@GetMapping("/getAttendanceReportInfo")
@WeaPermission(publicPermission = true)
public List<Person> saveQueryCondition(
@RequestParam("yearMonth") String yearMonth,
@RequestParam(value = "department", required = false) String department,
@RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "jobNum", required = false) String jobNum){
log.error("getAttendanceReportInfo.yearMonth:{},department:{},userName:{},jobNum:{}",yearMonth,department,userName,jobNum);
return attendanceReportService.getAttendanceReportInfo(yearMonth,department,userName,jobNum);
}
/**
* 报表数据存为EB表数据
* @return
*/
@GetMapping("/saveEBInfo")
@WeaPermission(publicPermission = true)
public Map<String,String> saveEBInfo(
@RequestParam("yearMonth") String yearMonth,
@RequestParam("department") String department,
@RequestParam("userName") String userName,
@RequestParam("jobNum") String jobNum){
log.error("saveEBInfo.yearMonth:{},department:{},userName:{},jobNum:{}",yearMonth,department,userName,jobNum);
return attendanceReportService.saveEBInfo(yearMonth,department,userName,jobNum);
}
@GetMapping("/getEmployeePreparationInfo")
@WeaPermission(publicPermission = true)
public Map<String, String> getEmployeePreparationInfo(
@RequestParam(name = "department", required = false) String department,
@RequestParam(name = "year", required = false) String year,
@RequestParam(name = "month", required = false) String month) {
log.error("getEmployeePreparationInfo.department=={},year=={},month=={}", department, year,month);
return attendanceReportService.getEmployeePreparationInfo(department,year,month);
}
}

View File

@ -0,0 +1,26 @@
package com.weaver.seconddev.jcl.organization.entity.hldz;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;
/**
* 原始打卡数据人员打卡数据
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceRecord {
private String personId;
// 标准加班类型小时数
private LocalDateTime addTime; // 打卡时间
}

View File

@ -0,0 +1,34 @@
package com.weaver.seconddev.jcl.organization.entity.hldz;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Auxiliary {
private String ryxm;
private String gh;
private String bm;
private String rq;
// 补贴字段
private String cfbt; // 厂房补贴
private String hjbt1; // 环境补贴1
private String hjbt2; //环境补贴2
private String hjbt3; // 环境补贴3
private String hjbt4; // 环境补贴4
private String hjbt5; // 环境补贴5
private String clbt; // 车辆补贴
private String byf; // 搬运费
private String zhts; // 在华天数
private String bmnbt; // 部门内部贴
private String wcbt; //误餐补贴()
}

View File

@ -0,0 +1,89 @@
package com.weaver.seconddev.jcl.organization.entity.hldz;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String id;
private String jobNum;
private String name;
private String deptId;
private String dept;
private String yearMonth;
private String totalShifts;
// 假期余额字段
private String paidAnnualLeave; // 带薪年休假
private String nursingLeave; // 哺乳假
private String paidAnnualAndNursingLeave;//年休假天数+含哺乳假
private String maternityLeave; // 产假
private String marriageLeave; // 婚假
private String familyVisitLeave; // 探亲假 1.父母1177292850110423040
private String familyVisitLeaveSpouse; //2.配偶 1199278194791358465
private String bereavementLeave; // 丧假
private String personalLeave; // 事假
private String commonSickLeave; // 普通病假
private String hospitalSickLeave; // 住院病假
private String officialLeave; // 因公休假
private String workInjuryLeave; // 工伤假
private String examLeave; // 考试假
private String careLeave; // 护理假+陪产假+育儿假
//private int paternityLeave; // 陪产假
//private int parentalLeave; // 育儿假
private String businessTrip; // 公出
private String compensatoryLeave; // 加班换休换休天数
private String womanresting; // 孕妇工间休息
private String OvertimeForCompensatoryleave; //加班换休技能职
// 补贴字段
private String cfbt; // 厂房补贴
private String hjbt1; // 环境补贴1
private String hjbt2; //环境补贴2
private String hjbt3; // 环境补贴3
private String hjbt4; // 环境补贴4
private String hjbt5; // 环境补贴5
private String clbt; // 车辆补贴
private String byf; // 搬运费
private String zhts; // 在华天数
private String bmnbt; // 部门内部贴
private String wcf; // 误餐费
// 标准加班类型小时数
private String day_type; // 加班类型
private String workOverTime; // 平时加班小时数
private String playDayOverTime; //周末加班小时数休日加班取系统中加班换休假+加班换休假-技能职中的加班时间转为可调休时间本月数据还是查加班换休之和
private String holidayOverTime; //节假日加班小时数
//中班/晚班数
private String midShifts; // 中班数排班上班
private String nightShifts; // 夜班数排班上班
//中班/晚班加班
private String midShiftsOver; // 中班数加班
private String nightShiftsOver; // 夜班数加班
//中班(总数)/晚班数总数
private String midShiftsAll;
private String nightShiftsAll;
//休日加班小时数计算后
private String playDayOverTimeCal;
//平日加班小时数计算后
private String workOverTimeCal;
//合计加班时长计算后
private String standardOvertimeAll;
//矿工天数
private String miner;
//福利假失效小时数
private String welfareLeaveDays;
//实际出勤天数
private String workLengthDay;
//加班余额兑换数
private double overtimeExchangeRate;
}

View File

@ -0,0 +1,24 @@
package com.weaver.seconddev.jcl.organization.entity.hldz;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StandardOvertime {
private String id;
// 标准加班类型小时数
private String day_type; // 加班类型
private String hour; // 小时数
private String minute; //分钟数
private String day; // 天数
}

View File

@ -0,0 +1,42 @@
package com.weaver.seconddev.jcl.organization.entity.hldz;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VacationBalance {
private String id;
private String name;
// 假期字段
private String paidAnnualLeave; // 带薪年休假
private String nursingLeave; // 哺乳假
//private int paidAnnualAndNursingLeave;//年休假天数+含哺乳假
private String maternityLeave; // 产假
private String marriageLeave; // 婚假
private String familyVisitLeave; // 探亲假(父母)
private String familyVisitLeaveSpouse;// 探亲假(配偶)
private String bereavementLeave; // 丧假
private String personalLeave; // 事假
private String commonSickLeave; // 普通病假
private String hospitalSickLeave; // 住院病假
private String officialLeave; // 因公休假
private String workInjuryLeave; // 工伤假
private String examLeave; // 考试假
private String careLeave; // 护理假+陪产假+育儿假
private String paternityLeave; // 陪产假
private String parentalLeave; // 育儿假
private String businessTrip; // 公出
private String compensatoryLeave; // 加班换休
private String womanresting; // 孕妇工间休息
private String OvertimeForCompensatoryleave; //加班换休技能职
}

View File

@ -166,10 +166,18 @@ public class SynEmployeeAgeGlSlInfoAction implements EsbServerlessRpcRemoteInter
return Period.between(startDate, endDate).getYears();
}
private Double calculateYears(LocalDate startDate, LocalDate endDate) {
// private Double calculateYears(LocalDate startDate, LocalDate endDate) {
// Period period = Period.between(startDate, endDate);
// double years = period.getYears() + (period.getMonths() / 12.0) + (period.getDays() / 365.0);
// return Math.round(years * 100.0) / 100.0; // 保留两位小数
// }
private Double calculateYears(LocalDate startDate, LocalDate endDate) {
// 计算日期间隔的年
Period period = Period.between(startDate, endDate);
// 转换为以年为单位的小数 + /12 + /365
double years = period.getYears() + (period.getMonths() / 12.0) + (period.getDays() / 365.0);
return Math.round(years * 100.0) / 100.0; // 保留两位小数
// 保留一位小数并向下取整放大10倍向下取整缩小10倍
return Math.floor(years * 10.0) / 10.0;
}
// 检查是否是日期格式 yyyy-MM-dd

View File

@ -0,0 +1,459 @@
package com.weaver.seconddev.jcl.organization.esb.cbd;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* @use同步考勤规则-应用范围人员
* @date 2025年12月27日
* @author xuxy
*/
@Service("syncAttendConfigRangeEmp_kq")
public class SyncAttendConfigRangeEmp implements EsbServerlessRpcRemoteInterface {
@Autowired
private DatabaseUtils databaseUtils;
private static final Logger log = LoggerFactory.getLogger(SyncAttendConfigRangeEmp.class);
@Override
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
log.error("SyncAttendConfigrangeEmp.start");
try {
//1.根据考勤规则eb表规则查询出每套考勤规则下对应的-应用范围人员
List<Map<String, Object>> kqgzEbInfo = getKqgzEbInfo();
//2.遍历考勤规则eb表查询1.范围人员 2.排除人员
for (Map<String, Object> map : kqgzEbInfo) {
String form_data_id = String.valueOf(map.get("form_data_id"));
String bm = String.valueOf(map.get("bm"));
String rylb2 = String.valueOf(map.get("rylb2"));
String bmpc = String.valueOf(map.get("bmpc"));
String frgs = String.valueOf(map.get("frgs"));
String kqgz = String.valueOf(map.get("kqgz"));
//根据部门人员类别查询add人员
List<Map<String, Object>> addEmployeeInfoAuto = getAddEmployeeInfoAuto(bm, rylb2);
//再查询手动新增人员/排除人员
List<Map<String, Object>> addEmployeeInfoManual = getAddEmployeeInfoManual(form_data_id);
//根据部门排除法人公司排除
List<Map<String, Object>> deleteEmployeeInfoAuto = getDeleteEmployeeInfoAuto(bmpc, frgs);
//筛选之后的新增人员id集合
List<String> list = filterFinalAddEmployees(addEmployeeInfoAuto, addEmployeeInfoManual, deleteEmployeeInfoAuto);
//新增人员再跟原本的考勤规则-应用范围做比对1.增量插入 2.缺量设置缺失人员失效日期为当前日期yyyy-MM-dd
filterResultList(list, kqgz);
}
log.error("SyncAttendConfigrangeEmp.kqgzEbInfo:{}", kqgzEbInfo);
}catch (Exception e) {
result.put("code","201");
log.error("Exception_em:"+e);
}
return WeaResult.success(result);
}
/**
* 根据考勤规则eb表规则查询出每套考勤规则下对应的-应用范围人员
* @return
*/
public List<Map<String, Object>> getKqgzEbInfo(){
String sql = " select * from e10_common.uf_kqgz where kqgz is not null and delete_type=0 and TENANT_KEY = 't024j0gfn0' ";
log.error("getKqgzEbInfo.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getKqgzEbInfo.recordList:{}", recordList);
return recordList;
}
/**
* 根据部门人员类别查询add人员
* @return
*/
public List<Map<String, Object>> getAddEmployeeInfoAuto(String bm,String rylb){
String sql = " SELECT DISTINCT e.id,e.username\n" +
" FROM eteams.employee e\n" +
" left JOIN eteams.ft_1152026012537184302 f on f.FORM_DATA_ID=e.formdata\n" +
" WHERE \n" +
" f.rylb= '"+rylb+"' and \n" +
" e.personnel_status not in ('6','7') and\n" +
" e.DEPARTMENT in \n" +
" (WITH RECURSIVE SubDepartments AS (\n" +
" SELECT id,name\n" +
" FROM eteams.department\n" +
" WHERE id in ("+bm+")\n" +
" AND IS_DELETE = 0\n" +
" AND `type` = 'department'\n" +
" AND STATUS = 1 \n" +
" \n" +
" UNION ALL\n" +
" \n" +
" SELECT d.id,d.name\n" +
" FROM eteams.department d\n" +
" INNER JOIN SubDepartments sd ON d.parent = sd.id\n" +
" WHERE d.IS_DELETE = 0\n" +
" AND d.`type` = 'department'\n" +
" AND d.STATUS = 1\n" +
" )\n" +
" SELECT DISTINCT CAST(id AS CHAR)\n" +
" FROM SubDepartments) ";
log.error("getAddEmployeeInfoAuto.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getAddEmployeeInfoAuto.recordList:{}", recordList);
return recordList;
}
/**
* 手动新增人员
* @return
*/
public List<Map<String, Object>> getAddEmployeeInfoManual(String form_data_id){
String sql = " select xzpc,ry from e10_common.uf_kqgz_sddz where delete_type=0 and FORM_DATA_ID = '"+form_data_id+"' and TENANT_KEY = 't024j0gfn0' ";
log.error("getAddEmployeeInfoManual.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getAddEmployeeInfoManual.recordList:{}", recordList);
return recordList;
}
/**
* 根据部门排除法人公司排除
* @return
*/
public List<Map<String, Object>> getDeleteEmployeeInfoAuto(String bmpc, String frgs){
// 优化点1前置判断 - bmpc和frgs都为空时直接返回空列表
if (StringUtils.isAllBlank(bmpc, frgs)) {
log.info("getDeleteEmployeeInfoAuto: bmpc和frgs均为空返回空列表");
return new ArrayList<>();
}
// ========== 1. 构建SQL固定部分 ==========
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append(" SELECT DISTINCT e.id,e.username ")
.append(" FROM eteams.employee e ")
.append(" left JOIN eteams.ft_1152026012537184302 f on f.FORM_DATA_ID=e.formdata ")
.append(" WHERE 1=1 "); // 占位符方便后续拼接AND条件
// ========== 2. 动态拼接frgs相关条件 ==========
if (StringUtils.isNotBlank(frgs)) {
sqlBuilder.append(" AND f.gzdssyyzx = '").append(frgs).append("' "); // 参数化占位符避免注入
}
// ========== 3. 动态拼接bmpc相关的部门递归查询 ==========
if (StringUtils.isNotBlank(bmpc)) {
sqlBuilder.append(" AND e.DEPARTMENT in ( ")
.append(" WITH RECURSIVE SubDepartments AS ( ")
.append(" SELECT id,name ")
.append(" FROM eteams.department ").append(" WHERE id in (").append(bmpc).append(") ") // 参数化占位符
.append(" AND IS_DELETE = 0 ")
.append(" AND `type` = 'department' ")
.append(" AND STATUS = 1 ")
.append(" UNION ALL ")
.append(" SELECT d.id,d.name ")
.append(" FROM eteams.department d ")
.append(" INNER JOIN SubDepartments sd ON d.parent = sd.id ")
.append(" WHERE d.IS_DELETE = 0 ")
.append(" AND d.`type` = 'department' ")
.append(" AND d.STATUS = 1 ")
.append(" ) ")
.append(" SELECT DISTINCT CAST(id AS CHAR) FROM SubDepartments ")
.append(" ) ");
}
// ========== 4. 拼接固定的人员状态条件 ==========
sqlBuilder.append(" AND e.personnel_status not in ('6','7') ");
log.error("getDeleteEmployeeInfoAuto.sql:{}", sqlBuilder.toString());
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sqlBuilder.toString());
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getDeleteEmployeeInfoAuto.recordList:{}", recordList);
return recordList;
}
/**
* 筛选最终剩余的新增人员ID集合去重排除后
* @param addEmployeeInfoAuto 自动新增人员列表含idname字段
* @param addEmployeeInfoManual 手动新增人员列表含xzpcry字段xzpc=0/1为标识ry=人员ID
* @param deleteEmployeeInfoAuto 自动排除人员列表含idname字段
* @return 剩余新增人员ID集合List<String>无重复
*/
public static List<String> filterFinalAddEmployees(
List<Map<String, Object>> addEmployeeInfoAuto,
List<Map<String, Object>> addEmployeeInfoManual,
List<Map<String, Object>> deleteEmployeeInfoAuto) {
// ========== 步骤1构建新增人员池id -> ry 映射去重 ==========
Map<String, String> addEmployeeMap = new HashMap<>();
// 1.1 处理自动新增列表id=人员IDname=ry
if (CollectionUtils.isNotEmpty(addEmployeeInfoAuto)) {
addEmployeeInfoAuto.stream()
.filter(map -> {
String id = getStringValue(map, "id");
String name = getStringValue(map, "name");
return StringUtils.isNotBlank(id) && StringUtils.isNotBlank(name);
})
.forEach(map -> {
String id = getStringValue(map, "id");
String ry = getStringValue(map, "name");
addEmployeeMap.putIfAbsent(id, ry);
});
}
// 1.2 处理手动新增列表筛选xzpc=0的人员ry=人员ID
if (CollectionUtils.isNotEmpty(addEmployeeInfoManual)) {
addEmployeeInfoManual.stream()
.filter(map -> {
String xzpc = getStringValue(map, "xzpc");
String empId = getStringValue(map, "ry");
return "0".equals(xzpc) && StringUtils.isNotBlank(empId);
})
.forEach(map -> {
String empId = getStringValue(map, "ry");
String ry = empId;
addEmployeeMap.putIfAbsent(empId, ry);
});
}
// ========== 步骤2构建排除人员ID集合 ==========
Set<String> excludeIdSet = new HashSet<>();
// 2.1 处理自动排除列表提取id人员ID
if (CollectionUtils.isNotEmpty(deleteEmployeeInfoAuto)) {
excludeIdSet.addAll(
deleteEmployeeInfoAuto.stream()
.map(map -> getStringValue(map, "id"))
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet())
);
}
// 2.2 处理手动新增列表筛选xzpc=1的人员提取ry人员ID作为排除ID
if (CollectionUtils.isNotEmpty(addEmployeeInfoManual)) {
excludeIdSet.addAll(
addEmployeeInfoManual.stream()
.filter(map -> {
String xzpc = getStringValue(map, "xzpc");
String empId = getStringValue(map, "ry");
return "1".equals(xzpc) && StringUtils.isNotBlank(empId);
})
.map(map -> getStringValue(map, "ry"))
.collect(Collectors.toSet())
);
}
// ========== 步骤3筛选剩余新增人员ID核心修改部分 ==========
// 排除需删除的人员ID
List<String> finalAddEmployees = addEmployeeMap.keySet().stream()
.filter(s -> !excludeIdSet.contains(s)) // 直接提取人员ID去掉Map构建
.collect(Collectors.toList()); // 收集为List<String>
log.error("filterFinalAddEmployees.finalAddEmployees:{}", finalAddEmployees);
return finalAddEmployees;
}
/**
* 安全获取Map中的String类型值处理null/
*/
private static String getStringValue(Map<String, Object> map, String key) {
if (map == null || key == null) {
return "";
}
Object value = map.get(key);
return value == null ? "" : value.toString().trim();
}
/**
* 插入考勤规则--应用范围
* @return
*/
public void insertAttendConfigRange(List<String> list,String kqgz){
/**
* 这里先查询一下:kqgz对应的应用范围人员最大序号
*/
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
int sort_num = 0;
String sql = " select sort_num from e10_other_business.attend_config_range where attend_config='"+kqgz+"' and delete_type =0 and TENANT_KEY = 't024j0gfn0' order by sort_num desc ";
log.error("insertAttendConfigRange.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("insertAttendConfigRange.recordList:{}", recordList);
sort_num = Integer.parseInt(String.valueOf(recordList.get(0).get("sort_num")));
log.error("insertAttendConfigRange.sort_num:{}", sort_num);
for (String s : list) {
sort_num+=1;
// 格式化时间
String formattedDateTime = now.format(formatter);
// 生成随机 ID
long id = IdGenerator.generate();
sql="insert into e10_other_business.attend_config_range(id,target_id,entry_type,tenant_key,create_time,update_time,delete_type,include_sub_dept,min_sec_level,max_sec_level,sort_num,creator) " +
" values('"+id+"','"+s+"','user','"+kqgz+"','t024j0gfn0','"+formattedDateTime+"','"+formattedDateTime+"','0','0','-999','999','"+sort_num+"','1167276462243069953') ";
log.error("insertAttendConfigRange.sql222:{}", sql);
Map<String, Object> rt = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("insertAttendConfigRange.sort_num22222:{}", sort_num);
log.error("insertAttendConfigRange.rs:{}", rt);
}
}
/**
* 更新考勤规则--应用范围失效时间
* @return
*/
public void updateAttendConfigRangeExp(List<String> list,String kqgz){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (String s : list) {
String sql = " select * from e10_other_business.attend_configrange_exp where CONFIG_RANGE_ID in(select id from e10_other_business.attend_config_range where attend_config='"+kqgz+"' \n" +
" and delete_type =0 and ENTRY_TYPE = 'user' and TENANT_KEY = 't024j0gfn0' and TARGET_ID = '"+s+"')";
log.error("updateAttendConfigRangeExp.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("updateAttendConfigRangeExp.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
String id = String.valueOf(recordList.get(0).get("id"));
String formattedDateTime = now.format(formatter);
//根据id更新失效时间
sql = "update e10_other_business.attend_configrange_exp set EXPIRY_DATE_END = '"+formattedDateTime+"' where id = '"+id+"' ";
log.error("updateAttendConfigRangeExp.sql222:{}", sql);
Map<String, Object> rt = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("updateAttendConfigRangeExp.rt222:{}", rt);
}else {
//新增失效时间表
//生成随机 ID
long id = IdGenerator.generate();
String formattedDateTime = now.format(formatter);
/**
* 这里查询一下CONFIG_RANGE_ID
*/
sql = " select id from e10_other_business.attend_config_range where attend_config='"+kqgz+"' and delete_type =0 and ENTRY_TYPE = 'user' and TENANT_KEY = 't024j0gfn0' and TARGET_ID = '"+s+"' ";
log.error("updateAttendConfigRangeExp.sql333:{}", sql);
Map<String, Object> rt2 = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList2 = databaseUtils.getDataSourceList(rt2);
log.error("updateAttendConfigRangeExp.recordList2:{}", recordList2);
String config_range_id = String.valueOf(recordList2.get(0).get("id"));
sql="insert into e10_other_business.attend_configrange_exp(id,create_time,update_time,delete_type,creator,tenant_key,EXPIRY_DATE_BEGIN,EXPIRY_DATE_END,CONFIG_RANGE_ID,CONFIG_ID) " +
" values('"+id+"','"+formattedDateTime+"','"+formattedDateTime+"','0','1167276462243069953','t024j0gfn0','2000-01-01','"+formattedDateTime+"','"+config_range_id+"','"+kqgz+"') ";
log.error("insertAttendConfigRange.sql444:{}", sql);
Map<String, Object> rt3 = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList3 = databaseUtils.getDataSourceList(rt3);
log.error("updateAttendConfigRangeExp.recordList3:{}", recordList3);
}
}
}
public void filterResultList(List<String> list,String kqgz){
//1.查询原本的考勤规则对应的人员范围
String sql = " select * from e10_other_business.attend_config_range where attend_config='"+kqgz+"' and delete_type =0 and ENTRY_TYPE = 'user' and TENANT_KEY = 't024j0gfn0' ";
log.error("filterResultList.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("filterResultList.recordList:{}", recordList);
List<String> recordList2 = getTargetIdList(recordList);
//2.比对新老人员筛选新增人员和失效人员
List<String>[] lists = compareStringListWithOrder(list, recordList2);
List<String> addData = lists[0];
List<String> missingData = lists[1];
//插入考勤规则--应用范围
insertAttendConfigRange(addData,kqgz);
//缺失人员设置失效日期
updateAttendConfigRangeExp(missingData,kqgz);
}
public List<String> getTargetIdList(List<Map<String, Object>> recordList) {
if (Objects.isNull(recordList)) {
return new ArrayList<>();
}
return recordList.stream()
.filter(Objects::nonNull)
.map(map -> Optional.ofNullable(map.get("target_id")).map(Object::toString).map(String::trim).orElse(""))
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
}
/**
* 对比两个String列表返回新增数据缺失数据保留原顺序
* @param baseList 基准列表list
* @param compareList 对比列表recordList2
* @return [新增数据List, 缺失数据List]
*/
public static List<String>[] compareStringListWithOrder(List<String> baseList, List<String> compareList) {
// 空值兜底
List<String> safeBase = Optional.ofNullable(baseList).orElse(new ArrayList<>());
List<String> safeCompare = Optional.ofNullable(compareList).orElse(new ArrayList<>());
// 转LinkedHashSet有序 + 去重 + 高效查找
Set<String> baseSet = new LinkedHashSet<>(safeBase);
Set<String> compareSet = new LinkedHashSet<>(safeCompare);
// 新增数据compareList有baseList无
List<String> addData = safeCompare.stream()
.filter(item -> !baseSet.contains(item))
.collect(Collectors.toList());
// 缺失数据baseList有compareList无
List<String> missingData = safeBase.stream()
.filter(item -> !compareSet.contains(item))
.collect(Collectors.toList());
return new List[]{addData, missingData};
}
// 测试方法
// public static void main(String[] args) {
// // 模拟测试数据同之前
// List<Map<String, Object>> addAuto = new ArrayList<>();
// Map<String, Object> auto1 = new HashMap<>();
// auto1.put("id", "001");
// auto1.put("name", "张三");
// addAuto.add(auto1);
// Map<String, Object> auto2 = new HashMap<>();
// auto2.put("id", "002");
// auto2.put("name", "李四");
// addAuto.add(auto2);
//
// List<Map<String, Object>> addManual = new ArrayList<>();
// Map<String, Object> manual1 = new HashMap<>();
// manual1.put("xzpc", "0");
// manual1.put("ry", "003");
// addManual.add(manual1);
// Map<String, Object> manual2 = new HashMap<>();
// manual2.put("xzpc", "1");
// manual2.put("ry", "002");
// addManual.add(manual2);
//
// List<Map<String, Object>> deleteAuto = new ArrayList<>();
// Map<String, Object> delete1 = new HashMap<>();
// delete1.put("id", "001");
// delete1.put("name", "张三");
// deleteAuto.add(delete1);
//
// // 筛选最终新增人员ID
// List<String> finalResult = filterFinalAddEmployees(addAuto, addManual, deleteAuto);
//
// // 输出结果
// System.out.println("最终剩余新增人员ID");
// finalResult.forEach(id -> System.out.println(id));
// }
}

View File

@ -0,0 +1,283 @@
package com.weaver.seconddev.jcl.organization.esb.cbd;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @use同步人员附件信息
* @date 2025年12月29日
* @author xuxy
*/
@Service("syncEmployeeAttaInfo_jcl")
public class SyncEmployeeAttaInfo implements EsbServerlessRpcRemoteInterface {
private static final Pattern JOB_NUM_PATTERN = Pattern.compile("_(\\d+)(\\(\\d+\\))?\\.[^.]+$");
@Autowired
private DatabaseUtils databaseUtils;
private static final Logger log = LoggerFactory.getLogger(SyncEmployeeAttaInfo.class);
@Override
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
log.error("SyncEmployeeAttaInfo.start");
String ml = null!=params.get("ml")?String.valueOf(params.get("ml").toString()):"";
String fieldName = null!=params.get("fieldName")?String.valueOf(params.get("fieldName").toString()):"";
log.error("SyncEmployeeAttaInfo.ml:{}", ml);
log.error("SyncEmployeeAttaInfo.fieldName:{}", fieldName);
try {
Map<String, String> map = parseFileAndMatchJobNum(ml, fieldName);
result.put("map",map);
}catch (Exception e) {
result.put("code","201");
log.error("Exception_em:"+e);
}
return WeaResult.success(result);
}
// ===================== 2. 核心主方法一站式完成读文件+解析工号+工号匹配=====================
/**
* 读取指定目录下所有文件解析文件名中的工号并匹配目标工号
* @param targetDir 本地指定目录路径必填
*/
public Map<String,String> parseFileAndMatchJobNum(String targetDir,String fieldName) {
Map<String,String> map = new HashMap<>();
// 1. 封装目录File对象
File dir = new File(targetDir);
log.error("SyncEmployeeAttaInfo.dir:{}", dir);
// 校验目录合法性
if (!dir.exists()) {
log.error("❌ 错误:指定的目录不存在 → " + targetDir);
map.put("targetDir",targetDir);
map.put("msg","指定的目录不存在");
return map;
}
if (!dir.isDirectory()) {
log.error("❌ 错误:指定路径不是文件夹 → " + targetDir);
map.put("targetDir",targetDir);
map.put("msg","指定路径不是文件夹");
return map;
}
// 2. Java8 流式遍历目录下所有文件自动过滤文件夹
Optional.ofNullable(dir.listFiles())
.ifPresent(files -> {
for (File file : files) {
if (file.isFile()) { // 只处理文件跳过子文件夹
String docName = file.getName(); // 获取完整文件名
log.error("📄 读取到文件:" + docName);
// 3. 解析文件名中的工号
String jobNum = parseJobNumFromFileName(docName);
if (Objects.nonNull(jobNum)) {
log.error("✅ 解析出工号:" + jobNum);
// 4. 根据工号执行匹配逻辑
matchTargetJobNum(jobNum,docName,fieldName);
} else {
log.error("❌ 该文件名称不符合规则,未解析出工号 → " + fieldName);
}
}
}
});
return map;
}
// ===================== 3. 核心工具方法从文件名解析工号核心逻辑=====================
/**
* 从指定文件名中提取工号兼容两种格式xxx_工号 / xxx_工号(数字)
* @param docName 完整文件名黄小倩_身份证人像面_1000006711(1)
* @return 解析后的纯工号格式不匹配返回null
*/
public static String parseJobNumFromFileName(String docName) {
if (docName == null || docName.trim().isEmpty()) {
return null;
}
Matcher matcher = JOB_NUM_PATTERN.matcher(docName);
// 匹配成功则返回分组1的纯工号失败返回null
return matcher.find() ? matcher.group(1) : null;
}
// ===================== 4. 业务方法工号匹配可根据实际需求扩展=====================
/**
* 工号匹配逻辑可根据业务需求自定义实现数据库查询集合匹配等
* @param fileJobNum 从文件解析出的工号
* @param fileName 从文件解析出的名称
*/
public void matchTargetJobNum(String fileJobNum,String docName,String fileName) {
//1.根据文件名称查询文件id
String docId = getFileId(docName);
if(StringUtils.isNotBlank(docId)){
//2.更新eb表附件字段
updateEmployeeInformationField(fileJobNum,docId,fileName);
//3.更新个人信息自定义表附件字段
updateHruserInfoField(fileJobNum,docId,fileName);
}
}
/**
* 根据文件名称查询文件id
* @return
*/
public String getFileId(String docName){
String docid = "";
String sql = " select id from e10_core_business.fileobj where name = '"+docName+"' and DELETE_TYPE = 0 and TENANT_KEY = 't024j0gfn0' ";
log.error("getFileId.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getFileId.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
docid = String.valueOf(recordList.get(0).get("id"));
}
return docid;
}
/**
* 根据文件名称查询员工信息表文件id
* @return
*/
public void updateEmployeeInformationField(String job_num,String docid,String fileName){
String sql = " SELECT "+fileName+" from e10_common.uf_jcl_employee_information where job_num = '"+job_num+"' and DELETE_TYPE = 0 and TENANT_KEY = 't024j0gfn0'\n ";
log.error("checkEmployeeIsNotHave.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("checkEmployeeIsNotHave.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
String xxzbs = String.valueOf(recordList.get(0).get(fileName));
//返回新拼接得附件id
String notContain = appendIfNotContain(xxzbs, docid);
//将新附件id更新到原来字段中
updateEbField(notContain,job_num,fileName);
}else {
//为空直接更新docid到对应eb字段
updateEbField(docid,job_num,fileName);
}
}
/**
* 根据个人信息表附件字段
* @return
*/
public void updateHruserInfoField(String job_num,String docid,String fileName){
String sql = " select form_data_id,"+fileName+" from ft_1152116439014449153 where FORM_DATA_ID = (\n" +
"select FORM_DATA from e10_other_business.hr_userinfo where user = (\n" +
"select id from eteams.employee where job_num = '"+job_num+"')) and DELETE_TYPE = 0 and TENANT_KEY = 't024j0gfn0'\n ";
log.error("updateHruserInfoField.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("updateHruserInfoField.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
String xxzbs = String.valueOf(recordList.get(0).get(fileName));
String form_data_id = String.valueOf(recordList.get(0).get("form_data_id"));
if(StringUtils.isNotBlank(xxzbs)){
//返回新拼接得附件id
String notContain = appendIfNotContain(xxzbs, docid);
//将新附件id更新到原来字段中
updateHrField(notContain,form_data_id,fileName);
}else {
//为空直接更新docid到对应eb字段
updateHrField(docid,form_data_id,fileName);
}
}
}
/**
* 逗号分隔字符串若不包含目标str则追加最终返回新的逗号分隔字符串
* @param originalStr 原始逗号分隔字符串 (1000006711,1000006712)
* @param targetStr 待判断的目标字符串 (1000006713)
* @return 拼接后的新字符串
*/
public static String appendIfNotContain(String originalStr, String targetStr) {
// 1. 逗号字符串 List集合
List<String> strList = Arrays.stream(originalStr.split(","))
.map(String::trim) // 去首尾空格
.collect(Collectors.toList());
// 2. 判断是否包含不包含则追加
if (!strList.contains(targetStr.trim())) {
strList.add(targetStr.trim());
}
// 3. List 逗号分隔的新字符串核心Java8流式拼接
return strList.stream().collect(Collectors.joining(","));
}
/**
* 根据人员工号将新的附件id更新到原来eb字段
* @return
*/
public void updateEbField(String fileid,String job_num,String fileName){
String sql = " update e10_common.uf_jcl_employee_information set "+fileName+" = '"+fileid+"' where job_num = '"+job_num+"' and DELETE_TYPE = 0 and TENANT_KEY = 't024j0gfn0' ";
log.error("updateEbField.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("updateEbField.recordList:{}", recordList);
}
/**
* 根据人员工号将新的附件id更新到原来hr字段
* @return
*/
public void updateHrField(String fileid,String form_data_id,String fileName){
String sql = " update e10_other_business.ft_1152116439014449153 set "+fileName+" = '"+fileid+"' where form_data_id = '"+form_data_id+"' and DELETE_TYPE = 0 and TENANT_KEY = 't024j0gfn0'\n ";
log.error("updateHrField.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("updateHrField.recordList:{}", recordList);
}
/**
* 插入考勤规则--应用范围
* @return
*/
public void insertAttendConfigRange(List<String> list,String kqgz){
/**
* 这里先查询一下:kqgz对应的应用范围人员最大序号
*/
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
int sort_num = 0;
String sql = " select sort_num from e10_other_business.attend_config_range where attend_config='"+kqgz+"' and delete_type =0 and TENANT_KEY = 't024j0gfn0' order by sort_num desc ";
log.error("insertAttendConfigRange.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("insertAttendConfigRange.recordList:{}", recordList);
sort_num = Integer.parseInt(String.valueOf(recordList.get(0).get("sort_num")));
log.error("insertAttendConfigRange.sort_num:{}", sort_num);
for (String s : list) {
sort_num+=1;
// 格式化时间
String formattedDateTime = now.format(formatter);
// 生成随机 ID
long id = IdGenerator.generate();
sql="insert into e10_other_business.attend_config_range(id,target_id,entry_type,tenant_key,create_time,update_time,delete_type,include_sub_dept,min_sec_level,max_sec_level,sort_num,creator) " +
" values('"+id+"','"+s+"','user','"+kqgz+"','t024j0gfn0','"+formattedDateTime+"','"+formattedDateTime+"','0','0','-999','999','"+sort_num+"','1167276462243069953') ";
log.error("insertAttendConfigRange.sql222:{}", sql);
Map<String, Object> rt = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("insertAttendConfigRange.sort_num22222:{}", sort_num);
log.error("insertAttendConfigRange.rs:{}", rt);
}
}
}

View File

@ -0,0 +1,155 @@
package com.weaver.seconddev.jcl.organization.esb.cbd;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* @use同步矩阵信息
* @date 2025年12月31日
* @author xuxy
*/
@Service("syncMatrixInfo_jcl")
public class SyncMatrixInfo implements EsbServerlessRpcRemoteInterface {
@Autowired
private DatabaseUtils databaseUtils;
private static final Logger log = LoggerFactory.getLogger(SyncMatrixInfo.class);
@Override
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
try {
//1.查询数据源
List<Map<String, Object>> hrbpValues = getHrbpValues();
//2.遍历查询是否存在不存在插入矩阵信息
for (Map<String, Object> hrbpValue : hrbpValues) {
//判断是否存在
String empid = getValueOrDefaultEmpty(hrbpValue, "empid");
String hrbp = getValueOrDefaultEmpty(hrbpValue, "hrbp");
boolean b = checkIsNotHave(empid);
boolean b1 = checkIsNotHaveData(hrbp);
if(b&&b1){
//插表
insertMatrixInfo(empid,hrbp);
}
}
log.error("syncDepartment.result:{}", result);
}catch (Exception e) {
result.put("status2","exception");
log.error("Exception_em:"+e);
}
return WeaResult.success(result);
}
/**
* 从Map中根据key取值null则返回空字符串非null返回原值转为String
* @param map 源Map
* @param key 要获取的key
* @return 处理后的字符串
*/
private static String getValueOrDefaultEmpty(Map<String, Object> map, String key) {
// Optional.ofNullable处理nullorElse设置默认值为空字符串
return Optional.ofNullable(map.get(key))
.map(Object::toString) // 将非null的Object转为String
.orElse("");
}
/**
* 查询数据源
* @return
*/
public List<Map<String, Object>> getHrbpValues(){
String sql = "select * from eteams.v_hrbp where hrbp is not null ";
log.error("getHrbpValues.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getHrbpValues.recordList:{}", recordList);
return recordList;
}
/**
* 判断是否存在
* @return
*/
public boolean checkIsNotHave(String relate_id){
boolean flag = true;
String sql = " select id from eteams.hrm_matrix_condition_data where RELATE_ID = '"+relate_id+"' and DELETE_TYPE=0 and TENANT_KEY='t024j0gfn0' ";
log.error("checkIsNotHave.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("checkIsNotHave.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
flag = false;
}
return flag;
}
/**
* 判断是否存在
* @return
*/
public boolean checkIsNotHaveData(String relate_id){
boolean flag = true;
String sql = " select id from eteams.hrm_matrix_value_data where RELATE_ID = '"+relate_id+"' and DELETE_TYPE=0 and TENANT_KEY='t024j0gfn0' ";
log.error("checkIsNotHaveData.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("checkIsNotHaveData.recordList:{}", recordList);
if(CollectionUtils.isNotEmpty(recordList)){
flag = false;
}
return flag;
}
/**
* 插入考勤规则--应用范围
* @return
*/
public void insertMatrixInfo(String empid,String hrbp){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化时间
String dateTime = now.format(formatter);
log.error("insertMatrixInfo.dateTime:{}", dateTime);
// 生成随机 ID
long id = IdGenerator.generate();
log.error("insertMatrixInfo.id:{}", id);
//插入eteams.hrm_matrix_data
String sql="insert into eteams.hrm_matrix_data(id,matrix_id,create_time,update_time,creator,delete_type,tenant_key,data_sort) " +
" values('"+id+"','1219550724007141382','"+dateTime+"','"+dateTime+"','1167276462243069953','0','t024j0gfn0','') ";
log.error("insertMatrixInfo.sql:{}", sql);
Map<String, Object> rt = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("insertMatrixInfo.rs:{}", rt);
//插入:eteams.hrm_matrix_condition_data
long id2 = IdGenerator.generate();
sql="insert into eteams.hrm_matrix_condition_data(id,matrix_id,matrix_condition_config_id,matrix_data_id,relate_id,create_time,update_time,creator,delete_type,tenant_key) " +
" values('"+id2+"','1219550724007141382','1219550736933986305','"+ id +"','"+empid+"','"+dateTime+"','"+dateTime+"','1167276462243069953','0','t024j0gfn0') ";
log.error("insertMatrixInfo.sql222:{}", sql);
Map<String, Object> rt2 = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("insertMatrixInfo.rs2:{}", rt2);
//插入eteams.hrm_matrix_value_data
long id3 = IdGenerator.generate();
sql="insert into eteams.hrm_matrix_value_data(id,matrix_id,matrix_condition_config_id,matrix_data_id,relate_id,create_time,update_time,creator,delete_type,tenant_key,sort) " +
" values('"+id3+"','1219550724007141382','1219550736933986305','"+ id +"','"+hrbp+"','"+dateTime+"','"+dateTime+"','1167276462243069953','0','t024j0gfn0','') ";
log.error("insertMatrixInfo.sql333:{}", sql);
Map<String, Object> rt3 = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
log.error("insertMatrixInfo.rs3:{}", rt3);
}
}

View File

@ -375,7 +375,7 @@ public class SyncOrganizationPersonInfo_cbd implements EsbServerlessRpcRemoteInt
user_Info.put("employeeid",getIgnoreCase(employee_info, "id"));
user_Info.put("password",containsKeyIgnoreCase(employee_info,"mm")?getIgnoreCase(employee_info, "mm"):"");
user_Info.put("status","6");
user_Info.put("TENANTKEY",getIgnoreCase(employee_info, "TENANTKEY"));
user_Info.put("TENANTKEY","t024j0gfn0");
user_Info.put("username",getIgnoreCase(employee_info, "username"));
user_Info.put("email",containsKeyIgnoreCase(employee_info,"email")?getIgnoreCase(employee_info, "email"):"");
user_Info.put("mobile",containsKeyIgnoreCase(employee_info,"mobile")?getIgnoreCase(employee_info, "mobile"):"");

View File

@ -1,8 +1,6 @@
package com.weaver.seconddev.jcl.organization.esb.cbd;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.hrm.util.ImmutableMapUtil;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.loom.context.annotation.WeaHookReg;
import com.weaver.loom.context.domain.AppInfo;
import com.weaver.loom.context.domain.WeaHookRequest;
@ -14,10 +12,8 @@ import com.weaver.common.hrm.dto.xmind.Node;
import com.weaver.common.hrm.dto.xmind.Sheet;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import com.weaver.seconddev.jcl.organization.util.RecruitModuleUtils;
import com.weaver.teams.hrapp.dto.est.HrComEstCfgInfoDto;
import com.weaver.teams.hrapp.dto.est.param.HrComEstCfgInfoParam;
import com.weaver.teams.hrapp.rest.HrRemoteApiService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -32,6 +28,7 @@ public class XmindDataFilterCmd extends RegHookEvent {
private static String tenant_key = RecruitModuleUtils.getCurrentTenantKey();
// 线程安全的全局岗位映射
private static final Map<String, List<Map<String, Object>>> DEPT_POSITION_MAP = new ConcurrentHashMap<>();
private static final Map<String, List<Map<String, Object>>> POSITION_EMP_MAP = new ConcurrentHashMap<>();
private static final List<Map<String, Object>> DEPT_POSITION_EST_MAP = new ArrayList<>();
private static final List<Map<String, Object>> POSITION_EST_MAP = new ArrayList<>();
private static final Map<String, Integer> DEPT_EMPLOYEE_COUNT_MAP = new ConcurrentHashMap<>();
@ -84,6 +81,7 @@ public class XmindDataFilterCmd extends RegHookEvent {
@Override
public WeaHookResponse handle(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
log.error("XmindDataFilterCmd.start11111111111111");
//入参修改入参并不会影响到埋点的原始数据
Map<String, Object> param = request.getParams();
long start = System.nanoTime();
@ -91,6 +89,8 @@ public class XmindDataFilterCmd extends RegHookEvent {
initialize();
//初始化部门岗位数据
initializeDeptEmployeeCount();
//初始化各岗位人员姓名
initializePositionEmployee();
//初始化各岗位人数
initializePositionEmployeeCount();
//初始化人员信息
@ -116,18 +116,20 @@ public class XmindDataFilterCmd extends RegHookEvent {
for (Map<String, Object> allDepartment : allDepartments) {
Deft deft = new Deft();
String id = String.valueOf(allDepartment.get("id"));
deft.setId(id);
deft.setName(String.valueOf(allDepartment.get("name")));
deft.setParent_id(String.valueOf(allDepartment.get("parent")));
String deptName = String.valueOf(allDepartment.get("name"));
/**
* 计算完部门人员和编制数之后再入值
*/
//这里要根据部门id查询
List<Map<String, Object>> bmBzList = getBzListByBmId(id);
log.error("XmindDataFilterCmd.bmBzList:{}", bmBzList);
// 处理数据增加空列表校验
//编制数
//部门编制数
int estCount =0;
//缺编数
//部门缺编数
int estLackCount =0;
//超编数
//部门超编数
int estOverCount =0;
if (bmBzList != null && !bmBzList.isEmpty()) {
Map<String, Object> data = bmBzList.get(0);
@ -147,20 +149,27 @@ public class XmindDataFilterCmd extends RegHookEvent {
estOverCount = Integer.parseInt(value3.trim());
}
}
//查询部门在岗人数
//查询部门在岗人数positionCount
// 在调用前添加日志检查
log.error("DEPT_EMPLOYEE_COUNT_MAP size: {}", DEPT_EMPLOYEE_COUNT_MAP != null ? DEPT_EMPLOYEE_COUNT_MAP.size() : "null");
log.error("DEPT_EMPLOYEE_COUNT_MAP size: {}", DEPT_EMPLOYEE_COUNT_MAP.size());
log.error("XmindDataFilterCmd.id8888:{}", id);
int positionCount = Optional.ofNullable(DEPT_EMPLOYEE_COUNT_MAP)
int positionCount = Optional.of(DEPT_EMPLOYEE_COUNT_MAP)
.map(map -> map.getOrDefault(id, 0))
.orElse(0);
//查询部门岗位名称
List<Map<String, Object>> positionByDept = getPositionsByDept(id);
log.error("XmindDataFilterCmd.positionByDept:{}", positionByDept);
/**
* 这里修改一下逻辑改变原来的部门下岗位名称的展示
*/
//List<Map<String, Object>> positionByDept = DEPT_POSITION_MAP.get(id);
//log.error("XmindDataFilterCmd.positionByDept:{}", positionByDept);
/**
* 这里补充一个逻辑增加部门对应的岗位+岗位对应的人员作为子节点
*/
//遍历部门岗位查询岗位编制等相关信息
StringJoiner joiner = new StringJoiner(",");
if(CollectionUtils.isNotEmpty(positionByDept)){
for (Map<String, Object> map : positionByDept) {
if(CollectionUtils.isNotEmpty(DEPT_POSITION_MAP.get(id))){
for (Map<String, Object> map : DEPT_POSITION_MAP.get(id)) {
String gwId = String.valueOf(map.get("id"));
String gwName = String.valueOf(map.get("name"));
//查询岗位编制数/缺编数
@ -174,7 +183,6 @@ public class XmindDataFilterCmd extends RegHookEvent {
String value1 = String.valueOf(data.get("estLackCount"));
String value2 = String.valueOf(data.get("estLackCount"));
if (value1 == null || value1.trim().isEmpty()) {
estCountGw = 0;
}else {
estCountGw = Integer.parseInt(value1.trim());
}
@ -185,13 +193,45 @@ public class XmindDataFilterCmd extends RegHookEvent {
}
}
//查询岗位人数
int countGw = Optional.ofNullable(POSITION_EMPLOYEE_COUNT_MAP)
int countGw = Optional.of(POSITION_EMPLOYEE_COUNT_MAP)
.map(map1 -> map1.getOrDefault(gwId, 0))
.orElse(0);
log.error("XmindDataFilterCmd.countGw:{}", countGw);
String gwInfo = String.format("\n岗位名称%s、编制数%d、在岗人数%d、缺编数%d",
gwName, estCountGw, countGw, estLackCountGw);
joiner.add(gwInfo);
/**
* 这里增加一个岗位信息展示
* 岗位名称
* 在岗人数/岗位编制数
*人员姓名
*/
//根据岗位id获取人员列表
List<Map<String, Object>> mapList = POSITION_EMP_MAP.get(gwId);
// 2. 处理mapList为null的情况替换为空List
mapList = mapList == null ? Collections.emptyList() : mapList;
// 3. 提取姓名时增加空Map过滤 + 异常捕获
List<String> empNames = mapList.stream()
.filter(Objects::nonNull) // 过滤List中的null元素关键
.map(map1 -> {
try {
Object nameObj = map1.get("name");
// 处理nameObj为非字符串类型的情况如数字布尔值
return nameObj == null ? null : nameObj.toString().trim();
} catch (Exception e) {
// 捕获toString()异常日志记录后返回null后续被filter过滤
log.error("提取姓名失败map数据{},异常:{}", map1, e.getMessage());
return null;
}
})
.filter(name -> name != null && !name.isEmpty())
.collect(Collectors.toList());
/**
* 拼接岗位参数替换原来的岗位名称展示
*/
String result2 = formatGwInfo(gwName, countGw, estCountGw, empNames);
map.put("name",result2);
}
}
//查询人员姓名/职级/职位
@ -204,12 +244,12 @@ public class XmindDataFilterCmd extends RegHookEvent {
String jobset_level = String.valueOf(map.get("jobset_level"));
//职级
//String jobsetLevel = USERINFO_Level_MAP.get(jobset_level);
String jobsetLevel = Optional.ofNullable(USERINFO_Level_MAP)
String jobsetLevel = Optional.of(USERINFO_Level_MAP)
.map(map1 -> map1.getOrDefault(jobset_level, ""))
.orElse("");
//职位
//String zw = USERINFO_ZW_MAP.get(userId);
String zw = Optional.ofNullable(USERINFO_ZW_MAP)
String zw = Optional.of(USERINFO_ZW_MAP)
.map(map1 -> map1.getOrDefault(userId, ""))
.orElse("");
// 格式化当前人员信息
@ -223,6 +263,26 @@ public class XmindDataFilterCmd extends RegHookEvent {
sb.append(personInfo);
}
}
/**
* 在这里拼接参数包括部门的岗位的
*/
//1.部门参数
// 步骤1拼接下层字符串
String lowerStr = positionCount + "/" + estCount;
// 步骤2计算上层和下层的字符串长度
int deptNameLen = deptName.length();
int lowerStrLen = lowerStr.length();
// 步骤3计算居中缩进的空格数向下取整若长度差为奇数会轻微偏左+1调整
int indentSpace = (deptNameLen - lowerStrLen) / 2;
// 步骤4生成缩进空格Java 8可用String.join生成重复空格
String indent = String.join("", java.util.Collections.nCopies(indentSpace, " "));
// 步骤5拼接最终结果
String resultdept = String.format("%s%n%s%s", deptName, indent, lowerStr);
deft.setId(id);
deft.setName(resultdept);
deft.setParent_id(String.valueOf(allDepartment.get("parent")));
// 计算remark
String remark = String.format("部门编制数:%d\n部门在岗人数%d\n部门缺编数%d\n岗位%s\n人员%s",
estCount,
@ -239,16 +299,18 @@ public class XmindDataFilterCmd extends RegHookEvent {
// }
deft.setRemark(remark);
if((estLackCount >0) || (estOverCount >0)){
deft.setBgColor("#F1F1F1");
deft.setBgColor("#B0E0E6");// 粉末蓝
}
defts.add(deft);
}
//3.组装
//3.组装这里构建富子结点增加了部门子节点对应岗位++岗位子节点对应人员
Node root = buildDepartmentTree(defts);
//4.塞入节点
allDataSheet.setNode(root);
log.error("XmindDataFilterCmd.allDataSheet11:{}", allDataSheet);
//独立部门
/**
* 独立部门 (独立sheet页面)
*/
List<Map<String, Object>> getsfdcdlzzjgBm = getsfdcdlzzjgBm();
if(CollectionUtils.isNotEmpty(getsfdcdlzzjgBm)){
//2.组装部门数据2
@ -294,15 +356,15 @@ public class XmindDataFilterCmd extends RegHookEvent {
}
}
//查询在岗人数
int positionCount = Optional.ofNullable(DEPT_EMPLOYEE_COUNT_MAP)
.map(map -> map.getOrDefault(id, 0))
int positionCount = Optional.of(DEPT_EMPLOYEE_COUNT_MAP)
.map(map -> map.getOrDefault(id2, 0))
.orElse(0);
//查询部门岗位名称
List<Map<String, Object>> positionByDept = getPositionsByDept(id);
//List<Map<String, Object>> positionByDept = getPositionsByDept(id);
//遍历部门岗位查询岗位编制等相关信息
StringJoiner joiner = new StringJoiner(",");
if(CollectionUtils.isNotEmpty(positionByDept)){
for (Map<String, Object> map : positionByDept) {
if(CollectionUtils.isNotEmpty(DEPT_POSITION_MAP.get(id2))){
for (Map<String, Object> map : DEPT_POSITION_MAP.get(id2)) {
String gwId = String.valueOf(map.get("id"));
String gwName = String.valueOf(map.get("name"));
//查询岗位编制数/缺编数
@ -315,7 +377,6 @@ public class XmindDataFilterCmd extends RegHookEvent {
String value1 = String.valueOf(data.get("estLackCount"));
String value2 = String.valueOf(data.get("estLackCount"));
if (value1 == null || value1.trim().isEmpty()) {
estCountGw = 0;
}else {
estCountGw = Integer.parseInt(value1.trim());
}
@ -326,61 +387,112 @@ public class XmindDataFilterCmd extends RegHookEvent {
}
}
//查询岗位人数
int countGw = Optional.ofNullable(POSITION_EMPLOYEE_COUNT_MAP)
int countGw = Optional.of(POSITION_EMPLOYEE_COUNT_MAP)
.map(map1 -> map1.getOrDefault(gwId, 0))
.orElse(0);
String gwInfo = String.format("岗位名称:%s、编制数%d、在岗人数%d、缺编数%d",
gwName, estCountGw, countGw, estLackCountGw);
joiner.add(gwInfo);
/**
* 这里增加一个岗位信息展示
* 岗位名称
* 在岗人数/岗位编制数
*人员姓名
*/
//根据岗位id获取人员列表
// List<Map<String, Object>> mapList = POSITION_EMP_MAP.get(gwId);
// 2. 处理mapList为null的情况替换为空List
//mapList = mapList == null ? Collections.emptyList() : mapList;
// 3. 提取姓名时增加空Map过滤 + 异常捕获
// List<String> empNames = mapList.stream()
// .filter(Objects::nonNull) // 过滤List中的null元素关键
// .map(map1 -> {
// try {
// Object nameObj = map1.get("name");
// // 处理nameObj为非字符串类型的情况如数字布尔值
// return nameObj == null ? null : nameObj.toString().trim();
// } catch (Exception e) {
// // 捕获toString()异常日志记录后返回null后续被filter过滤
// log.error("提取姓名失败map数据{},异常:{}", map1, e.getMessage());
// return null;
// }
// })
// .filter(name2 -> name2 != null && !name2.isEmpty())
// .collect(Collectors.toList());
/**
* 拼接岗位参数替换原来的岗位名称展示
*/
//log.error("XmindDataFilterCmd.gwName:{},countGw:{},estCountGw:{},empNames:{}", gwName,countGw,estCountGw,empNames);
//String result2 = formatGwInfo(gwName, countGw, estCountGw, empNames);
//map.put("name",result2);
}
}
//查询人员姓名/职级/职位
StringBuilder sb = new StringBuilder();
List<Map<String, Object>> userNameByDept = getUserinfoByDept(id);
if(CollectionUtils.isNotEmpty(userNameByDept)){
for (Map<String, Object> map : userNameByDept) {
String userId = String.valueOf(map.get("id"));
String userName = String.valueOf(map.get("username"));
String jobset_level = String.valueOf(map.get("jobset_level"));
//职级
//String jobsetLevel = USERINFO_Level_MAP.get(jobset_level);
String jobsetLevel = Optional.ofNullable(USERINFO_Level_MAP)
.map(map1 -> map1.getOrDefault(jobset_level, ""))
.orElse("");
//职位
//String zw = USERINFO_ZW_MAP.get(userId);
String zw = Optional.ofNullable(USERINFO_ZW_MAP)
.map(map1 -> map1.getOrDefault(userId, ""))
.orElse("");
// 格式化当前人员信息
String personInfo = String.format("姓名:%s、职级%s、职位%s",
userName, jobsetLevel, zw);
// 非首条数据添加分隔符
if (sb.length() > 0) {
sb.append(",");
}
sb.append(personInfo);
}
}
//StringBuilder sb = new StringBuilder();
//List<Map<String, Object>> userNameByDept = getUserinfoByDept(id);
// if(CollectionUtils.isNotEmpty(userNameByDept)){
// for (Map<String, Object> map : userNameByDept) {
// String userId = String.valueOf(map.get("id"));
// String userName = String.valueOf(map.get("username"));
// String jobset_level = String.valueOf(map.get("jobset_level"));
// //职级
// //String jobsetLevel = USERINFO_Level_MAP.get(jobset_level);
// String jobsetLevel = Optional.ofNullable(USERINFO_Level_MAP)
// .map(map1 -> map1.getOrDefault(jobset_level, ""))
// .orElse("");
// //职位
// //String zw = USERINFO_ZW_MAP.get(userId);
// String zw = Optional.ofNullable(USERINFO_ZW_MAP)
// .map(map1 -> map1.getOrDefault(userId, ""))
// .orElse("");
// // 格式化当前人员信息
// String personInfo = String.format("姓名:%s、职级%s、职位%s",
// userName, jobsetLevel, zw);
//
// // 非首条数据添加分隔符
// if (sb.length() > 0) {
// sb.append(",");
// }
// sb.append(personInfo);
// }
// }
/**
* 在这里拼接参数包括部门的岗位的222
*/
//1.部门参数
// 步骤1拼接下层字符串
// String lowerStr = positionCount + "/" + estCount;
// String name1 = String.valueOf(objectMap.get("name"));
// // 步骤2计算上层和下层的字符串长度
// int deptNameLen = name1.length();
// int lowerStrLen = lowerStr.length();
// // 步骤3计算居中缩进的空格数向下取整若长度差为奇数会轻微偏左+1调整
// int indentSpace = (deptNameLen - lowerStrLen) / 2;
// // 步骤4生成缩进空格Java 8可用String.join生成重复空格
// String indent = String.join("", java.util.Collections.nCopies(indentSpace, " "));
// // 步骤5拼接最终结果
// String resultdept = String.format("%s%n%s%s", name1, indent, lowerStr);
// //deft.setId(id2);
//deft.setName(resultdept);
//deft.setParent_id(String.valueOf(objectMap.get("parent")));
// 计算remark
String remark = String.format("部门编制数:%d\n部门在岗人数%d\n部门缺编数%d\n岗位%s\n人员%s",
estCount,
positionCount,
estLackCount,
joiner.toString(),
sb.toString());
log.error("XmindDataFilterCmd.remark222:{}", remark);
// String remark = String.format("部门编制数:%d\n部门在岗人数%d\n部门缺编数%d\n岗位%s\n人员%s",
// estCount,
// positionCount,
// estLackCount,
// joiner.toString(),
// sb.toString());
// log.error("XmindDataFilterCmd.remark222:{}", remark);
// if (estLackCount >0) {
// remark += "\n缺编" + (estLackCount);
// }
// if (estOverCount >0) {
// remark += "\n超编" + (estOverCount);
// }
deft.setRemark(remark);
if((estLackCount >0) || (estOverCount >0)){
deft.setBgColor("#F1F1F1");
}
//deft.setRemark(remark);
// if((estLackCount >0) || (estOverCount >0)){
// deft.setBgColor("#B0E0E6");// 粉末蓝
// }
defts2.add(deft);
}
//3.组装
@ -405,11 +517,150 @@ public class XmindDataFilterCmd extends RegHookEvent {
return response;
}
/**
* 拼接岗位信息为3层居中对齐的字符串
* @param gwName 岗位名称可为null默认"未知岗位"
* @param countGw 岗位人数
* @param estCountGw 编制数
* @param empNames 人员姓名列表可为null/无人员时不显示该层
* @return 3层居中对齐的拼接字符串
*/
// public static String formatGwInfo(String gwName, int countGw, int estCountGw, List<String> empNames) {
// // 1. 处理岗位名称空值兜底默认值
// String safeGwName = Objects.isNull(gwName) || gwName.trim().isEmpty() ? "未知岗位" : gwName.trim();
// // 2. 拼接第2层内容人数/编制数
// String layer2Str = countGw + "/" + estCountGw;
// // 3. 计算第1层岗位名称长度
// int layer1Len = safeGwName.length();
//
// // 4. 处理第2层计算居中缩进 + 拼接内容
// int layer2Len = layer2Str.length();
// int layer2Indent = (layer1Len - layer2Len) / 2; // 第2层相对于第1层的居中缩进
// String layer2IndentSpace = getIndentSpace(layer2Indent);
// String layer2Content = layer2IndentSpace + layer2Str;
//
// // 5. 处理第3层人员姓名列表每行一个居中对齐
// StringBuilder layer3Content = new StringBuilder();
// if (Objects.nonNull(empNames) && !empNames.isEmpty()) {
// // 遍历姓名列表每个姓名单独一行相对于第1层居中
// String layer3Lines = empNames.stream()
// .map(name -> {
// String safeName = Objects.isNull(name) ? "未知人员" : name.trim();
// int nameLen = safeName.length();
// int nameIndent = (layer1Len - nameLen) / 2; // 单个姓名的居中缩进
// return getIndentSpace(nameIndent) + safeName;
// })
// .collect(Collectors.joining("\n")); // 姓名间换行分隔
// layer3Content.append("\n").append(layer3Lines); // 拼接第3层先换行
// }
//
// // 6. 拼接所有层层间换行
// return String.format("%s%n%s%s", safeGwName, layer2Content, layer3Content);
// }
public static String formatGwInfo(String gwName, int countGw, int estCountGw, List<String> empNames) {
// 1. 岗位名称空值兜底 + 去首尾空格核心基准值
String safeGwName = StringUtils.isBlank(gwName) ? "未知岗位" : gwName.trim();
int layer1Len = safeGwName.length(); // 基准长度所有层级对齐的核心
if (layer1Len == 0) { // 极端边界兜底
safeGwName = "未知岗位";
layer1Len = 4;
}
// 2. 拼接编制人数层count/编制核心修复统一缩进计算逻辑
String layer2Str = countGw + "/" + estCountGw;
int layer2Indent = (layer1Len - layer2Str.length()) / 2;
String layer2Content = getIndentSpace(Math.max(layer2Indent, 0)) + layer2Str; // 缩进0避免负数
// 3. 拼接人员姓名层统一换行符 + 可选去重 + 精准居中核心修复换行/重复问题
StringBuilder layer3Content = new StringBuilder();
if (Objects.nonNull(empNames) && !empNames.isEmpty()) {
// 流式处理空值兜底 + 去重 + 居中缩进一步到位
int finalLayer1Len = layer1Len;
String layer3Lines = empNames.stream()
.filter(StringUtils::isNotBlank) // 过滤空字符串/纯空格姓名
.map(name -> StringUtils.isBlank(name) ? "未知人员" : name.trim()) // 姓名空值兜底
.distinct() // 核心自动去重开启开关后生效
.map(safeName -> {
int nameLen = safeName.length();
int nameIndent = (finalLayer1Len - nameLen) / 2;
return getIndentSpace(Math.max(nameIndent, 0)) + safeName; // 缩进0
})
.collect(Collectors.joining(System.lineSeparator())); // 核心统一用系统标准换行符
if (StringUtils.isNotBlank(layer3Lines)) {
// 仅在有人员数据时拼接单个标准换行杜绝多余换行导致的重复
layer3Content.append(System.lineSeparator()).append(layer3Lines);
}
}
// 4. 最终拼接统一用系统标准换行符三层内容严格分离无重复拼接
// 核心修复用System.lineSeparator()替代%n和\n全环境统一换行
return safeGwName +
System.lineSeparator() +
layer2Content +
layer3Content;
}
// // 工具方法生成指定数量的空格缩进专用性能优化版
// private String getIndentSpace(int indentNum) {
// if (indentNum <= 0) {
// return "";
// }
// return StringUtils.repeat(" ", indentNum);
// }
/**
* 生成指定数量的缩进空格Java 8实现
* @param indentCount 缩进空格数负数时返回空字符串
* @return 缩进空格字符串
*/
private static String getIndentSpace(int indentCount) {
if (indentCount <= 0) {
return "";
}
// Java 8生成重复空格Collections.nCopies + String.join
return String.join("", Collections.nCopies(indentCount, " "));
}
@Override
public void rollBack(WeaHookRequest request, WeaHookResponse response, AppInfo appInfo) throws Exception {
}
// 部门岗位映射转换String部门ID -> Long部门ID
public static Map<Long, List<Map<String, Object>>> convertDeptPositions(
Map<String, List<Map<String, Object>>> deptPositionMap) {
return deptPositionMap.entrySet().stream()
.filter(entry -> entry.getKey() != null && !entry.getKey().isEmpty())
.collect(Collectors.toMap(
entry -> parseToLongSafely(entry.getKey(), "部门ID"),
Map.Entry::getValue
));
}
// 岗位人员映射转换String岗位ID -> Long岗位ID
public static Map<Long, List<Map<String, Object>>> convertPositionPersons(
Map<String, List<Map<String, Object>>> positionEmpMap) {
return positionEmpMap.entrySet().stream()
.filter(entry -> entry.getKey() != null && !entry.getKey().isEmpty())
.collect(Collectors.toMap(
entry -> parseToLongSafely(entry.getKey(), "岗位ID"),
Map.Entry::getValue
));
}
// 安全类型转换方法带错误日志
private static Long parseToLongSafely(String idStr, String type) {
try {
return Long.parseLong(idStr);
} catch (NumberFormatException e) {
log.error("警告: 无法将%s(%s)转换为Long类型\n", type, idStr);
return null; // 转换失败返回null后续collect方法会自动过滤
}
}
/**
* 塞入节点
* @param departments
@ -417,6 +668,13 @@ public class XmindDataFilterCmd extends RegHookEvent {
*/
public Node buildDepartmentTree(List<Deft> departments) {
log.error("XmindDataFilterCmd.departments:{}", departments);
Map<Long, List<Map<String, Object>>> deptPositions = convertDeptPositions(DEPT_POSITION_MAP);
/**
* 这里传一个空的岗位人员不拼接岗位下级人员了
*/
Map<Long, List<Map<String, Object>>> positionPersons = convertDeptPositions(POSITION_EMP_MAP);
log.error("XmindDataFilterCmd.deptPositions:{}", deptPositions);
log.error("XmindDataFilterCmd.positionPersons:{}", positionPersons);
// 创建ID到Node的映射
Map<String, Node> nodeMap = new HashMap<>();
List<Node> rootCandidates = new ArrayList<>(); // 记录无父节点的节点
@ -455,8 +713,79 @@ public class XmindDataFilterCmd extends RegHookEvent {
// 处理最终根节点选择
Node node = resolveRootNode(rootCandidates);
log.error("buildDepartmentTree.rootCandidates:{}", node);
// 递归遍历部门树为叶子部门节点添加岗位及人员
traverseAndInjectPositions(node, deptPositions, positionPersons);
return node;
}
// 岗位节点创建方法适配Map数据
public static Node createPositionNode(Map<String, Object> positionMap) {
return new Node()
.setId(getLongValue(positionMap, "id"))
.setName(getStringValue(positionMap, "name"))
.setType("position")
.setChildren(new ArrayList<>());
}
// 人员节点创建方法适配Map数据
public static Node createPersonNode(Map<String, Object> personMap) {
return new Node()
.setId(getLongValue(personMap, "id"))
.setName(getStringValue(personMap, "name"))
.setType("person");
}
// 辅助方法安全获取Long值
private static Long getLongValue(Map<String, Object> map, String key) {
return map.containsKey(key) ?
Long.parseLong(map.get(key).toString()) : null;
}
// 辅助方法安全获取String值
private static String getStringValue(Map<String, Object> map, String key) {
return map.containsKey(key) ?
map.get(key).toString() : "";
}
private void traverseAndInjectPositions(Node node,
Map<Long, List<Map<String, Object>>> deptPositions,
Map<Long, List<Map<String, Object>>> positionPersons) {
// 处理叶子部门节点
if ("department".equals(node.getType()) && (node.getChildren() == null || node.getChildren().isEmpty())) {
// 获取该部门岗位列表注意类型已变为List<Map>
List<Map<String, Object>> positions = deptPositions.get(node.getId());
if (positions != null) {
for (Map<String, Object> posMap : positions) {
// 创建岗位节点
Node posNode = createPositionNode(posMap);
// 获取岗位下人员列表
// List<Map<String, Object>> persons =
// positionPersons.get(posNode.getId()); // 通过岗位ID获取人员
// if (persons != null) {
// for (Map<String, Object> perMap : persons) {
// // 创建人员节点并添加到岗位节点
// posNode.getChildren().add(
// createPersonNode(perMap)
// );
// }
// }
// 将岗位节点添加到部门节点
node.getChildren().add(posNode);
}
}
}
// 递归处理非叶子部门
else if (node.getChildren() != null) {
for (Node child : node.getChildren()) {
traverseAndInjectPositions(child, deptPositions, positionPersons);
}
}
}
// 判断是否为根节点
private boolean isRootNode(String parentId) {
return parentId == null
@ -513,7 +842,7 @@ public class XmindDataFilterCmd extends RegHookEvent {
* 查询所有部门
*/
private List<Map<String,Object>> getAllDepartments(){
String sql="select id,name,parent from eteams.department where 1=1";
String sql="select id,name,parent from eteams.department where 1=1 and virtualid = '1' ";
log.error("getAllDept.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
@ -606,7 +935,7 @@ public class XmindDataFilterCmd extends RegHookEvent {
// 执行SQL查询
String sql = "SELECT p.id AS dept_id, COUNT(e.id) AS employee_count FROM eteams.department\n" +
"p LEFT JOIN eteams.employee e ON p.id = e.department WHERE p.TENANT_KEY = 't024j0gfn0'\n" +
"AND p.is_delete = '0' GROUP BY p.id ";
"AND p.is_delete = '0' and e.PERSONNEL_STATUS = 3 GROUP BY p.id ";
// 获取原始结果集
log.error("initializeDeptEmployeeCount.sql:{}", sql);
@ -657,6 +986,43 @@ public class XmindDataFilterCmd extends RegHookEvent {
log.error("initializePositionEmployeeCount.POSITION_EMPLOYEE_COUNT_MAP:{}", POSITION_EMPLOYEE_COUNT_MAP);
}
/**
* 根据岗位获取岗位人员姓名
* @return
*/
public void initializePositionEmployee() {
POSITION_EMP_MAP.clear();
// 执行SQL查询
String sql = "SELECT p.id AS position_id, e.id,e.username as name " +
"FROM eteams.position p " +
"LEFT JOIN eteams.employee e ON p.id = e.position " +
"WHERE p.TENANT_KEY = 't024j0gfn0' " +
"AND p.is_delete = '0' " +
"AND (p.delete_type = '0' OR p.delete_type IS NULL) " +
"AND p.is_canceled = '0' and e.username is not null and e.PERSONNEL_STATUS = 3 " +
"GROUP BY p.id";
// 获取原始结果集
log.error("initializePositionEmployeeCount.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("initializePositionEmployeeCount.recordList:{}", recordList);
// 按部门ID分组Java 8 Stream
Map<String, List<Map<String, Object>>> tempMap = recordList.stream()
.filter(row -> row.get("position_id") != null)
.collect(Collectors.groupingBy(
row -> String.valueOf(row.get("position_id")),
ConcurrentHashMap::new,
Collectors.toList()
));
// 更新全局映射
POSITION_EMP_MAP.putAll(tempMap);
log.error("initialize.POSITION_EMP_MAP:{}", POSITION_EMP_MAP);
}
/**
* 初始化人员职级
* @return
@ -786,7 +1152,7 @@ public class XmindDataFilterCmd extends RegHookEvent {
")\n" +
"AND p.is_canceled = '0'\n" +
"and pdl.delete_type = 0\n" +
"and pdl.department_id in (select id from eteams.department where 1=1) ";
"and pdl.department_id in (select id from eteams.department where 1=1 and virtualid = '1') ";
log.error("initialize.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);

View File

@ -0,0 +1,231 @@
package com.weaver.seconddev.jcl.organization.esb.zkd;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import com.weaver.seconddev.jcl.organization.util.RecruitModuleUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* @use人员卡片数据同步到导师名录
* @date 2025年10月31日
* @author xuxy
*/
@Service("SyncDsmlInfo_zkd")
public class SyncDsmlInfo implements EsbServerlessRpcRemoteInterface {
@Autowired
private DatabaseUtils databaseUtils;
@Autowired
RecruitModuleUtils recruitModuleUtils;
private static final Logger log = LoggerFactory.getLogger(SyncDsmlInfo.class);
// 定义常量分组Java 8兼容写法
private static final Set<String> GROUP_2345 = new HashSet<>(Arrays.asList(
"1175819959708491776",
"1175819963869241516",
"1175819976972247465"
));
private static final Set<String> GROUP_45 = new HashSet<>(Arrays.asList(
"1175819963869241349",
"1175819976972247549",
"1175819976972247717"
));
@Override
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
log.error("SyncDsmlInfo.start:"+"11111111");
log.error("SyncDsmlInfo.GROUP_2345:"+GROUP_2345);
log.error("SyncDsmlInfo.GROUP_45:"+GROUP_45);
/**
* 1.查询到原数据
*/
List<Map<String, Object>> dsmlInfo = getDsmlInfo();
//log.error("SyncDsmlInfo.dsmlInfoSize:"+dsmlInfo.size());
/**
* 2.根据position增加zsfw
*/
processDsmlInfo(dsmlInfo);
log.error("processDsmlInfo.dsmlInfo222:"+dsmlInfo);
/**
* 3.将查询原数据插入到导师名录eb表中/写入表单引擎数据大表
*/
insertDsml(dsmlInfo);
log.error("SyncDsmlInfo.result:"+result);
return WeaResult.success(result);
}
// public static void main(String[] args) {
// List<Map<String, Object>> dsmlInfo = new ArrayList<>();
// Map<String, Object> map = new HashMap<>();
// map.put("id","1130926169645793287");
// map.put("position","111");
// map.put("department","1127665787032453134");
// map.put("email","linyue@ustc.edu.cn");
// map.put("username","林岳");
//
// Map<String, Object> map1 = new HashMap<>();
// map1.put("id","1130926169645793306");
// map1.put("position","222");
// map1.put("department","1127665709882425381");
// map1.put("email","linyue@ustc.edu.cn");
// map1.put("username","郭昌");
//
// Map<String, Object> map2 = new HashMap<>();
// map2.put("id","1130926212830347514");
// map2.put("position","333");
// map2.put("department","1127665520794812442");
// map2.put("email","linyue@ustc.edu.cn");
// map2.put("username","葛亮");
// dsmlInfo.add(map);
// dsmlInfo.add(map1);
// dsmlInfo.add(map2);
// processDsmlInfo(dsmlInfo);
// }
public static void processDsmlInfo(List<Map<String, Object>> dsmlInfo) {
log.error("processDsmlInfo.dsmlInfo000:"+dsmlInfo);
for (Map<String, Object> map : dsmlInfo) {
String position = Optional.ofNullable(map.get("position"))
.map(Object::toString)
.orElse("");
if ("1175819959708491776".equals(position)||
"1175819963869241516".equals(position)||
"1175819976972247465".equals(position)) {
map.put("zsfw", "2,3,4,5");
} else if ("1175819963869241349".equals(position)||
"1175819976972247549".equals(position)||
"1175819976972247717".equals(position)) {
map.put("zsfw", "4,5");
} else {
map.put("zsfw", "");
}
}
}
/**
* 写入导师名录eb表
* @return
*/
public void insertDsml(List<Map<String, Object>> dsmlInfo){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化时间
String formattedDateTime = now.format(formatter);
/**
* 插入前先删除导师名录表数据
*/
String str = "update uf_dsml set is_delete=1,delete_type=1 where sjly = 0 ";
Map<String, Object> rt = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", str);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rt);
log.error("insertDsml.recordList:{}", recordList);
for (Map<String, Object> map : dsmlInfo) {
// 生成随机 ID
long formuserdataid = IdGenerator.generate();
log.error("insertDsml.formuserdataid:"+formuserdataid);
// 使用Optional进行空值安全处理
String id = Optional.ofNullable(map.get("id"))
.map(Object::toString)
.orElse("");
String username = Optional.ofNullable(map.get("username"))
.map(Object::toString)
.orElse("");
String department = Optional.ofNullable(map.get("department"))
.map(Object::toString)
.orElse("");
String email = Optional.ofNullable(map. get("email"))
.map(Object::toString)
.orElse("");
String position = Optional.ofNullable(map.get("position"))
.map(Object::toString)
.orElse("");
String zsfw = Optional.ofNullable(map.get("zsfw"))
.map(Object::toString)
.orElse("");
String sql="insert into uf_dsml(id,form_data_id,data_index,create_time,creator,updater,TENANT_KEY,is_flow,data_status,xm,glry,xy,yx,gw,zsfw,sjly) " +
" values('"+formuserdataid+"','"+formuserdataid+"',0.0,'"+formattedDateTime+"','1103415980721364998','1103415980721364998','txk4srsbcd',0,1," +
" '"+username+"','"+id+"','"+department+"','"+email+"','"+position+"','"+zsfw+"','0') ";
log.error("insertDsml.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
/**
* 写入表单引擎数据大表
*/
String stf="insert into formdata(id, form_id, layout_id, data_status, tenant_key, operator, create_time, update_time, " +
" module, client, is_delete, creator, delete_type)" +
" values('" + formuserdataid + "','1177631276257845249','1177631276257845321','submit','txk4srsbcd','1103415980721364998','" + formattedDateTime + "'," +
" '" + formattedDateTime + "','ebuilderform','pc','0','1103415980721364998','0')";
log.error("insertFormdata.sql:{}", stf);
Map<String, Object> ry = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", stf);
//List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
//log.error("insertDsml.recordList:{}", recordList);
}
}
/**
* 写入表单引擎数据大表
* @return
*/
public void insertFormdata(List<Map<String, Object>> dsmlInfo){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器格式为yyyy-MM-dd HH:mm:ss
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化时间
String formattedDateTime = now.format(formatter);
log.error("insertFormdata.formattedDateTime:{}", formattedDateTime);
for (Map<String, Object> map : dsmlInfo) {
String sql="insert into formdata(id, form_id, layout_id, data_status, tenant_key, operator, create_time, update_time, " +
" module, client, is_delete, creator, delete_type)" +
" values('" + map.get("id") + "','1177631276257845249','1177631276257845321','submit','txk4srsbcd','1103415980721364998','" + formattedDateTime + "'," +
" '" + formattedDateTime + "','ebuilderform','pc','0','1103415980721364998','0')";
log.error("insertFormdata.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
}
//List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
//log.error("insertFormdata.recordList:{}", recordList);
}
/**
* 写入EB表单数据大表
* @return
*/
public void insertPhysical(Map<String, Object> map,String obj_id){
String sql="insert into ebdf_physical_data(id, tenant_key, obj_id, name, form_data_id, form_table_id, is_flow, data_status, creator, create_time)" +
" values('" + map.get("id") + "','" + map.get("tenant_key") + "','" + obj_id + "','" + map.get("name") + "','" + map.get("id") + "'," +
" '" + map.get("id") + "','" + map.get("is_flow") + "','" + map.get("data_status") + "','" + map.get("creator") + "','" + map.get("create_time") + "')";
log.error("insertPhysical.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("insertPhysical.recordList:{}", recordList);
}
/**
* 全量人员信息中筛选出符合条件的岗位人员数据
* @return
*/
public List<Map<String, Object>> getDsmlInfo(){
//String sql = "select * from eteams.position where name in('教授','研究员','特任教授','副教授','特任研究员','特任正高级工程师')";
String sql = " select id,username,department,email,position from eteams.employee where position \n" +
" in(1175819959708491776,1175819963869241349,1175819963869241516,1175819976972247465,1175819976972247549,1175819976972247717)";
log.error("getDsmlInfo.sql:{}", sql);
Map<String, Object> rs = databaseUtils.execute("LOGIC", "weaver-ebuilder-form-service", sql);
List<Map<String, Object>> recordList = databaseUtils.getDataSourceList(rs);
log.error("getDsmlInfo.recordList:{}", recordList);
return recordList;
}
}

View File

@ -0,0 +1,203 @@
package com.weaver.seconddev.jcl.organization.esb.zkd;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.weaver.common.base.entity.result.WeaResult;
import com.weaver.common.distribution.genid.IdGenerator;
import com.weaver.common.ei.utils.Util;
import com.weaver.common.mybatis.sqlinjection.interceptor.StringUtil;
import com.weaver.ebuilder.common.exception.BusinessException;
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
import com.weaver.seconddev.jcl.organization.esb.zkd.entity.ApiResponse;
import com.weaver.seconddev.jcl.organization.esb.zkd.entity.UserData;
import com.weaver.seconddev.jcl.organization.esb.zkd.util.HttpUtil;
import com.weaver.seconddev.jcl.organization.esb.zkd.util.PapiUtil;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* @use同步聘期制人员
* @date 2025年11月12日
* @author xuxy
*/
@Service("SyncTermBasedPerson_zkd")
public class SyncTermBasedPerson implements EsbServerlessRpcRemoteInterface {
@Autowired
private DatabaseUtils databaseUtils;
@Autowired
private HttpUtil httpUtil;
private static final Logger log = LoggerFactory.getLogger(SyncTermBasedPerson.class);
private static final ObjectMapper mapper = new ObjectMapper();
private static String baseUrl = "https://dcm.ustc.edu.cn";
private static String tokenPath = "/open_api/authentication/get_access_token";
private static String employeeInfoPath = "/open_api/customization/tgxggfwdzzcyhxx/full";
@Override
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
Map<String, Object> result = new HashMap<>();
log.error("SyncTermBasedPerson.start:"+"11111111");
/**
* 1获取token
*/
try {
String json11 = httpUtil.callGetApi(baseUrl, tokenPath, "20250421259519141525246261411841844", "f3603149693d172fc2e0de6b6818a2a2ddc9048c");
log.error("ZkdGetInfoController.json:"+json11);
log.debug("Token响应: {}", json11);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json11);
String accessToken = "";
// 校验业务状态码
if (root.get("code").asInt() != 10000) {
String errMsg = String.format("三方接口错误 [%d]: %s",
root.get("code").asInt(),
root.get("message").asText()
);
log.error(errMsg);
throw new BusinessException(errMsg);
}
// 3. 提取access_token带空值校验
JsonNode resultNode = root.get("result");
if (resultNode == null || resultNode.isEmpty()) {
log.error("三方接口响应结构异常: result节点为空");
throw new BusinessException("三方接口返回无效的result结构");
}
accessToken = resultNode.get("access_token").asText();
log.info("获取Token成功: {}", accessToken);
/**
* 2.根据accessToken获取电子注册用户信息
*/
String resultInfo = httpUtil.callPostApi(baseUrl, employeeInfoPath, "", accessToken);
log.error("ZkdGetInfoController.resultInfo:"+resultInfo);
List<UserData> users = parseUserData(resultInfo);
log.error("ZkdGetInfoController.users:"+users);
result.put("users",users);
/**
* 3.根据返回的电子注册用户信息在自身系统创建人员账号
*/
syncEmployeeInfo(users);
} catch (Exception e) {
e.printStackTrace();
}
log.error("SyncDsmlInfo.result:"+result);
return WeaResult.success(result);
}
// 直接解析JSON获取用户数据列表
public static List<UserData> parseUserData(String jsonResponse) throws Exception {
ApiResponse response = mapper.readValue(jsonResponse, ApiResponse.class);
// 验证业务状态码可选
if (!"10000".equals(response.getCode())) {
throw new IllegalStateException("业务错误: " + response.getMessage());
}
return response.getResult().getData(); // 直接返回data列表
}
/**
* 同步员工信息
*/
private void syncEmployeeInfo(List<UserData> users) {
log.error("syncEmployeeInfo runnint");
String e10code = PapiUtil.getCode();
String e10accessToken = PapiUtil.getAccessToken(e10code);
//同步人员数据结构
JSONArray datalist = new JSONArray();
for (UserData user : users) {
JSONObject obj = new JSONObject();
//姓名
String username = Util.null2String(user.getYhxm());
//邮箱
String email = Util.null2String(user.getDzyx());
//主要邮箱
String mainMmail = Util.null2String(user.getZyyx());
if(StringUtils.isNotBlank(mainMmail)){
email = mainMmail;
}
//人员分类码
String ryfl = Util.null2String(user.getRyflm());
if(("180030000".equals(ryfl)||"180040000".equals(ryfl))&&StringUtils.isNotBlank(email)){
//手机号
//String mobile = Util.null2String(dataobj.get("sjh"));
//办公电话
// telephone = Util.null2String(dataobj.get("bgdh"));
//性别malefemale
// String sex = Util.null2String(dataobj.get("xbm"));
// if ("1".equals(sex)) {
// sex = "male";
// } else {
// sex = "female";
// }
//工号
String job_num = Util.null2String(user.getXgh());
//入职日期
// String hiredate = Util.null2String(dataobj.get("jxrq"));
//部门所属组织
//String department = Util.null2String(dataobj.get("dwbm"));
//状态1:试用2:试用延期3:正式4:临时;5:实习;6:离职;7:退休
//String personnel_status = "3";
//身份证
//String id_no = Util.null2String(dataobj.get("sfzjh"));
//籍贯
// String jg = Util.null2String(dataobj.get("jg"));
//账号
// String account = "";
// if(StringUtils.isNotBlank(mobile)){
// account = mobile;
// }else if(StringUtils.isNotBlank(email)){
// account = email;
// }else{
// continue;
// }
// String loginid = Util.null2String(dataobj.get("gid"));
//
// String password = "1";
obj.put("username", username);//必须 todo
obj.put("email", email);
//obj.put("mobile", mobile);
//obj.put("telephone", telephone);
//obj.put("sex", sex);
obj.put("job_num", job_num);
//obj.put("department", department);//必须 todo
obj.put("personnel_status", "1");//必须 todo
//obj.put("id_no", id_no);
// obj.put("account", account);
// obj.put("loginid", loginid);
// obj.put("password", password);
//obj.put("userInfoExtend", userInfoExtend);
// obj.put("employeeExtend", employeeExtend);
datalist.add(obj);
}
}
//调用接口平台 标准接口
Map<String, Object> params = new HashMap<>(10);
JSONObject dataRule = new JSONObject(10);//规则必须 todo
dataRule.put("department", "code");
dataRule.put("employee", "job_num");
params.put("data", datalist);
params.put("dataRule", dataRule);
PapiUtil.syncEmployee(e10accessToken, params);
}
}

View File

@ -0,0 +1,119 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.weaver.common.authority.annotation.WeaPermission;
import com.weaver.ebuilder.common.exception.BusinessException;
import com.weaver.seconddev.jcl.organization.esb.zkd.entity.ApiResponse;
import com.weaver.seconddev.jcl.organization.esb.zkd.entity.UserData;
import com.weaver.seconddev.jcl.organization.esb.zkd.util.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api/secondev/jcl/zkdGetInfo")
public class ZkdGetInfoController {
@Autowired
private HttpUtil httpUtil;
private static final Logger log = LoggerFactory.getLogger(ZkdGetInfoController.class);
private static final ObjectMapper mapper = new ObjectMapper();
private static String baseUrl = "https://dcm.ustc.edu.cn";
private static String tokenPath = "/open_api/authentication/get_access_token";
private static String employeeInfoPath = "/open_api/customization/tgxggfwdzzcyhxx/full";
/**
* 二开测试接口
* @return
*/
@GetMapping("/test")
@WeaPermission(publicPermission = true)
public String secondTest(@RequestParam("name") String name){
log.error("secondTest.name:{}",name);
return name ;
}
/**
* 获取三方接口信息
* @return
*/
@GetMapping("/syncTermBasedPerson")
@WeaPermission(publicPermission = true)
public List<UserData> syncTermBasedPerson(){
log.error("ZkdGetInfoController.start:"+"11111111");
log.error("ZkdGetInfoController.httpUtil:"+httpUtil);
List<UserData> users = new ArrayList<>();
/**
* 1获取token
*/
try {
log.error("ZkdGetInfoController.baseUrl:"+baseUrl);
log.error("ZkdGetInfoController.tokenPath:"+tokenPath);
log.error("ZkdGetInfoController.clientId:"+"20250421259519141525246261411841844");
log.error("ZkdGetInfoController.clientSecret:"+"f3603149693d172fc2e0de6b6818a2a2ddc9048c");
String json11 = httpUtil.callGetApi(baseUrl, tokenPath, "20250421259519141525246261411841844", "f3603149693d172fc2e0de6b6818a2a2ddc9048c");
log.error("ZkdGetInfoController.json:"+json11);
log.debug("Token响应: {}", json11);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json11);
String accessToken = "";
// 校验业务状态码
if (root.get("code").asInt() != 10000) {
String errMsg = String.format("三方接口错误 [%d]: %s",
root.get("code").asInt(),
root.get("message").asText()
);
log.error(errMsg);
throw new BusinessException(errMsg);
}
// 3. 提取access_token带空值校验
JsonNode resultNode = root.get("result");
if (resultNode == null || resultNode.isEmpty()) {
log.error("三方接口响应结构异常: result节点为空");
throw new BusinessException("三方接口返回无效的result结构");
}
accessToken = resultNode.get("access_token").asText();
log.info("获取Token成功: {}", accessToken);
/**
* 2.根据accessToken获取电子注册用户信息
*/
String resultInfo = httpUtil.callPostApi(baseUrl, employeeInfoPath, "", accessToken);
log.error("ZkdGetInfoController.resultInfo:"+resultInfo);
users = parseUserData(resultInfo);
log.error("ZkdGetInfoController.users:"+users);
/**
* 3.根据返回的电子注册用户信息在自身系统创建人员账号
*/
} catch (Exception e) {
log.error("接口调用异常 - URL: {} PATH: {}", baseUrl, tokenPath, e); // 记录完整堆栈到日志
// 可选抛出封装后的业务异常
throw new BusinessException("三方接口调用失败", e);
}
return users;
}
// 直接解析JSON获取用户数据列表
public static List<UserData> parseUserData(String jsonResponse) throws Exception {
ApiResponse response = mapper.readValue(jsonResponse, ApiResponse.class);
log.error("parseUserData.response:"+response);
// 验证业务状态码可选
if (!"10000".equals(response.getCode())) {
throw new IllegalStateException("业务错误: " + response.getMessage());
}
return response.getResult().getData(); // 直接返回data列表
}
}

View File

@ -0,0 +1,28 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiResponse {
@JsonProperty("code")
private String code;
@JsonProperty("description")
private String description;
@JsonProperty("message")
private String message;
@JsonProperty("result")
private Result result;
@JsonProperty("uuid")
private String uuid;
}

View File

@ -0,0 +1,40 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Result {
@JsonProperty("data")
private List<UserData> data; // 核心数据列表
@JsonProperty("data_struct")
private Map<String, String> data_struct;
@JsonProperty("encrypted_field")
private String encrypted_field;
@JsonProperty("max_page")
private int max_page;
@JsonProperty("page")
private int page;
@JsonProperty("per")
private int per;
@JsonProperty("per_page")
private int per_page;
@JsonProperty("total")
private int total;
@JsonProperty("water_mark")
private int water_mark;
}

View File

@ -0,0 +1,44 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* uf_jcl_employee_information
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserData {
@JsonProperty("wybs")
private String wybs; // 唯一标识
@JsonProperty("yhgid")
private String yhgid; // 用户GID
@JsonProperty("xgh")
private String xgh; // 学工号
@JsonProperty("yhxm")
private String yhxm; // 用户姓名
@JsonProperty("zsfid")
private String zsfid; // 主身份ID
@JsonProperty("dzyx")
private String dzyx; // 电子邮箱
@JsonProperty("dzyxqrzt")
private String dzyxqrzt;// 邮箱确认状态
@JsonProperty("zyyx")
private String zyyx; // 主要邮箱
@JsonProperty("cjsj")
private String cjsj; // 创建时间
@JsonProperty("gxsj")
private String gxsj; // 更新时间
@JsonProperty("tstamp")
private String tstamp; // 时间戳
@JsonProperty("ryglflm")
private String ryglflm; // 人员管理分类码
@JsonProperty("ryflm")
private String ryflm; // 人员分类码
}

View File

@ -0,0 +1,892 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.util;
import okhttp3.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* http请求工具类
*
* @author wangj
* @version 1.00版本
* @Date 2025-4-24
*/
public class HttpCilentUtil {
private static final Logger logger = LoggerFactory.getLogger(HttpCilentUtil.class);
/**
* post请求 xml格式带请求头
*
* @param httpurl
* @param header
* @param xmlPayload
* @return
*/
public static String postXmlRequestHeader(String httpurl, Map<String, String> header, String xmlPayload) {
String result = "";
try {
// 接口的 URL
URL url = new URL(httpurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法为 POST
connection.setRequestMethod("POST");
// 设置请求头
connection.setRequestProperty("Content-Type", "application/xml");
if (header != null) {
for (String key : header.keySet()) {
connection.setRequestProperty(key, header.get(key));
}
}
// 允许输出
connection.setDoOutput(true);
byte[] input = xmlPayload.getBytes(StandardCharsets.UTF_8);
// 写入 XML 数据
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(input);
}
// 获取响应码
int responseCode = connection.getResponseCode();
// 读取响应
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
result = response.toString();
}
} catch (Exception e) {
logger.error("postXmlRequestHeader Exception:" + e.getMessage());
}
return result;
}
/**
* 带参数的get请求
*
* @param url
* @param param
* @return String
*/
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
// if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 不带参数的get请求
*
* @param url
* @return String
*/
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPostFile(String url, File file, String fileName, String token) {
String resultString = "";
// 创建 HttpClient 实例
HttpClient httpClient = HttpClients.createDefault();
// 创建 HttpPost 请求
HttpPost httpPost = new HttpPost(url);
try {
// 在请求头中添加 token
httpPost.addHeader("Authorization", "bearer " + token);
// 创建 MultipartEntityBuilder 用于构建 multipart/form-data 请求体
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// 添加文件参数
FileBody fileBody = new FileBody(file);
builder.addPart("file", fileBody);
// 添加普通文本参数
builder.addTextBody("fileName", fileName, ContentType.TEXT_PLAIN.withCharset("UTF-8"));
// 构建请求实体
HttpEntity multipart = builder.build();
httpPost.setEntity(multipart);
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
// 获取响应实体
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
// 打印响应内容
resultString = EntityUtils.toString(responseEntity);
}
} catch (IOException e) {
System.out.println("IOException:" + e.getMessage());
e.printStackTrace();
} finally {
// 释放连接
httpPost.releaseConnection();
}
return resultString;
}
/**
* 带参数的post请求
*
* @param url
* @param param
* @return String
*/
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 带参数,带请求头的post请求
*
* @param url
* @param param
* @return String
*/
public static String doParamHeaderPost(String url, Map<String, String> header, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求头
if (header != null) {
for (String key : header.keySet()) {
httpPost.addHeader(key, header.get(key));
}
}
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 不带参数的post请求
*
* @param url
* @return String
*/
public static String doPost(String url) {
return doPost(url, null);
}
/**
* 传送json类型的post请求
*
* @param url
* @param json
* @return String
*/
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("accept", "application/json;charset=utf-8");
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 传送json类型的post请求带header
*
* @param url
* @param json
* @param header
* @return String
*/
public static String doPostJsonHeader(String url, String json, Map<String, String> header) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("accept", "application/json;charset=utf-8");
if (header != null) {
for (String key : header.keySet()) {
httpPost.addHeader(key, header.get(key));
}
}
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* post请求带header
*
* @param url
* @param header
* @return String
*/
public static String doPostHeader(String url, Map<String, String> header) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("accept", "application/json;charset=utf-8");
if (header != null) {
for (String key : header.keySet()) {
httpPost.addHeader(key, header.get(key));
}
}
// 创建请求内容
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 传送json类型的post请求带header
*
* @param url
* @param header
* @return String
*/
public static String doPostJsonHeader(String url, Map<String, String> header, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("accept", "application/json;charset=utf-8");
if (header != null) {
for (String key : header.keySet()) {
httpPost.addHeader(key, header.get(key));
}
}
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 带参数的get请求带header
*
* @param url
* @param param
* @return String
*/
public static String doGetHeader(String url, Map<String, String> header, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
httpGet.addHeader("accept", "application/json;charset=utf-8");
if (header != null) {
for (String key : header.keySet()) {
httpGet.addHeader(key, header.get(key));
}
}
// 执行请求
response = httpclient.execute(httpGet);
// // 判断返回状态是否为200
// if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* POST请求接口跳过ssl证书
*
* @param url
* @param params
* @return
*/
public static String doPostNoSSL(String url, String params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 创建 HttpPost 请求
HttpPost httpPost = new HttpPost(url);
// 设置请求体
StringEntity entity = new StringEntity(params);
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", "application/json");
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
// 处理响应
int statusCode = response.getStatusLine().getStatusCode();
result = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 带参数的get请求 跳过ssl证书
*
* @param url
* @return String
*/
public static String doGetNoSSL(String url, Map<String, String> params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 构建带参数的 URL
String fullUrl = buildUrlWithParams(url, params);
// 创建 HttpGet 请求
HttpGet httpGet = new HttpGet(fullUrl);
httpGet.setHeader("User-Agent", "Apache HttpClient");
// 执行请求并获取响应
HttpResponse response = httpClient.execute(httpGet);
// 检查响应状态码
int statusCode = response.getStatusLine().getStatusCode();
// 成功响应获取响应内容
result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 构建带查询参数的 URL
*/
private static String buildUrlWithParams(String url, Map<String, String> params) throws UnsupportedEncodingException {
if (params == null || params.isEmpty()) {
return url;
}
StringBuilder queryString = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (queryString.length() > 0) {
queryString.append("&");
}
queryString.append(URLEncoder.encode(entry.getKey(), "UTF-8"))
.append("=")
.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
// 处理 URL 中是否已有查询参数
if (url.contains("?")) {
return url + "&" + queryString;
} else {
return url + "?" + queryString;
}
}
/**
* POST请求接口跳过ssl证书
*
* @param url
* @param params
* @return
*/
public static String doPostHeaderNoSSL(String url, Map<String,String> headers,String params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 创建 HttpPost 请求
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/json");
// 添加自定义请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
// 设置请求体
if (params != null && !params.isEmpty()) {
StringEntity entity = new StringEntity(params, "UTF-8"); // 指定编码避免中文乱码
httpPost.setEntity(entity);
}
// 执行请求
HttpResponse response = httpClient.execute(httpPost);
// 处理响应
int statusCode = response.getStatusLine().getStatusCode();
result = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 带参数的get请求 跳过ssl证书
*
* @param url
* @return String
*/
public static String doGetHeaderNoSSL(String url, Map<String,String> headers,Map<String, String> params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 构建带参数的 URL
String fullUrl = buildUrlWithParams(url, params);
// 创建 HttpGet 请求
HttpGet httpGet = new HttpGet(fullUrl);
httpGet.setHeader("User-Agent", "Apache HttpClient");
// 添加自定义请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
// 执行请求并获取响应
HttpResponse response = httpClient.execute(httpGet);
// 检查响应状态码
int statusCode = response.getStatusLine().getStatusCode();
// 成功响应获取响应内容
result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* DELETE请求接口跳过ssl证书
*
* @param url 请求地址
* @param headers 请求头信息
* @param params 请求参数
* @return 响应结果
*/
public static String doDeleteHeaderNoSSL(String url, Map<String, String> headers, String params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 创建 HttpDelete 请求
HttpDelete httpDelete = new HttpDelete(url);
httpDelete.setHeader("Content-Type", "application/json");
// 添加自定义请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpDelete.setHeader(entry.getKey(), entry.getValue());
}
}
// 设置请求体某些DELETE请求可能需要传递参数
if (params != null && !params.isEmpty()) {
// 对于需要在请求体中传递参数的DELETE请求使用HttpEntityEnclosingRequestBase
HttpEntityEnclosingRequestBase httpDeleteWithBody = new HttpEntityEnclosingRequestBase() {
@Override
public String getMethod() {
return "DELETE";
}
};
httpDeleteWithBody.setURI(new URI(url));
httpDeleteWithBody.setHeader("Content-Type", "application/json");
// 复制请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpDeleteWithBody.setHeader(entry.getKey(), entry.getValue());
}
}
StringEntity entity = new StringEntity(params, "UTF-8");
httpDeleteWithBody.setEntity(entity);
// 执行请求
HttpResponse response = httpClient.execute(httpDeleteWithBody);
result = EntityUtils.toString(response.getEntity());
} else {
// 执行没有请求体的DELETE请求
HttpResponse response = httpClient.execute(httpDelete);
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* PUT请求接口跳过ssl证书
*
* @param url 请求地址
* @param headers 请求头信息
* @param params 请求参数
* @return 响应结果
*/
public static String doPutHeaderNoSSL(String url, Map<String, String> headers, String params) {
String result = "";
try {
// 创建信任所有证书的 SSL 上下文
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build();
// 创建 HttpClient 实例使用自定义的 SSL 上下文和主机名验证器
HttpClient httpClient = HttpClients.custom()
.setSslcontext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
// 创建 HttpPut 请求
HttpPut httpPut = new HttpPut(url);
httpPut.setHeader("Content-Type", "application/json");
// 添加自定义请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPut.setHeader(entry.getKey(), entry.getValue());
}
}
// 设置请求体某些PUT请求可能需要传递参数
if (params != null && !params.isEmpty()) {
// 对于需要在请求体中传递参数的PUT请求使用HttpEntityEnclosingRequestBase
HttpEntityEnclosingRequestBase httpDeleteWithBody = new HttpEntityEnclosingRequestBase() {
@Override
public String getMethod() {
return "PUT";
}
};
httpDeleteWithBody.setURI(new URI(url));
httpDeleteWithBody.setHeader("Content-Type", "application/json");
// 复制请求头
if (headers != null && !headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpDeleteWithBody.setHeader(entry.getKey(), entry.getValue());
}
}
StringEntity entity = new StringEntity(params, "UTF-8");
httpDeleteWithBody.setEntity(entity);
// 执行请求
HttpResponse response = httpClient.execute(httpDeleteWithBody);
result = EntityUtils.toString(response.getEntity());
} else {
// 执行没有请求体的PUT请求
HttpResponse response = httpClient.execute(httpPut);
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String okhttp3doPost(String url,String app_key,String app_security,String account,String authType) {
String resultString = "";
Response response = null;
try {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("app_key", app_key)
.addFormDataPart("app_security", app_security)
.addFormDataPart("account", account)
.addFormDataPart("authType", authType)
.build();
Request request = new Request.Builder()
.url(url)
.method("POST", body)
.build();
response = client.newCall(request).execute();
resultString = response.body().string();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (response != null) {
response.close();
}
}
return resultString;
}
}

View File

@ -0,0 +1,83 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.net.URI;
@Slf4j
@Component
public class HttpUtil {
private static final int TIMEOUT = 5000; // 5秒超时
public String callGetApi(String baseUrl, String apiPath,String clientId, String clientSecret) throws Exception {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 构建完整URL
URI uri = new URIBuilder(baseUrl + apiPath)
.addParameter("key", clientId)
.addParameter("secret", clientSecret)
.build();
log.error("HttpUtil.url"+uri);
HttpGet request = new HttpGet(uri);
request.setConfig(RequestConfig.custom()
.setConnectTimeout(TIMEOUT)
.setSocketTimeout(30000)
.build());
request.setHeader("Content-Type", "application/json");
log.error("HttpUtil.request"+request);
try (CloseableHttpResponse response = httpClient.execute(request)) {
log.error("HttpUtil.response"+response);
int statusCode = response.getStatusLine().getStatusCode();
log.error("HttpUtil.statusCode"+statusCode);
if (statusCode < 200 || statusCode >= 300) {
throw new RuntimeException("HTTP error: " + statusCode);
}
HttpEntity entity = response.getEntity();
log.error("HttpUtil.entity"+entity);
return EntityUtils.toString(entity);
}
}
}
// POST请求方法
public String callPostApi(String baseUrl, String apiPath,String jsonBody, String token) throws Exception {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
URI uri = new URIBuilder(baseUrl + apiPath).build();
HttpPost request = new HttpPost(uri);
// 设置请求头
request.setHeader("Content-Type", "application/json");
if (token != null) {
request.setHeader("Authorization", "Bearer " + token);
}
// 设置请求体
request.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));
// 设置超时配置
request.setConfig(RequestConfig.custom()
.setConnectTimeout(TIMEOUT)
.setSocketTimeout(TIMEOUT)
.build());
log.error("callPostApi.request"+request);
try (CloseableHttpResponse response = httpClient.execute(request)) {
log.error("callPostApi.response"+request);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode < 200 || statusCode >= 300) {
throw new RuntimeException("HTTP error: " + statusCode);
}
return EntityUtils.toString(response.getEntity());
}
}
}
}

View File

@ -0,0 +1,192 @@
package com.weaver.seconddev.jcl.organization.esb.zkd.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weaver.signcenter.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* 接口平台调用工具类
*
* @author wangj
* @version 1.00版本
* @Date 2025-4-27
*/
public class PapiUtil {
private final static Logger log = LoggerFactory.getLogger(PapiUtil.class);
private static String host = "https://hr.ustc.edu.cn/pqz";
private static String corpid = "c4e15b4733f463615c4d78d09a52d732";
private static String app_key = "ae7959882729017d7919b33b8b1735d1";
private static String app_secret = "26456dcd33506b68a656c057b68bf6f";
/**
* 获取CODE
*
* @return
*/
public static String getCode() {
String url = "/papi/openapi/oauth2/authorize";
Map<String, String> params = new HashMap<>(10);
params.put("corpid", corpid);
params.put("response_type", "code");
params.put("state", "");
String code = "";
String result = HttpCilentUtil.doPost(host + url, params);
JSONObject resObj = JSON.parseObject(result);
String errcode = Util.null2String(resObj.get("errcode"));
if ("0".equals(errcode)) {
code = Util.null2String(resObj.get("code"));
}
return code;
}
/**
* 获取AccessToken
*
* @param code
* @return
*/
public static String getAccessToken(String code) {
String url = "/papi/openapi/oauth2/access_token";
Map<String, String> params = new HashMap<>(10);
params.put("app_key", app_key);
params.put("app_secret", app_secret);
params.put("grant_type", "authorization_code");
params.put("code", code);
String accessToken = "";
String result = HttpCilentUtil.doPost(host + url, params);
JSONObject resObj = JSON.parseObject(result);
String errcode = Util.null2String(resObj.get("errcode"));
if ("0".equals(errcode)) {
accessToken = Util.null2String(resObj.get("accessToken"));
}
return accessToken;
}
/**
* 同步人员
*/
public static boolean syncEmployee(String accessToken, Map<String, Object> params) {
boolean flag = true;
String url = "/papi/openapi/api/hrm/restful/syncEmployee?access_token=" + accessToken;
String result = HttpCilentUtil.doPostJson(host + url, JSONObject.toJSONString(params));
JSONObject resObj = JSON.parseObject(result);
JSONObject message = (JSONObject) resObj.get("message");
String errcode = Util.null2String(message.get("errcode"));
if ("0".equals(errcode)) {
JSONArray data = (JSONArray) resObj.get("data");
JSONObject dataObj = (JSONObject) data.get(0);
String status = (String) dataObj.get("status");
if (!"SUCCESS".equals(status)) {
flag = false;
log.error("syncEmployee params:" + JSONObject.toJSONString(params));
log.error("syncEmployee result:" + result);
}
}
log.error("syncEmployee result:" + result);
return flag;
}
/**
* 同步部门
*/
public static boolean syncDepartment(String accessToken, Map<String, Object> params) {
boolean flag = true;
String url = "/papi/openapi/api/hrm/restful/syncDepartment?access_token=" + accessToken;
String result = HttpCilentUtil.doPostJson(host + url, JSONObject.toJSONString(params));
JSONObject resObj = JSON.parseObject(result);
JSONObject message = (JSONObject) resObj.get("message");
String errcode = Util.null2String(message.get("errcode"));
if ("0".equals(errcode)) {
JSONArray data = (JSONArray) resObj.get("data");
for (int i = 0; i < data.size(); i++) {
JSONObject dataObj = (JSONObject) data.get(i);
String status = (String) dataObj.get("status");
if (!"SUCCESS".equals(status)) {
flag = false;
}
}
}
if (!flag) {
log.error("syncDepartment params:" + JSONObject.toJSONString(params));
log.error("syncDepartment result:" + result);
}
return flag;
}
/**
* 同步岗位
*/
public static boolean syncPosition(String accessToken, Map<String, Object> params) {
boolean flag = true;
String url = "/papi/openapi/api/hrm/restful/syncPosition?access_token=" + accessToken;
String result = HttpCilentUtil.doPostJson(host + url, JSONObject.toJSONString(params));
JSONObject resObj = JSON.parseObject(result);
JSONObject message = (JSONObject) resObj.get("message");
String errcode = Util.null2String(message.get("errcode"));
if ("0".equals(errcode)) {
JSONArray data = (JSONArray) resObj.get("data");
for (int i = 0; i < data.size(); i++) {
JSONObject dataObj = (JSONObject) data.get(i);
String status = (String) dataObj.get("status");
if (!"SUCCESS".equals(status)) {
flag = false;
}
}
}
if (!flag) {
log.error("syncPosition params:" + JSONObject.toJSONString(params));
log.error("syncPosition result:" + result);
}
return flag;
}
/**
* 同步建模数据信息
*/
public static boolean updateFormData(String jkbs, String accessToken, Map<String, Object> params) {
String url = "/papi/openapi/api/ebuilder/form/formdata/v2/updateFormData/" + jkbs + "?access_token=" + accessToken;
String result = HttpCilentUtil.doPostJson(host + url, JSONObject.toJSONString(params));
JSONObject resObj = JSON.parseObject(result);
JSONObject datajson = (JSONObject) resObj.get("datajson");
boolean status = (boolean) datajson.get("status");
if (!status) {
log.error("updateFormData jkbs:" + jkbs);
log.error("updateFormData params:" + JSONObject.toJSONString(params));
log.error("updateFormData result:" + result);
}
return status;
}
/**
* 同步建模数据信息(新建)
*/
public static boolean insertFormData(String jkbs, String accessToken, Map<String, Object> params) {
String url = "/papi/openapi/api/ebuilder/form/formdata/v2/saveFormData/" + jkbs + "?access_token=" + accessToken;
String result = HttpCilentUtil.doPostJson(host + url, JSONObject.toJSONString(params));
JSONObject resObj = JSON.parseObject(result);
JSONObject datajson = (JSONObject) resObj.get("datajson");
boolean status = (boolean) datajson.get("status");
if (!status) {
log.error("saveFormData jkbs:" + jkbs);
log.error("saveFormData params:" + JSONObject.toJSONString(params));
log.error("saveFormData result:" + result);
}
return status;
}
}

View File

@ -0,0 +1,16 @@
package com.weaver.seconddev.jcl.organization.service;
import com.weaver.seconddev.jcl.organization.entity.hldz.Person;
import java.util.List;
import java.util.Map;
public interface AttendanceReportService {
List<Person> getAttendanceReportInfo(String yearMonth, String department, String userName, String jobNum);
Map<String,String> saveEBInfo(String yearMonth, String department, String userName, String jobNum);
Map<String,String> getEmployeePreparationInfo(String department, String year, String month);
}

View File

@ -43,6 +43,7 @@ public class OrganaztionSeviceImpl implements OrganaztionService {
@Override
public void addOrganaztionDepartment(Department department, SimpleEmployee employee) {
Map<String, Object> insertParam = CommonUtils.convertEntityToMap(department);
log.error("addOrganaztionDepartment.insertParam0000:{}",insertParam);
String id= idGeneratorService.generatorIds(1)[0];
insertParam.put("id",id);
insertParam.put("data_index","0.0");
@ -54,6 +55,7 @@ public class OrganaztionSeviceImpl implements OrganaztionService {
insertParam.put("updater",String.valueOf(employee.getId()));
insertParam.put("delete_type","0");
insertParam.put("ft_status","0");
log.error("addOrganaztionDepartment.insertParam1111:{}",insertParam);
Map<String,Object> param = Maps.newHashMap();
param.put("dataMap",insertParam);
param.put("tableName","uf_organization_bghzzsj");
@ -118,12 +120,13 @@ public class OrganaztionSeviceImpl implements OrganaztionService {
@Override
public void splitOrganzationDepartment(Map<String,Object> param, SimpleEmployee employee) {
Gson gson = new Gson();
log.error("param : "+param);
log.error("splitOrganzationDepartment.param000: "+param);
log.error(gson.toJson(param));
String splitDepartment = String.valueOf(param.get("departmentId"));
String splitDepartmentCode = String.valueOf(param.get("departmentCode"));
String fgldId = String.valueOf(param.get("fgldId"));
String sscb = String.valueOf(param.get("sscb"));
log.error("splitOrganzationDepartment.splitDepartment:{},splitDepartmentCode:{},fgldId:{},sscb:{}"+splitDepartment,splitDepartmentCode,fgldId,sscb);
List<Map<String,Object>> dataList = gson.fromJson(param.get("data").toString(),List.class);
String sql = "select * from eteams.department where parent=? and delete_type='0'";
@ -136,16 +139,24 @@ public class OrganaztionSeviceImpl implements OrganaztionService {
throw new EmployeeJclRunTimeException("被拆分组织下存在人员");
}
for (Map<String,Object> data:dataList){
log.error("splitOrganzationDepartment data"+data);
log.error("splitOrganzationDepartment.data"+data);
String bmfzr = ((List<Map<String,Object>>)data.get("bmfzr")).get(0).get("id").toString();
String sjzz = ((List<Map<String,Object>>)data.get("sjzz")).get(0).get("id").toString();
String sjzzName = ((List<Map<String,Object>>)data.get("sjzz")).get(0).get("name").toString();
Department department = Department.builder().form_data_id(String.valueOf(param.get("id"))).bh(data.get("bh").toString()).czlx("4").bcfzzid(splitDepartmentCode).bz(data.get("bz").toString())
.sscb(sscb).fgld(fgldId).sjzzmc(sjzzName).bmsqcj(data.get("bmsqcj").toString()).bmfzr(bmfzr).zzmc(data.get("zzmc").toString()).sjzz(sjzz).sjzzbh(data.get("sjzzbh").toString()).build();
log.error("splitOrganzationDepartment.bmfzr:{},sjzz:{},sjzzName:{}"+bmfzr,sjzz,sjzzName);
/**
* 这里补充一个逻辑根据上级组织id查询上级组织编号
*/
String code = String.valueOf(getDepartmentCodeById(sjzz).get(0).get("code"));
log.error("splitOrganzationDepartment.code"+code);
Department department = Department.builder().form_data_id(String.valueOf(param.get("id"))).bh(data.get("bh").toString()).czlx("4").bcfzzid(splitDepartmentCode)
.sscb(sscb).fgld(fgldId).sjzzmc(sjzzName).bmsqcj(data.get("bmsqcj").toString()).bmfzr(bmfzr).zzmc(data.get("zzmc").toString()).sjzz(sjzz).sjzzbh(code).build();
log.error("splitOrganzationDepartment.department"+department);
addOrganaztionDepartment(department,employee);
}
sql = "update uf_organization_bghzzsj set delete_type='3',is_delete='1' where bh=?";
databaseUtils.execute(sql,CommonUtils.getParamList(splitDepartmentCode));
Map<String, Object> execute = databaseUtils.execute(sql, CommonUtils.getParamList(splitDepartmentCode));
log.error("splitOrganzationDepartment.execute111:{}",execute);
}

View File

@ -1,289 +1,289 @@
package com.weaver.seconddev.jcl.organization.service.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weaver.common.form.data.FormDataService;
import com.weaver.common.form.metadata.ModuleSource;
import com.weaver.common.util.MimeTypeUtil;
import com.weaver.eteams.file.client.file.FileData;
import com.weaver.eteams.file.client.file.FileObj;
import com.weaver.eteams.file.client.remote.FileClientService;
import com.weaver.eteams.file.client.remote.RemoteUploadService;
import com.weaver.file.ud.api.FileDownloadService;
import com.weaver.framework.rpc.annotation.RpcReference;
import com.weaver.seconddev.jcl.common.service.CommonService;
import com.weaver.seconddev.jcl.enums.ContractStatusEnum;
import com.weaver.seconddev.jcl.organization.service.UploadService;
import com.weaver.seconddev.jcl.organization.util.CommonUtils;
import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
import com.weaver.seconddev.jcl.organization.util.excel.ExcelParseHelper;
import com.weaver.seconddev.jcl.organization.util.excel.ExcelSupport;
import com.weaver.seconddev.jcl.organization.util.excel.ExcelUtil;
import com.weaver.teams.client.doc.remote.DocClientService;
import com.weaver.teams.crm.property.PropertyType;
import com.weaver.teams.domain.EntityType;
import com.weaver.teams.domain.crm.RemoteCustomerProperty;
import com.weaver.teams.domain.crm.RemoteCustomerPropertyService;
import com.weaver.teams.domain.user.SimpleEmployee;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class UploadServiceImpl implements UploadService {
@RpcReference
private RemoteUploadService remoteUploadService;
@RpcReference
private DocClientService docClientService;
@RpcReference
private FileClientService fileClientService;
@Autowired
private DatabaseUtils databaseUtils;
@RpcReference
private RemoteCustomerPropertyService remoteCustomerPropertyService;
@Autowired
private CommonService commonService;
@Autowired
private FileDownloadService fileDownloadService;
public static final String EXCEL_TYPE_XLSX = "xlsx";
public static final String EXCEL_TYPE_XLS = "xls";
@Override
public Map<String, Object> jcluploadFile(List<Map<String, Object>> list,String tableName,String folderId,SimpleEmployee employee) throws Exception {
Map<String,Object> returnMap = Maps.newHashMap();
List<Map<String, Object>> importList = Lists.newArrayList();
String sql = "select a.* from form_field a left join form_table b on a.form_id=b.form_id where b.table_name=? and a.delete_type='0'";
List<Map<String, Object>> fieldList = databaseUtils.getSqlList(sql,CommonUtils.getParamList(tableName));
Map<String,List<Map<String, Object>>> fieldGroupByTitle = fieldList.stream().collect(Collectors.groupingBy(e->e.get("title").toString()));
for (Map<String, Object> resultMap:list){
FileData fileData = new FileData();
fileData.setLoadUrl(fileDownloadService.getDownloadUrl(CommonUtils.null2String(resultMap.get("url")),CommonUtils.null2String(resultMap.get("tenant_key")),CommonUtils.null2String(resultMap.get("name"))));
InputStream fileInputStream = fileData.getInputStream();
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
//标题
List<String> titles = ExcelSupport.getSheetHeader(sheet, 0);
returnMap.put("titles",titles);
log.error("title长度:{}",titles.get(0).length());
String title = titles.get(0).replace(" ", "");
log.error("处理前年月信息:{}",title);
// 处理数值
List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1, 0);
log.error("excel导入数据数量[{}]", data.size());
// 表头
List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
List<Map<String, String>> dataList = Lists.newArrayList();
List<Map<String,Object>> fileList = ExcelUtil.processEmbeddedObjects((XSSFSheet)sheet);
Map<String,Object> map = Maps.newHashMap();
for (int i = 0; i < data.size(); i++) {
map = data.get(i);
Map<String, String> singleCheck = new HashMap<>();
for (int j = 0; j < headers.size(); j++) {
//组装单条数据基础数据
String key = headers.get(j);
if (key == null) {
continue;
}
singleCheck.put(key.replace(" ", ""), Optional.ofNullable(map.get(key)).orElse("").toString().replace(" ", ""));
}
dataList.add(singleCheck);
}
//处理导入附件
List<Map<String, String>> needUpdataList = Lists.newArrayList();
for (Map<String,Object> fileMap:fileList){
int rowNum = Integer.valueOf(fileMap.get("rowNum").toString());
int colNum = Integer.valueOf(fileMap.get("colNum").toString());
String fileName = dataList.get(rowNum-1).get(titles.get(colNum));
fileMap.put("filename",fileName);
Map<String,Object> fileUploadMap = uploadFile(fileMap,folderId,ModuleSource.ebuildercard,0L,employee,null);
long docId = ((FileObj)fileUploadMap.get("fileObj")).getDocId();
long fileid = ((FileObj)fileUploadMap.get("fileObj")).getFileid();
long id = ((FileObj)fileUploadMap.get("fileObj")).getId();
log.error("docId : [{}],fileid:[{}],id:[{}]",docId,fileid,id);
dataList.get(rowNum-1).put(titles.get(colNum),String.valueOf(docId));
Map<String,String> updataMap = Maps.newHashMap();
updataMap.put("id",dataList.get(rowNum-1).get("数据ID"));
if (fieldGroupByTitle.get(titles.get(colNum)).get(0).get("component_key").equals("FileComponent")){
//附件
log.error("附件字段");
updataMap.put(titles.get(colNum),String.valueOf(fileid));
}else{
log.error("文档字段");
log.error("字段key"+fieldGroupByTitle.get(titles.get(colNum)).get(0).get("component_key"));
updataMap.put(titles.get(colNum),String.valueOf(docId));
}
needUpdataList.add(updataMap);
}
Map<String, Object> importResult = importData(needUpdataList,tableName,fieldGroupByTitle);
importList.add(importResult);
}
returnMap.put("importList",importList);
return returnMap;
}
public Map<String, Object> uploadFile(Map<String,Object> fileMap,String folderId, ModuleSource module, Long refId, SimpleEmployee employee, String chunks) {
File data = null;
try{
data = File.createTempFile(UUID.randomUUID().toString(),null);
InputStream stream = (InputStream)fileMap.get("stream");
String filename = CommonUtils.null2String(fileMap.get("filename"));
if (filename.endsWith(".pdf") || filename.endsWith(".bin")){
PDDocument document = PDDocument.load(stream);
document.save(data);
if (filename.endsWith(".bin")){
filename = filename.replace(".bin",".pdf");
fileMap.put("filename",filename);
}
}else {
FileUtils.copyInputStreamToFile(stream, data);
}
stream.close();
}catch (Exception e){
log.error("error", e);
}
Map<String, Object> result = new HashMap<>();
if (refId == 0L) {
FileObj fileObj = new FileObj();
String dataFileName = CommonUtils.null2String(fileMap.get("filename"));
if(StringUtils.isEmpty(dataFileName)){
return result;
}
String dataContentType = CommonUtils.null2String(fileMap.get("contentType"));
fileObj.setName(dataFileName);
fileObj.setRefId(refId);
fileObj.setModule(EntityType.valueOf(module.toString()));
String extensionName = dataFileName.lastIndexOf(".") > 0 ? dataFileName.substring(dataFileName.lastIndexOf(".")) : "";
String contentType = MimeTypeUtil.getMimeType(extensionName);
fileObj.setType(contentType != null ? contentType : dataContentType);
fileObj.setSize(data.length());
String tenantKey = employee.getTenantKey();
fileObj.setTenantKey(tenantKey);
if(chunks != null) {
try {
InputStream input = new FileInputStream(data);
Map<String, Object> map = remoteUploadService.chunkUpload(
employee.getEmployeeId(),
chunks,
Integer.parseInt(chunks == null ? "0" : chunks),
Integer.parseInt(chunks == null ? "0" : chunks),
data.length(),
toByteArray(input),
String.valueOf(new Date().getTime()),
dataFileName,
data.length(),
module.toString(),
refId,
null,
"false",
tenantKey);
String success = (String) map.get("success");
if(map.get("fileObj") != null) {
success = "true";
fileObj = (FileObj) map.get("fileObj");
}
result.put("success",success);
result.put("responseMap",map);
}catch (Exception e) {
log.error("error", e);
result.put("error",e);
}
}else{
try{
fileObj = remoteUploadService.saveFile(employee.getTenantKey(), fileObj, Files.readAllBytes(data.toPath()));
//生成附件文档
fileObj.setDocId(docClientService.fileCreateDoc(fileObj.getFileid(),Long.valueOf(folderId),employee.getId(),EntityType.valueOf(module.toString()),employee.getTenantKey()));
//fileObj.setDocId(docClientService.postFileUploadReId(fileObj, employee, new Date(), EntityType.valueOf(module.toString())));
fileClientService.update(fileObj);
} catch (Exception e) {
log.error("error", e);
} finally {
if(data != null){
data.delete();
}
}
}
result.put("fileObj",fileObj);
result.put("module",module);
result.put("refId",refId);
}
return result;
}
public Map<String, Object> importData(List<Map<String, String>> dataList,String tableName,Map<String,List<Map<String, Object>>> fieldGroupByTitle) {
Map<String,Object> resultMap = Maps.newHashMap();
List<Map<String, Object>> updateData = Lists.newArrayList();
Map<String,List<Map<String, String>>> dataGroupById = dataList.stream().collect(Collectors.groupingBy(e->e.get("id").toString()));
for (Map.Entry<String,List<Map<String, String>>>entry : dataGroupById.entrySet()){
Map<String,Object> updataMap = Maps.newHashMap();
String id = entry.getKey();
Map<String,Object> dataMap = Maps.newHashMap();
for (Map<String,String> map : entry.getValue()){
for (Map.Entry<String,String> data: map.entrySet()){
String key = data.getKey();
key = fieldGroupByTitle.get(key)==null?key:fieldGroupByTitle.get(key).get(0).get("data_key").toString();
String value = data.getValue();
if (dataMap.get(key) == null){
dataMap.put(key,value);
}else {
String oldValue = CommonUtils.null2String(dataMap.get(key));
dataMap.put(key,oldValue+","+value);
}
}
}
Map<String,Object> condition = Maps.newHashMap();
condition.put("id",id);
updataMap.put("condition",condition);
updataMap.put("dataMap",dataMap);
updataMap.put("tableName",tableName);
commonService.updateCommon(updataMap);
updateData.add(updataMap);
}
resultMap.put("updateData",updateData);
return resultMap;
}
/**
* InputStream转化为byte数组
* @param input 输入流
* @return 字节
* @throws IOException 异常
*/
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
}
//package com.weaver.seconddev.jcl.organization.service.impl;
//
//import com.google.common.collect.Lists;
//import com.google.common.collect.Maps;
//import com.weaver.common.form.data.FormDataService;
//import com.weaver.common.form.metadata.ModuleSource;
//import com.weaver.common.util.MimeTypeUtil;
//import com.weaver.eteams.file.client.file.FileData;
//import com.weaver.eteams.file.client.file.FileObj;
//import com.weaver.eteams.file.client.remote.FileClientService;
//import com.weaver.eteams.file.client.remote.RemoteUploadService;
//import com.weaver.file.ud.api.FileDownloadService;
//import com.weaver.framework.rpc.annotation.RpcReference;
//import com.weaver.seconddev.jcl.common.service.CommonService;
//import com.weaver.seconddev.jcl.enums.ContractStatusEnum;
//import com.weaver.seconddev.jcl.organization.service.UploadService;
//import com.weaver.seconddev.jcl.organization.util.CommonUtils;
//import com.weaver.seconddev.jcl.organization.util.DatabaseUtils;
//import com.weaver.seconddev.jcl.organization.util.excel.ExcelParseHelper;
//import com.weaver.seconddev.jcl.organization.util.excel.ExcelSupport;
//import com.weaver.seconddev.jcl.organization.util.excel.ExcelUtil;
//import com.weaver.teams.client.doc.remote.DocClientService;
//import com.weaver.teams.crm.property.PropertyType;
//import com.weaver.teams.domain.EntityType;
//import com.weaver.teams.domain.crm.RemoteCustomerProperty;
//import com.weaver.teams.domain.crm.RemoteCustomerPropertyService;
//import com.weaver.teams.domain.user.SimpleEmployee;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.io.FileUtils;
//import org.apache.commons.io.IOUtils;
//import org.apache.commons.lang.StringUtils;
//import org.apache.pdfbox.pdmodel.PDDocument;
//import org.apache.poi.ss.usermodel.Sheet;
//import org.apache.poi.xssf.usermodel.XSSFSheet;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.*;
//import java.nio.file.Files;
//import java.util.*;
//import java.util.stream.Collectors;
//
//@Slf4j
//@Service
//public class UploadServiceImpl implements UploadService {
//
// @RpcReference
// private RemoteUploadService remoteUploadService;
// @RpcReference
// private DocClientService docClientService;
// @RpcReference
// private FileClientService fileClientService;
// @Autowired
// private DatabaseUtils databaseUtils;
// @RpcReference
// private RemoteCustomerPropertyService remoteCustomerPropertyService;
// @Autowired
// private CommonService commonService;
// @Autowired
// private FileDownloadService fileDownloadService;
// public static final String EXCEL_TYPE_XLSX = "xlsx";
// public static final String EXCEL_TYPE_XLS = "xls";
//
//
// @Override
// public Map<String, Object> jcluploadFile(List<Map<String, Object>> list,String tableName,String folderId,SimpleEmployee employee) throws Exception {
// Map<String,Object> returnMap = Maps.newHashMap();
// List<Map<String, Object>> importList = Lists.newArrayList();
// String sql = "select a.* from form_field a left join form_table b on a.form_id=b.form_id where b.table_name=? and a.delete_type='0'";
// List<Map<String, Object>> fieldList = databaseUtils.getSqlList(sql,CommonUtils.getParamList(tableName));
// Map<String,List<Map<String, Object>>> fieldGroupByTitle = fieldList.stream().collect(Collectors.groupingBy(e->e.get("title").toString()));
// for (Map<String, Object> resultMap:list){
// FileData fileData = new FileData();
// fileData.setLoadUrl(fileDownloadService.getDownloadUrl(CommonUtils.null2String(resultMap.get("url")),CommonUtils.null2String(resultMap.get("tenant_key")),CommonUtils.null2String(resultMap.get("name"))));
//
// InputStream fileInputStream = fileData.getInputStream();
//
// Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
// //标题
// List<String> titles = ExcelSupport.getSheetHeader(sheet, 0);
// returnMap.put("titles",titles);
// log.error("title长度:{}",titles.get(0).length());
// String title = titles.get(0).replace(" ", "");
// log.error("处理前年月信息:{}",title);
//
//
// // 处理数值
// List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1, 0);
// log.error("excel导入数据数量[{}]", data.size());
// // 表头
// List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
// List<Map<String, String>> dataList = Lists.newArrayList();
// List<Map<String,Object>> fileList = ExcelUtil.processEmbeddedObjects((XSSFSheet)sheet);
// Map<String,Object> map = Maps.newHashMap();
// for (int i = 0; i < data.size(); i++) {
// map = data.get(i);
// Map<String, String> singleCheck = new HashMap<>();
// for (int j = 0; j < headers.size(); j++) {
// //组装单条数据基础数据
// String key = headers.get(j);
// if (key == null) {
// continue;
// }
// singleCheck.put(key.replace(" ", ""), Optional.ofNullable(map.get(key)).orElse("").toString().replace(" ", ""));
// }
// dataList.add(singleCheck);
// }
// //处理导入附件
// List<Map<String, String>> needUpdataList = Lists.newArrayList();
// for (Map<String,Object> fileMap:fileList){
// int rowNum = Integer.valueOf(fileMap.get("rowNum").toString());
// int colNum = Integer.valueOf(fileMap.get("colNum").toString());
// String fileName = dataList.get(rowNum-1).get(titles.get(colNum));
// fileMap.put("filename",fileName);
//
// Map<String,Object> fileUploadMap = uploadFile(fileMap,folderId,ModuleSource.ebuildercard,0L,employee,null);
// long docId = ((FileObj)fileUploadMap.get("fileObj")).getDocId();
// long fileid = ((FileObj)fileUploadMap.get("fileObj")).getFileid();
// long id = ((FileObj)fileUploadMap.get("fileObj")).getId();
// log.error("docId : [{}],fileid:[{}],id:[{}]",docId,fileid,id);
// dataList.get(rowNum-1).put(titles.get(colNum),String.valueOf(docId));
// Map<String,String> updataMap = Maps.newHashMap();
// updataMap.put("id",dataList.get(rowNum-1).get("数据ID"));
// if (fieldGroupByTitle.get(titles.get(colNum)).get(0).get("component_key").equals("FileComponent")){
// //附件
// log.error("附件字段");
// updataMap.put(titles.get(colNum),String.valueOf(fileid));
// }else{
// log.error("文档字段");
// log.error("字段key"+fieldGroupByTitle.get(titles.get(colNum)).get(0).get("component_key"));
// updataMap.put(titles.get(colNum),String.valueOf(docId));
// }
// needUpdataList.add(updataMap);
// }
//
// Map<String, Object> importResult = importData(needUpdataList,tableName,fieldGroupByTitle);
// importList.add(importResult);
// }
// returnMap.put("importList",importList);
//
// return returnMap;
// }
//
// public Map<String, Object> uploadFile(Map<String,Object> fileMap,String folderId, ModuleSource module, Long refId, SimpleEmployee employee, String chunks) {
// File data = null;
// try{
// data = File.createTempFile(UUID.randomUUID().toString(),null);
// InputStream stream = (InputStream)fileMap.get("stream");
// String filename = CommonUtils.null2String(fileMap.get("filename"));
// if (filename.endsWith(".pdf") || filename.endsWith(".bin")){
// PDDocument document = PDDocument.load(stream);
// document.save(data);
// if (filename.endsWith(".bin")){
// filename = filename.replace(".bin",".pdf");
// fileMap.put("filename",filename);
// }
// }else {
// FileUtils.copyInputStreamToFile(stream, data);
// }
// stream.close();
// }catch (Exception e){
// log.error("error", e);
// }
//
// Map<String, Object> result = new HashMap<>();
// if (refId == 0L) {
// FileObj fileObj = new FileObj();
// String dataFileName = CommonUtils.null2String(fileMap.get("filename"));
//
// if(StringUtils.isEmpty(dataFileName)){
// return result;
// }
// String dataContentType = CommonUtils.null2String(fileMap.get("contentType"));
// fileObj.setName(dataFileName);
// fileObj.setRefId(refId);
// fileObj.setModule(EntityType.valueOf(module.toString()));
// String extensionName = dataFileName.lastIndexOf(".") > 0 ? dataFileName.substring(dataFileName.lastIndexOf(".")) : "";
// String contentType = MimeTypeUtil.getMimeType(extensionName);
//
// fileObj.setType(contentType != null ? contentType : dataContentType);
// fileObj.setSize(data.length());
// String tenantKey = employee.getTenantKey();
// fileObj.setTenantKey(tenantKey);
// if(chunks != null) {
// try {
// InputStream input = new FileInputStream(data);
// Map<String, Object> map = remoteUploadService.chunkUpload(
// employee.getEmployeeId(),
// chunks,
// Integer.parseInt(chunks == null ? "0" : chunks),
// Integer.parseInt(chunks == null ? "0" : chunks),
// data.length(),
// toByteArray(input),
// String.valueOf(new Date().getTime()),
// dataFileName,
// data.length(),
// module.toString(),
// refId,
// null,
// "false",
// tenantKey);
// String success = (String) map.get("success");
// if(map.get("fileObj") != null) {
// success = "true";
// fileObj = (FileObj) map.get("fileObj");
// }
// result.put("success",success);
// result.put("responseMap",map);
// }catch (Exception e) {
// log.error("error", e);
// result.put("error",e);
// }
// }else{
// try{
// fileObj = remoteUploadService.saveFile(employee.getTenantKey(), fileObj, Files.readAllBytes(data.toPath()));
// //生成附件文档
// fileObj.setDocId(docClientService.fileCreateDoc(fileObj.getFileid(),Long.valueOf(folderId),employee.getId(),EntityType.valueOf(module.toString()),employee.getTenantKey()));
// //fileObj.setDocId(docClientService.postFileUploadReId(fileObj, employee, new Date(), EntityType.valueOf(module.toString())));
// fileClientService.update(fileObj);
// } catch (Exception e) {
// log.error("error", e);
// } finally {
// if(data != null){
// data.delete();
// }
// }
// }
// result.put("fileObj",fileObj);
// result.put("module",module);
// result.put("refId",refId);
// }
//
// return result;
// }
//
// public Map<String, Object> importData(List<Map<String, String>> dataList,String tableName,Map<String,List<Map<String, Object>>> fieldGroupByTitle) {
//
// Map<String,Object> resultMap = Maps.newHashMap();
//
// List<Map<String, Object>> updateData = Lists.newArrayList();
//
// Map<String,List<Map<String, String>>> dataGroupById = dataList.stream().collect(Collectors.groupingBy(e->e.get("id").toString()));
// for (Map.Entry<String,List<Map<String, String>>>entry : dataGroupById.entrySet()){
// Map<String,Object> updataMap = Maps.newHashMap();
// String id = entry.getKey();
// Map<String,Object> dataMap = Maps.newHashMap();
// for (Map<String,String> map : entry.getValue()){
// for (Map.Entry<String,String> data: map.entrySet()){
// String key = data.getKey();
// key = fieldGroupByTitle.get(key)==null?key:fieldGroupByTitle.get(key).get(0).get("data_key").toString();
// String value = data.getValue();
// if (dataMap.get(key) == null){
// dataMap.put(key,value);
// }else {
// String oldValue = CommonUtils.null2String(dataMap.get(key));
// dataMap.put(key,oldValue+","+value);
// }
// }
// }
// Map<String,Object> condition = Maps.newHashMap();
// condition.put("id",id);
// updataMap.put("condition",condition);
// updataMap.put("dataMap",dataMap);
// updataMap.put("tableName",tableName);
// commonService.updateCommon(updataMap);
// updateData.add(updataMap);
// }
//
// resultMap.put("updateData",updateData);
// return resultMap;
// }
//
// /**
// * InputStream转化为byte数组
// * @param input 输入流
// * @return 字节
// * @throws IOException 异常
// */
// public static byte[] toByteArray(InputStream input) throws IOException {
// ByteArrayOutputStream output = new ByteArrayOutputStream();
// byte[] buffer = new byte[4096];
// int n = 0;
// while (-1 != (n = input.read(buffer))) {
// output.write(buffer, 0, n);
// }
// return output.toByteArray();
// }
//}