|
|
|
@ -16,14 +16,12 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
import javax.validation.Validator;
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
|
|
|
|
import org.apache.ibatis.session.ExecutorType;
|
|
|
|
|
import org.apache.ibatis.session.SqlSession;
|
|
|
|
|
import org.apache.ibatis.session.SqlSessionFactory;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Propagation;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
|
|
@ -31,7 +29,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
|
|
|
|
|
|
import com.alibaba.fastjson2.JSONArray;
|
|
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
|
|
|
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
|
|
|
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
|
|
import com.op.common.core.constant.UserConstants;
|
|
|
|
|
import com.op.common.core.domain.R;
|
|
|
|
|
import com.op.common.core.exception.ServiceException;
|
|
|
|
@ -91,6 +89,7 @@ public class SysUserServiceImpl implements ISysUserService {
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
protected Validator validator;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private SysDatasourceMapper sysDatasourceMapper;
|
|
|
|
|
|
|
|
|
@ -568,60 +567,51 @@ public class SysUserServiceImpl implements ISysUserService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@DS("master") // 指定数据
|
|
|
|
|
public R syncUserInfoTask() {
|
|
|
|
|
DynamicDataSourceContextHolder.push("master");// 这是数据源的key
|
|
|
|
|
try {
|
|
|
|
|
// Date maxTime0 = userMapper.getMaxTime();
|
|
|
|
|
// if(maxTime0 != null){
|
|
|
|
|
Calendar calendar = Calendar.getInstance();
|
|
|
|
|
// calendar.setTime(maxTime0);
|
|
|
|
|
calendar.add(Calendar.DAY_OF_YEAR, -1);
|
|
|
|
|
Date maxTime = calendar.getTime();
|
|
|
|
|
// Date maxTime = DateUtils.getNowDate();
|
|
|
|
|
String ymd = DateFormatUtils.format(maxTime, "yyyy-MM-dd");// yyyy-MM-dd
|
|
|
|
|
String ymd = DateFormatUtils.format(maxTime, "yyyy-MM-dd");
|
|
|
|
|
log.info("更新人力-参数:" + ymd);
|
|
|
|
|
// AjaxResult hrR = remoteOpenService.GetHrUserInfo("2024-05-01");
|
|
|
|
|
AjaxResult hrR = remoteOpenService.GetHrUserInfo(ymd);
|
|
|
|
|
|
|
|
|
|
AjaxResult hrR = remoteOpenService.GetHrUserInfo(ymd);
|
|
|
|
|
List<HRInfo> infoList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
if ((int) hrR.get("code") == 200 && hrR.get("data") != null) {
|
|
|
|
|
infoList = JSONArray.parseArray(JSONObject.toJSONString(hrR.get("data")), HRInfo.class);
|
|
|
|
|
log.info("更新人力-结果:" + JSONObject.toJSONString(infoList));
|
|
|
|
|
if (!CollectionUtils.isEmpty(infoList)) {
|
|
|
|
|
this.syncUserInfoFunc(infoList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return R.fail("无最新需要更新的人力数据");
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
DynamicDataSourceContextHolder.poll();
|
|
|
|
|
return R.ok();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("同步用户信息失败", e);
|
|
|
|
|
return R.fail(e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return R.ok();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected int syncUserInfoFunc(List<HRInfo> dtos) {
|
|
|
|
|
log.info("人力信息同步:" + JSONObject.toJSONString(dtos));
|
|
|
|
|
Date nowDate = DateUtils.getNowDate();
|
|
|
|
|
String createBy = "job";
|
|
|
|
|
|
|
|
|
|
for (HRInfo dto : dtos) {
|
|
|
|
|
dto.setCreateTime(nowDate);
|
|
|
|
|
dto.setCreateBy(createBy);
|
|
|
|
|
dto.setUpdateBy(createBy);
|
|
|
|
|
dto.setUpdateTime(nowDate);
|
|
|
|
|
|
|
|
|
|
dto.setUserName(dto.getPeWorkID());
|
|
|
|
|
dto.setNickName(dto.getPeName());
|
|
|
|
|
dto.setSex(dto.getPeSex().equals("F") ? "1" : "0");// 1女
|
|
|
|
|
dto.setSex(dto.getPeSex().equals("F") ? "1" : "0");
|
|
|
|
|
dto.setStatus("0");
|
|
|
|
|
dto.setPeSnr(dto.getWorkCard());
|
|
|
|
|
String[] delArrays = { "30", "31", "32", "33", "99" };
|
|
|
|
|
if (Arrays.asList(delArrays).contains(dto.getPeDocStatus())) {
|
|
|
|
|
dto.setDelFlag("1");
|
|
|
|
|
} else {
|
|
|
|
|
dto.setDelFlag("0");
|
|
|
|
|
}
|
|
|
|
|
dto.setDelFlag(Arrays.asList(delArrays).contains(dto.getPeDocStatus()) ? "1" : "0");
|
|
|
|
|
dto.setPhonenumber(dto.getPeMobilePhone());
|
|
|
|
|
dto.setPost(dto.getPoscd());
|
|
|
|
|
if (StringUtils.isNotBlank(dto.getOucod())) {
|
|
|
|
@ -633,113 +623,96 @@ public class SysUserServiceImpl implements ISysUserService {
|
|
|
|
|
List<String> codes = dtos.stream().map(HRInfo::getUserName).collect(Collectors.toList());
|
|
|
|
|
// sap返回的工作中心编码-本地已存在
|
|
|
|
|
List<String> exsitCodes = userMapper.getExsitCodes(codes);
|
|
|
|
|
// sap返回的工作中心编码-本地不存在// 差集 (list2 - list1)
|
|
|
|
|
List<String> noExsitCodes = codes.stream().filter(item -> !exsitCodes.contains(item))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
List<HRInfo> updates = dtos.stream().filter(item -> exsitCodes.contains(item.getUserName()))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(updates)) {
|
|
|
|
|
int allsize = updates.size();
|
|
|
|
|
int inserttimes = allsize / 100 + 1;
|
|
|
|
|
for (int m = 0; m < inserttimes; m++) {
|
|
|
|
|
List<HRInfo> everyList;
|
|
|
|
|
if (m < (inserttimes - 1)) {
|
|
|
|
|
everyList = updates.subList(m * 100, (m + 1) * 100);
|
|
|
|
|
} else {
|
|
|
|
|
everyList = updates.subList(m * 100, allsize);
|
|
|
|
|
}
|
|
|
|
|
if (everyList.size() > 0) {
|
|
|
|
|
int snum = userMapper.updateUserBatchs(everyList);
|
|
|
|
|
if (snum == 1) {
|
|
|
|
|
log.info("人员编辑成功条数:" + everyList.size());
|
|
|
|
|
} else {
|
|
|
|
|
log.info("人员编辑失败条数:" + everyList.size());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
batchUpdateUser(updates);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<HRInfo> adds = dtos.stream().filter(item -> noExsitCodes.contains(item.getUserName()))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(adds)) {
|
|
|
|
|
int allsize = adds.size();
|
|
|
|
|
int inserttimes = allsize / 100 + 1;
|
|
|
|
|
for (int m = 0; m < inserttimes; m++) {
|
|
|
|
|
List<HRInfo> everyList;
|
|
|
|
|
if (m < (inserttimes - 1)) {
|
|
|
|
|
everyList = adds.subList(m * 100, (m + 1) * 100);
|
|
|
|
|
} else {
|
|
|
|
|
everyList = adds.subList(m * 100, allsize);
|
|
|
|
|
}
|
|
|
|
|
if (everyList.size() > 0) {
|
|
|
|
|
int nnum = userMapper.addUserBatchs(everyList);
|
|
|
|
|
log.info("人员新增成功条数:" + nnum);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
batchAddUser(adds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量更新用户
|
|
|
|
|
private void batchUpdateUser(List<HRInfo> updates) {
|
|
|
|
|
int batchSize = 100;
|
|
|
|
|
int total = updates.size();
|
|
|
|
|
for (int i = 0; i < total; i += batchSize) {
|
|
|
|
|
int end = Math.min(i + batchSize, total);
|
|
|
|
|
userMapper.updateUserBatchs(updates.subList(i, end));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 批量新增用户
|
|
|
|
|
private void batchAddUser(List<HRInfo> adds) {
|
|
|
|
|
int batchSize = 100;
|
|
|
|
|
int total = adds.size();
|
|
|
|
|
for (int i = 0; i < total; i += batchSize) {
|
|
|
|
|
int end = Math.min(i + batchSize, total);
|
|
|
|
|
userMapper.addUserBatchs(adds.subList(i, end));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 同步
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@DS("ds_1000") // 指定数据源
|
|
|
|
|
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) // 独立事务,避免上下文污染
|
|
|
|
|
public R syncClockInRecord() {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
DynamicDataSourceContextHolder.push("ds_1000");
|
|
|
|
|
// 调用 sendPost 方法(确保此方法内部使用 POST 方法发送数据)
|
|
|
|
|
Map param = new HashMap();
|
|
|
|
|
Map param = new HashMap<>();
|
|
|
|
|
LocalDate yesterdayDate = LocalDate.now().minusDays(1);
|
|
|
|
|
param.put("day", yesterdayDate);
|
|
|
|
|
|
|
|
|
|
String result = HttpUtils.sendPostForm(attendanceRecordUrl, param);
|
|
|
|
|
List<MesClockRecord> mesClockRecordList = JSONArray.parseArray(result, MesClockRecord.class);
|
|
|
|
|
|
|
|
|
|
SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
List<MesClockRecord> clockRecordList = mesClockRecordList.stream().map(mesClockRecord -> {
|
|
|
|
|
String ClockTime = mesClockRecord.getDay() + " " + mesClockRecord.getTime();
|
|
|
|
|
String clockTimeStr = mesClockRecord.getDay() + " " + mesClockRecord.getTime();
|
|
|
|
|
try {
|
|
|
|
|
Date clockTime = sdfs.parse(ClockTime);
|
|
|
|
|
Date clockTime = sdfs.parse(clockTimeStr);
|
|
|
|
|
mesClockRecord.setClockTime(clockTime);
|
|
|
|
|
} catch (ParseException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
log.error("时间格式解析失败: {}", clockTimeStr, e);
|
|
|
|
|
}
|
|
|
|
|
return mesClockRecord;
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
// 处理响应结果
|
|
|
|
|
|
|
|
|
|
// 调用优化后的批量插入方法
|
|
|
|
|
batchInsert(clockRecordList);
|
|
|
|
|
System.out.println("服务器响应: " + clockRecordList);
|
|
|
|
|
log.info("打卡记录同步成功,条数:{}", clockRecordList.size());
|
|
|
|
|
return R.ok(result);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
log.error("同步打卡记录失败", e);
|
|
|
|
|
return R.fail(e.getMessage());
|
|
|
|
|
} finally {
|
|
|
|
|
DynamicDataSourceContextHolder.poll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Autowired // 关键:注入 SqlSessionFactory
|
|
|
|
|
private SqlSessionFactory sqlSessionFactory;
|
|
|
|
|
|
|
|
|
|
public void batchInsert(List<MesClockRecord> records) {
|
|
|
|
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
|
|
|
|
try {
|
|
|
|
|
MesClockRecordMapper mapper = sqlSession.getMapper(MesClockRecordMapper.class);
|
|
|
|
|
int batchSize = 500;
|
|
|
|
|
for (int i = 0; i < records.size(); i += batchSize) {
|
|
|
|
|
int end = Math.min(i + batchSize, records.size());
|
|
|
|
|
List<MesClockRecord> subList = records.subList(i, end);
|
|
|
|
|
mapper.insertMesClockRecordList(subList);
|
|
|
|
|
sqlSession.flushStatements(); // 批处理执行
|
|
|
|
|
}
|
|
|
|
|
sqlSession.commit(); // 提交事务
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
sqlSession.rollback();
|
|
|
|
|
throw new RuntimeException("批量插入失败", e);
|
|
|
|
|
} finally {
|
|
|
|
|
sqlSession.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 批量插入打卡记录
|
|
|
|
|
*/
|
|
|
|
|
private void batchInsert(List<MesClockRecord> records) {
|
|
|
|
|
if (CollectionUtils.isEmpty(records)) {
|
|
|
|
|
log.info("无打卡记录需要插入");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int batchSize = 500;
|
|
|
|
|
int total = records.size();
|
|
|
|
|
for (int i = 0; i < total; i += batchSize) {
|
|
|
|
|
int end = Math.min(i + batchSize, total);
|
|
|
|
|
List<MesClockRecord> subList = records.subList(i, end);
|
|
|
|
|
mesClockRecordMapper.insertMesClockRecordList(subList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|