From dc0fa3c6061a03d0ea04ed43d90bdf0bd68ae44e Mon Sep 17 00:00:00 2001 From: FCD <2453864257@qq.com> Date: Mon, 11 Aug 2025 10:49:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5hr=E7=B3=BB=E7=BB=9F=E5=87=BA?= =?UTF-8?q?=E5=8B=A4=E8=AE=B0=E5=BD=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MesAttendanceRecordsController.java | 36 +++++ .../mes/domain/MesPostAttendanceRecords.java | 98 ++++++++++++ .../mapper/MesAttendanceRecordsMapper.java | 8 + .../service/IMesAttendanceRecordsService.java | 9 ++ .../impl/MesAttendanceRecordsServiceImpl.java | 144 +++++++++++++++++- .../mapper/mes/MesAttendanceRecordsMapper.xml | 107 +++++++++++++ .../mapper/mes/MesReportWorkMapper.xml | 3 +- 7 files changed, 402 insertions(+), 3 deletions(-) create mode 100644 op-modules/op-mes/src/main/java/com/op/mes/domain/MesPostAttendanceRecords.java diff --git a/op-modules/op-mes/src/main/java/com/op/mes/controller/MesAttendanceRecordsController.java b/op-modules/op-mes/src/main/java/com/op/mes/controller/MesAttendanceRecordsController.java index 717c3126a..92f2f10e3 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/controller/MesAttendanceRecordsController.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/controller/MesAttendanceRecordsController.java @@ -5,8 +5,10 @@ import javax.servlet.http.HttpServletResponse; import com.op.common.core.utils.poi.ExcelUtil; import com.op.common.core.web.controller.BaseController; +import com.op.common.core.web.domain.AjaxResult; import com.op.common.core.web.page.TableDataInfo; import com.op.common.security.annotation.RequiresPermissions; +import com.op.mes.domain.MesPostAttendanceRecords; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -96,4 +98,38 @@ public class MesAttendanceRecordsController extends BaseController // { // return toAjax(mesAttendanceRecordsService.deleteMesAttendanceRecordsByIds(ids)); // } + + /** + * 同步hr系统出勤记录信息 + * **/ + @PostMapping("/syncHrAttendance") + public AjaxResult syncHrAttendance() { + return mesAttendanceRecordsService.syncHrAttendance(); + } + + /** + * 获取岗位人员出勤列表 + * **/ + @RequiresPermissions("mes:AttendanceRecords:list") + @GetMapping("/postAttendance/list") + public TableDataInfo getPostAttendanceList(MesPostAttendanceRecords mesAttendanceRecords) + { + startPage(); + List list = mesAttendanceRecordsService.getPostAttendanceList(mesAttendanceRecords); + return getDataTable(list); + } + + + /** + * 导出岗位出勤列表 + */ + @RequiresPermissions("mes:AttendanceRecords:export") + @PostMapping("/postAttendance/export") + public void exportPostAttendance(HttpServletResponse response, MesPostAttendanceRecords mesAttendanceRecords) + { + List list = mesAttendanceRecordsService.getPostAttendanceList(mesAttendanceRecords); + ExcelUtil util = new ExcelUtil(MesPostAttendanceRecords.class); + util.exportExcel(response, list, "岗位出勤数据"); + } + } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/domain/MesPostAttendanceRecords.java b/op-modules/op-mes/src/main/java/com/op/mes/domain/MesPostAttendanceRecords.java new file mode 100644 index 000000000..bbfaf2e6b --- /dev/null +++ b/op-modules/op-mes/src/main/java/com/op/mes/domain/MesPostAttendanceRecords.java @@ -0,0 +1,98 @@ +package com.op.mes.domain; + +import com.op.common.core.annotation.Excel; + +/** + * remark + * + * @author 019117 + * @date + */ +public class MesPostAttendanceRecords { + + @Excel(name = "排序") + private String sort; + + @Excel(name = "岗位") + private String post; + + @Excel(name = "总人数") + private String allNum; + + @Excel(name = "出勤人数") + private String attendNum; + + @Excel(name = "缺勤人数") + private String diffNum; + + private String beginDate; + + private String endDate; + + private String deptId; + + + public String getSort() { + return sort; + } + + public void setSort(String sort) { + this.sort = sort; + } + + public String getPost() { + return post; + } + + public void setPost(String post) { + this.post = post; + } + + public String getAllNum() { + return allNum; + } + + public void setAllNum(String allNum) { + this.allNum = allNum; + } + + public String getAttendNum() { + return attendNum; + } + + public void setAttendNum(String attendNum) { + this.attendNum = attendNum; + } + + public String getDiffNum() { + return diffNum; + } + + public void setDiffNum(String diffNum) { + this.diffNum = diffNum; + } + + public String getBeginDate() { + return beginDate; + } + + public void setBeginDate(String beginDate) { + this.beginDate = beginDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } +} diff --git a/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesAttendanceRecordsMapper.java b/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesAttendanceRecordsMapper.java index 8823c336b..9db293c20 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesAttendanceRecordsMapper.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesAttendanceRecordsMapper.java @@ -2,6 +2,7 @@ package com.op.mes.mapper; import java.util.List; import com.op.mes.domain.MesAttendanceRecords; +import com.op.mes.domain.MesPostAttendanceRecords; /** * MES打卡记录Mapper接口 @@ -61,4 +62,11 @@ public interface MesAttendanceRecordsMapper List selectMesClockRecord(MesAttendanceRecords mesAttendanceRecords); + + + List selectMesPersonList(String deptId); + + int batchAttendanceRecords(List list); + + List getPostAttendanceList(MesPostAttendanceRecords params); } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/service/IMesAttendanceRecordsService.java b/op-modules/op-mes/src/main/java/com/op/mes/service/IMesAttendanceRecordsService.java index f0819b23f..3719f5c1b 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/service/IMesAttendanceRecordsService.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/service/IMesAttendanceRecordsService.java @@ -1,7 +1,9 @@ package com.op.mes.service; import java.util.List; +import com.op.common.core.web.domain.AjaxResult; import com.op.mes.domain.MesAttendanceRecords; +import com.op.mes.domain.MesPostAttendanceRecords; /** * MES打卡记录Service接口 @@ -58,4 +60,11 @@ public interface IMesAttendanceRecordsService * @return 结果 */ public int deleteMesAttendanceRecordsById(String id); + + AjaxResult syncHrAttendance(); + + List getPostAttendanceList(MesPostAttendanceRecords params); + + + } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesAttendanceRecordsServiceImpl.java b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesAttendanceRecordsServiceImpl.java index 167eb9f2f..70f0eb60e 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesAttendanceRecordsServiceImpl.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesAttendanceRecordsServiceImpl.java @@ -1,15 +1,32 @@ package com.op.mes.service.impl; -import java.util.ArrayList; -import java.util.List; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +import com.op.common.core.domain.R; import com.op.common.core.utils.DateUtils; +import com.op.common.core.utils.uuid.IdUtils; +import com.op.common.core.web.domain.AjaxResult; +import com.op.mes.domain.MesPostAttendanceRecords; +import com.op.system.api.RemoteOpenService; +import com.op.system.api.RemoteUserService; +import com.op.system.api.domain.SysUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.op.mes.mapper.MesAttendanceRecordsMapper; import com.op.mes.domain.MesAttendanceRecords; import com.op.mes.service.IMesAttendanceRecordsService; +import org.springframework.util.CollectionUtils; + +import static com.op.common.core.web.domain.AjaxResult.error; +import static com.op.common.core.web.domain.AjaxResult.success; /** * MES打卡记录Service业务层处理 @@ -23,6 +40,14 @@ public class MesAttendanceRecordsServiceImpl implements IMesAttendanceRecordsSer @Autowired private MesAttendanceRecordsMapper mesAttendanceRecordsMapper; + + @Autowired + private RemoteOpenService remoteOpenService; + + @Autowired + private RemoteUserService remoteUserService; + + /** * 查询MES打卡记录 * @@ -96,4 +121,119 @@ public class MesAttendanceRecordsServiceImpl implements IMesAttendanceRecordsSer { return mesAttendanceRecordsMapper.deleteMesAttendanceRecordsById(id); } + + + @Override + public AjaxResult syncHrAttendance() { + // 加载sf-cloud库的sys_datasource + SysUser sysUser = new SysUser(); + sysUser.setUserId(1L); + DynamicDataSourceContextHolder.push("master"); + R>> dateSources0 = new R<>(); + try { + dateSources0 = remoteUserService.getPoolNameList(sysUser); + }finally { + DynamicDataSourceContextHolder.poll(); + } + List> dateSources = dateSources0.getData(); + ExecutorService executorService = new ThreadPoolExecutor( + dateSources.size(), + dateSources.size(), + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue()); + try { + dateSources.forEach(dateSource -> { + if("ds_1000".equals(dateSource.get("poolName"))){ + + Runnable run = () -> { + DynamicDataSourceContextHolder.push(dateSource.get("poolName")); + + //不同工厂使用不同的deptId + String deptId = "10000152"; + + //查询当前生效的车间人员信息 + List personList = mesAttendanceRecordsMapper.selectMesPersonList(deptId); + + //查询当天人员打开记录 + Map paramMap = new HashMap<>(); + paramMap.put("bd", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.getNowDate())); + paramMap.put("ed", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.getNowDate())); + AjaxResult result = remoteOpenService.getAttRecord(paramMap); + List attendanceRecords = new ArrayList<>(); + if (result.isSuccess()){ + List> attList = (List>) result.get("data"); + + //循环遍历出车间人员打开记录 + for (Map map : attList){ + for (MesAttendanceRecords person : personList) + if (person.getUserId().equals(map.get("empcode"))){ + MesAttendanceRecords attendanceRecord = new MesAttendanceRecords(); + attendanceRecord.setId(IdUtils.fastSimpleUUID()); + attendanceRecord.setUserId(person.getUserId()); + attendanceRecord.setUserName(person.getUserName()); + attendanceRecord.setAttendanceStatus("正常"); + attendanceRecord.setSex(person.getSex()); + Date attendTime = extractAttendTime(map.get("strdata")); + attendanceRecord.setStartTime(attendTime); + attendanceRecord.setAttendanceTime("07:30-19:30"); + attendanceRecord.setAttendanceDate(attendTime); + attendanceRecord.setWorkHours(0L); + attendanceRecord.setCreateTime(new Date()); + attendanceRecord.setPost(person.getPost()); + attendanceRecords.add(attendanceRecord); + } + } + //插入人员打卡记录 + if (!CollectionUtils.isEmpty(attendanceRecords)){ + mesAttendanceRecordsMapper.batchAttendanceRecords(attendanceRecords); + } + } + }; + executorService.execute(run); + } + }); + } catch (Exception e) { + return error("service == createCPBatchTask == exception"); + } finally { + executorService.shutdown(); + } + return success(); + } + + @Override + @DS("#header.poolName") + public List getPostAttendanceList(MesPostAttendanceRecords params) { + //目前只有小榄工厂黑蚊香车间 + params.setDeptId("10000152"); + return mesAttendanceRecordsMapper.getPostAttendanceList(params); + } + + private static Date extractAttendTime(String data) { + // 校验输入是否为空 + if (data == null || data.trim().isEmpty()) { + System.out.println("输入字符串不能为空"); + return null; + } + + // 按照空格分割字符串 + String[] parts = data.split(" "); + + // 校验分割后的数组长度是否符合预期 + if (parts.length < 6) { + System.out.println("输入字符串格式不正确,无法提取时间"); + return null; + } + + // 拼接日期和时间部分 + String datetimeStr = parts[4] + " " + parts[5]; + + // 定义日期格式并进行转换 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d HH:mm:ss"); + try { + return sdf.parse(datetimeStr); + } catch (ParseException e) { + System.out.println("时间格式解析错误: " + e.getMessage()); + return null; + } + } } diff --git a/op-modules/op-mes/src/main/resources/mapper/mes/MesAttendanceRecordsMapper.xml b/op-modules/op-mes/src/main/resources/mapper/mes/MesAttendanceRecordsMapper.xml index d51c9ebda..f4e93bd3a 100644 --- a/op-modules/op-mes/src/main/resources/mapper/mes/MesAttendanceRecordsMapper.xml +++ b/op-modules/op-mes/src/main/resources/mapper/mes/MesAttendanceRecordsMapper.xml @@ -169,4 +169,111 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} + + + + + + + INSERT INTO mes_attendance_records ( + id, + user_id, + user_name, + attendance_status, + sex, + start_time, + attendance_time, + attendance_date, + work_hours, + create_time, + post + ) + SELECT + temp.id, + temp.userId, + temp.userName, + temp.attendanceStatus, + temp.sex, + temp.startTime, + temp.attendanceTime, + temp.attendanceDate, + temp.workHours, + temp.createTime, + temp.post + FROM ( + + SELECT + #{item.id, jdbcType=VARCHAR} AS id, + #{item.userId, jdbcType=VARCHAR} AS userId, + #{item.userName, jdbcType=VARCHAR} AS userName, + #{item.attendanceStatus, jdbcType=VARCHAR} AS attendanceStatus, + #{item.sex, jdbcType=VARCHAR} AS sex, + #{item.startTime, jdbcType=TIMESTAMP} AS startTime, + #{item.attendanceTime, jdbcType=VARCHAR} AS attendanceTime, + #{item.attendanceDate, jdbcType=TIMESTAMP} AS attendanceDate, + #{item.workHours, jdbcType=DECIMAL} AS workHours, + #{item.createTime, jdbcType=TIMESTAMP} AS createTime, + #{item.post, jdbcType=VARCHAR} AS post + + ) AS temp + WHERE NOT EXISTS ( + SELECT 1 + FROM mes_attendance_records target + WHERE target.user_id = temp.userId + AND target.start_time = temp.startTime + ) + + + + + diff --git a/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml b/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml index 400c40a7b..47bfef884 100644 --- a/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml +++ b/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml @@ -203,7 +203,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sf1.factory_name carName, sf.equipment_code machineCode, sf.equipment_name machineName, - mrw.workorder_code workorderCode, + RIGHT(wo.workorder_code_sap, 9) workorderCode, mrw.batch batch, mrw.product_code productCode, mrw.product_name productName, @@ -215,6 +215,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join base_equipment sf on sf.equipment_code = mrw.machine_code left join sys_factory sf1 on sf.workshop_code = sf1.factory_code left join sys_factory sf2 on sf1.parent_id = sf2.factory_id + LEFT JOIN pro_order_workorder wo ON wo.workorder_code = mrw.workorder_code where mrw.parent_order = '0' and mrw.del_flag = '0' and sf.equipment_name like concat('%', #{machineName}, '%') and sf1.factory_name like concat('%', #{carName}, '%')