9 changed files with 1072 additions and 0 deletions
-
112src/main/java/com/gaotao/modules/shopOrder/controller/WorkOrderAllocController.java
-
81src/main/java/com/gaotao/modules/shopOrder/dao/WorkOrderAllocMapper.java
-
129src/main/java/com/gaotao/modules/shopOrder/entity/UspWorkOrderAllocData.java
-
105src/main/java/com/gaotao/modules/shopOrder/entity/dto/U8WorkHourRequestDto.java
-
32src/main/java/com/gaotao/modules/shopOrder/entity/dto/U8WorkHourResponseDto.java
-
294src/main/java/com/gaotao/modules/shopOrder/service/Impl/WorkOrderAllocServiceImpl.java
-
47src/main/java/com/gaotao/modules/shopOrder/service/WorkOrderAllocService.java
-
5src/main/resources/application-dev.yml
-
267src/main/resources/mapper/shopOrder/WorkOrderAllocMapper.xml
@ -0,0 +1,112 @@ |
|||||
|
package com.gaotao.modules.shopOrder.controller; |
||||
|
|
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.common.utils.R; |
||||
|
import com.gaotao.modules.pda.utils.ResponseData; |
||||
|
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
||||
|
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
||||
|
import com.gaotao.modules.shopOrder.service.WorkOrderAllocService; |
||||
|
import com.gaotao.modules.sys.controller.AbstractController; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总控制器 |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@RestController |
||||
|
@RequestMapping("/shopOrder/workOrderAlloc") |
||||
|
public class WorkOrderAllocController extends AbstractController { |
||||
|
|
||||
|
@Autowired |
||||
|
private WorkOrderAllocService workOrderAllocService; |
||||
|
|
||||
|
/** |
||||
|
* 分页查询生产订单(工单数据汇总专用) |
||||
|
*/ |
||||
|
@PostMapping("/searchShopOrder") |
||||
|
public R searchShopOrder(@RequestBody SearchShopOrder query) { |
||||
|
// 设置当前用户 |
||||
|
if (query.getUser() == null || query.getUser().isEmpty()) { |
||||
|
query.setUser(getUser().getUsername()); |
||||
|
} |
||||
|
PageUtils page = workOrderAllocService.searchShopOrderForAlloc(query); |
||||
|
return R.ok().put("page", page); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询工单汇总数据(根据allocType) |
||||
|
*/ |
||||
|
@PostMapping("/list") |
||||
|
public R list(@RequestBody UspWorkOrderAllocData params) { |
||||
|
List<UspWorkOrderAllocData> list = workOrderAllocService.selectByAllocType(params); |
||||
|
|
||||
|
// 手动分页处理 |
||||
|
int totalCount = list.size(); |
||||
|
int pageSize = params.getLimit() > 0 ? params.getLimit() : 20; |
||||
|
int offset = params.getPage(); |
||||
|
int currPage = offset / pageSize + 1; |
||||
|
|
||||
|
int fromIndex = offset; |
||||
|
int toIndex = Math.min(fromIndex + pageSize, totalCount); |
||||
|
|
||||
|
List<UspWorkOrderAllocData> pageList; |
||||
|
if (fromIndex < totalCount) { |
||||
|
pageList = list.subList(fromIndex, toIndex); |
||||
|
} else { |
||||
|
pageList = new ArrayList<>(); |
||||
|
} |
||||
|
|
||||
|
PageUtils page = new PageUtils(pageList, totalCount, pageSize, currPage); |
||||
|
return R.ok().put("page", page); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行工单数据汇总(调用存储过程) |
||||
|
*/ |
||||
|
@PostMapping("/executeAlloc") |
||||
|
public R executeAlloc(@RequestBody WorkOrderAllocRequest request) { |
||||
|
String currentUser = getUser().getUsername(); |
||||
|
|
||||
|
ResponseData response = workOrderAllocService.executeWorkOrderAlloc( |
||||
|
request.getQuery(), |
||||
|
request.getOrderNoList(), |
||||
|
currentUser, |
||||
|
request.isAllocAll() |
||||
|
); |
||||
|
|
||||
|
if (response.isSuccess()) { |
||||
|
return R.ok(response.getMsg()); |
||||
|
} else { |
||||
|
return R.error(response.getMsg()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行工单数据回传(调用U8接口) |
||||
|
*/ |
||||
|
@PostMapping("/executeSync") |
||||
|
public R executeSync(@RequestBody UspWorkOrderAllocData params) { |
||||
|
ResponseData response = workOrderAllocService.executeWorkOrderSync(params); |
||||
|
if (response.isSuccess()) { |
||||
|
return R.ok(response.getMsg()); |
||||
|
} else { |
||||
|
return R.error(response.getMsg()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总请求DTO |
||||
|
*/ |
||||
|
@lombok.Data |
||||
|
public static class WorkOrderAllocRequest { |
||||
|
private SearchShopOrder query; |
||||
|
private List<String> orderNoList; |
||||
|
private boolean allocAll; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
package com.gaotao.modules.shopOrder.dao; |
||||
|
|
||||
|
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
||||
|
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总Mapper |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@Mapper |
||||
|
@Repository |
||||
|
public interface WorkOrderAllocMapper { |
||||
|
|
||||
|
/** |
||||
|
* 分页查询生产订单(工单数据汇总专用) |
||||
|
* @param query 查询条件 |
||||
|
* @return 生产订单列表 |
||||
|
*/ |
||||
|
List<SearchShopOrder> searchShopOrderForAlloc(@Param("query") SearchShopOrder query); |
||||
|
|
||||
|
/** |
||||
|
* 根据allocType查询工单汇总数据 |
||||
|
* @param data 查询条件 |
||||
|
* @return 汇总数据列表 |
||||
|
*/ |
||||
|
List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data); |
||||
|
|
||||
|
/** |
||||
|
* 查询未传输的数据(产量未传输或工时未传输) |
||||
|
* @param data 查询条件 |
||||
|
* @return 未传输数据列表 |
||||
|
*/ |
||||
|
List<UspWorkOrderAllocData> selectUnSyncedData(UspWorkOrderAllocData data); |
||||
|
|
||||
|
/** |
||||
|
* 更新SFDC表的synced_code和synced_flag |
||||
|
* @param site 工厂编码 |
||||
|
* @param orderNo 订单号 |
||||
|
* @param batchNo 批次号 |
||||
|
* @param syncedCode 同步单号 |
||||
|
*/ |
||||
|
void updateSfdcSyncedCode(@Param("site") String site, |
||||
|
@Param("orderNo") String orderNo, |
||||
|
@Param("batchNo") String batchNo, |
||||
|
@Param("syncedCode") String syncedCode); |
||||
|
|
||||
|
/** |
||||
|
* 更新UspWorkOrderAlloc的同步异常信息 |
||||
|
* @param site 工厂编码 |
||||
|
* @param orderNo 订单号 |
||||
|
* @param rowNo 行号 |
||||
|
* @param syncedDate 同步时间 |
||||
|
* @param syncedMes 异常信息 |
||||
|
*/ |
||||
|
void updateAllocSyncedError(@Param("site") String site, |
||||
|
@Param("orderNo") String orderNo, |
||||
|
@Param("rowNo") String rowNo, |
||||
|
@Param("syncedDate") Date syncedDate, |
||||
|
@Param("syncedMes") String syncedMes); |
||||
|
|
||||
|
/** |
||||
|
* 插入临时表(单条) |
||||
|
* @param site 工厂编码 |
||||
|
* @param orderNo 订单号 |
||||
|
*/ |
||||
|
void insertAllocTemp(@Param("site") String site, |
||||
|
@Param("orderNo") String orderNo); |
||||
|
|
||||
|
/** |
||||
|
* 批量插入临时表(根据查询条件) |
||||
|
* @param query 查询条件 |
||||
|
*/ |
||||
|
void insertAllocTempByQuery(@Param("query") SearchShopOrder query); |
||||
|
} |
||||
@ -0,0 +1,129 @@ |
|||||
|
package com.gaotao.modules.shopOrder.entity; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import com.gaotao.common.utils.QueryPage; |
||||
|
import lombok.Data; |
||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总实体类 |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class UspWorkOrderAllocData extends QueryPage { |
||||
|
|
||||
|
/** |
||||
|
* 工厂编码 |
||||
|
*/ |
||||
|
private String site; |
||||
|
|
||||
|
/** |
||||
|
* 生产订单号 |
||||
|
*/ |
||||
|
private String orderNo; |
||||
|
|
||||
|
/** |
||||
|
* ERP订单号 |
||||
|
*/ |
||||
|
private String erpOrderNo; |
||||
|
|
||||
|
/** |
||||
|
* ERP订单行号 |
||||
|
*/ |
||||
|
private String erpOrderLineNo; |
||||
|
|
||||
|
/** |
||||
|
* 行号 |
||||
|
*/ |
||||
|
private String rowNo; |
||||
|
|
||||
|
/** |
||||
|
* 工序号 |
||||
|
*/ |
||||
|
private String itemNo; |
||||
|
|
||||
|
/** |
||||
|
* 操作员 |
||||
|
*/ |
||||
|
private String operator; |
||||
|
|
||||
|
/** |
||||
|
* 报告数量 |
||||
|
*/ |
||||
|
private Double allocReportQty; |
||||
|
|
||||
|
/** |
||||
|
* 合格数量 |
||||
|
*/ |
||||
|
private Double allocApproveQty; |
||||
|
|
||||
|
/** |
||||
|
* 不良数量 |
||||
|
*/ |
||||
|
private Double allocScrapQty; |
||||
|
|
||||
|
/** |
||||
|
* 数据类型(产量未传输、产量已传输、工时未传输、工时已传输) |
||||
|
*/ |
||||
|
private String allocType; |
||||
|
|
||||
|
/** |
||||
|
* 汇总操作人 |
||||
|
*/ |
||||
|
private String allocBy; |
||||
|
|
||||
|
/** |
||||
|
* 汇总时间 |
||||
|
*/ |
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date allocDate; |
||||
|
|
||||
|
/** |
||||
|
* 调机时长 |
||||
|
*/ |
||||
|
private BigDecimal allocSetupTime; |
||||
|
|
||||
|
/** |
||||
|
* 制造时长 |
||||
|
*/ |
||||
|
private BigDecimal allocManfTime; |
||||
|
|
||||
|
/** |
||||
|
* 回传时间 |
||||
|
*/ |
||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
||||
|
private Date syncedDate; |
||||
|
|
||||
|
/** |
||||
|
* 异常原因 |
||||
|
*/ |
||||
|
private String syncedMes; |
||||
|
|
||||
|
/** |
||||
|
* 批次号 |
||||
|
*/ |
||||
|
private String batchNo; |
||||
|
|
||||
|
/** |
||||
|
* 当前登录人 |
||||
|
*/ |
||||
|
private String currentUser; |
||||
|
|
||||
|
/** |
||||
|
* 查询的allocType列表(用于批量查询) |
||||
|
*/ |
||||
|
private List<String> allocTypeList; |
||||
|
|
||||
|
/** |
||||
|
* 批量勾选的工单号列表 |
||||
|
*/ |
||||
|
private List<String> orderNoList; |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,105 @@ |
|||||
|
package com.gaotao.modules.shopOrder.entity.dto; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* U8生产报工档案接口请求DTO |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class U8WorkHourRequestDto { |
||||
|
|
||||
|
/** |
||||
|
* 生产订单号 |
||||
|
*/ |
||||
|
@JsonProperty("Mocode") |
||||
|
private String mocode; |
||||
|
|
||||
|
/** |
||||
|
* 订单行号 |
||||
|
*/ |
||||
|
@JsonProperty("IrowNo") |
||||
|
private String irowNo; |
||||
|
|
||||
|
/** |
||||
|
* 汇总日期 |
||||
|
*/ |
||||
|
@JsonProperty("DDate") |
||||
|
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
||||
|
private Date dDate; |
||||
|
|
||||
|
/** |
||||
|
* 明细列表 |
||||
|
*/ |
||||
|
@JsonProperty("DetailList") |
||||
|
private List<DetailItem> detailList; |
||||
|
|
||||
|
/** |
||||
|
* 明细项 |
||||
|
*/ |
||||
|
@Data |
||||
|
public static class DetailItem { |
||||
|
|
||||
|
/** |
||||
|
* MES行号 |
||||
|
*/ |
||||
|
@JsonProperty("MESIrowNo") |
||||
|
private String mesIrowNo; |
||||
|
|
||||
|
/** |
||||
|
* 工序号 |
||||
|
*/ |
||||
|
@JsonProperty("SortSeq") |
||||
|
private String sortSeq; |
||||
|
|
||||
|
/** |
||||
|
* 设备编码 |
||||
|
*/ |
||||
|
@JsonProperty("EQId") |
||||
|
private String eqId; |
||||
|
|
||||
|
/** |
||||
|
* 班次编码 |
||||
|
*/ |
||||
|
@JsonProperty("DutyClassCode") |
||||
|
private String dutyClassCode; |
||||
|
|
||||
|
/** |
||||
|
* 员工编码 |
||||
|
*/ |
||||
|
@JsonProperty("EmployCode") |
||||
|
private String employCode; |
||||
|
|
||||
|
/** |
||||
|
* 合格数量 |
||||
|
*/ |
||||
|
@JsonProperty("QualifiedQty") |
||||
|
private Double qualifiedQty; |
||||
|
|
||||
|
/** |
||||
|
* 不合格数量 |
||||
|
*/ |
||||
|
@JsonProperty("RefusedQty") |
||||
|
private String refusedQty; |
||||
|
|
||||
|
/** |
||||
|
* 报废数量 |
||||
|
*/ |
||||
|
@JsonProperty("ScrapQty") |
||||
|
private Double scrapQty; |
||||
|
|
||||
|
/** |
||||
|
* 工时(调机时长+制造时长) |
||||
|
*/ |
||||
|
@JsonProperty("WorkHr") |
||||
|
private BigDecimal workHr; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,32 @@ |
|||||
|
package com.gaotao.modules.shopOrder.entity.dto; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* U8生产报工档案接口响应DTO |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class U8WorkHourResponseDto { |
||||
|
|
||||
|
/** |
||||
|
* 标记:failure:错误,success 成功 |
||||
|
*/ |
||||
|
@JsonProperty("Flag") |
||||
|
private String flag; |
||||
|
|
||||
|
/** |
||||
|
* success 时返回U8单号 |
||||
|
*/ |
||||
|
@JsonProperty("U8CCode") |
||||
|
private String u8CCode; |
||||
|
|
||||
|
/** |
||||
|
* 错误消息,成功则不返回 |
||||
|
*/ |
||||
|
@JsonProperty("ErrMsg") |
||||
|
private String errMsg; |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,294 @@ |
|||||
|
package com.gaotao.modules.shopOrder.service.Impl; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.modules.pda.utils.ResponseData; |
||||
|
import com.gaotao.modules.pms.util.HttpClientUtil; |
||||
|
import com.gaotao.modules.report.dao.ProcedureDao; |
||||
|
import com.gaotao.modules.shopOrder.dao.WorkOrderAllocMapper; |
||||
|
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
||||
|
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
||||
|
import com.gaotao.modules.shopOrder.entity.dto.U8WorkHourRequestDto; |
||||
|
import com.gaotao.modules.shopOrder.entity.dto.U8WorkHourResponseDto; |
||||
|
import com.gaotao.modules.shopOrder.service.WorkOrderAllocService; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.*; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总服务实现类 |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Service |
||||
|
public class WorkOrderAllocServiceImpl implements WorkOrderAllocService { |
||||
|
|
||||
|
@Autowired |
||||
|
private WorkOrderAllocMapper workOrderAllocMapper; |
||||
|
|
||||
|
@Autowired |
||||
|
private ProcedureDao procedureDao; |
||||
|
|
||||
|
/** |
||||
|
* U8接口地址,从配置文件读取 |
||||
|
*/ |
||||
|
@Value("${u8.workhour.add.url:}") |
||||
|
private String u8WorkHourAddUrl; |
||||
|
|
||||
|
@Override |
||||
|
public PageUtils searchShopOrderForAlloc(SearchShopOrder query) { |
||||
|
// 查询数据 |
||||
|
List<SearchShopOrder> list = workOrderAllocMapper.searchShopOrderForAlloc(query); |
||||
|
|
||||
|
// 构建分页结果 |
||||
|
int total = list.size(); |
||||
|
int pageSize = query.getLimit() > 0 ? query.getLimit() : 20; |
||||
|
int offset = query.getPage(); |
||||
|
int currPage = offset / pageSize + 1; |
||||
|
|
||||
|
// 手动分页处理 |
||||
|
int fromIndex = offset; |
||||
|
int toIndex = Math.min(fromIndex + pageSize, total); |
||||
|
|
||||
|
List<SearchShopOrder> pageList; |
||||
|
if (fromIndex < total) { |
||||
|
pageList = list.subList(fromIndex, toIndex); |
||||
|
} else { |
||||
|
pageList = new ArrayList<>(); |
||||
|
} |
||||
|
|
||||
|
return new PageUtils(pageList, total, pageSize, currPage); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data) { |
||||
|
return workOrderAllocMapper.selectByAllocType(data); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional(rollbackFor = Exception.class) |
||||
|
public ResponseData executeWorkOrderAlloc(SearchShopOrder query, List<String> orderNoList, String currentUser, boolean allocAll) { |
||||
|
ResponseData responseData = new ResponseData(); |
||||
|
try { |
||||
|
log.info("开始执行工单数据汇总,操作人:{},汇总所有:{}", currentUser, allocAll); |
||||
|
|
||||
|
// 1. 插入临时表(存储过程会先清空临时表) |
||||
|
if (allocAll) { |
||||
|
// 汇总所有:根据查询条件插入临时表 |
||||
|
workOrderAllocMapper.insertAllocTempByQuery(query); |
||||
|
log.info("已根据查询条件插入临时表"); |
||||
|
} else { |
||||
|
// 汇总选中的:逐条插入临时表 |
||||
|
String site = query.getSite() != null ? query.getSite() : ""; |
||||
|
for (String orderNo : orderNoList) { |
||||
|
workOrderAllocMapper.insertAllocTemp(site, orderNo); |
||||
|
} |
||||
|
log.info("已插入{}条选中的工单到临时表", orderNoList.size()); |
||||
|
} |
||||
|
|
||||
|
// 2. 调用存储过程,orderNo传空字符串 |
||||
|
List<Object> params = new ArrayList<>(); |
||||
|
params.add(query.getSite() != null ? query.getSite() : ""); |
||||
|
params.add(""); // orderNo传空字符串 |
||||
|
params.add(currentUser); |
||||
|
|
||||
|
List<Map<String, Object>> resultList = procedureDao.getProcedureData("UspInsertWorkOrderAlloc", params); |
||||
|
|
||||
|
// 3. 判断执行结果 |
||||
|
String resultMsg = "工单数据汇总完成"; |
||||
|
if (resultList != null && !resultList.isEmpty()) { |
||||
|
String code = String.valueOf(resultList.get(0).get("resultCode")); |
||||
|
if ("400".equalsIgnoreCase(code)) { |
||||
|
String msg = String.valueOf(resultList.get(0).get("resultMsg")); |
||||
|
responseData.setCode("500"); |
||||
|
responseData.setSuccess(false); |
||||
|
responseData.setMsg("工单数据汇总失败: " + msg); |
||||
|
return responseData; |
||||
|
} |
||||
|
// 获取返回消息 |
||||
|
if (resultList.get(0).get("resultMsg") != null) { |
||||
|
resultMsg = String.valueOf(resultList.get(0).get("resultMsg")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
responseData.setCode("200"); |
||||
|
responseData.setSuccess(true); |
||||
|
responseData.setMsg(resultMsg); |
||||
|
log.info("工单数据汇总成功:{}", resultMsg); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error("执行工单数据汇总时发生异常", e); |
||||
|
responseData.setCode("500"); |
||||
|
responseData.setSuccess(false); |
||||
|
responseData.setMsg("执行工单数据汇总时发生异常: " + e.getMessage()); |
||||
|
} |
||||
|
return responseData; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional(rollbackFor = Exception.class) |
||||
|
public ResponseData executeWorkOrderSync(UspWorkOrderAllocData data) { |
||||
|
ResponseData responseData = new ResponseData(); |
||||
|
try { |
||||
|
log.info("开始执行工单数据回传"); |
||||
|
|
||||
|
// 1. 查询未传输的数据 |
||||
|
List<UspWorkOrderAllocData> unSyncedList = workOrderAllocMapper.selectUnSyncedData(data); |
||||
|
|
||||
|
if (unSyncedList == null || unSyncedList.isEmpty()) { |
||||
|
responseData.setCode("200"); |
||||
|
responseData.setSuccess(true); |
||||
|
responseData.setMsg("没有需要回传的数据"); |
||||
|
return responseData; |
||||
|
} |
||||
|
|
||||
|
log.info("查询到{}条待回传数据", unSyncedList.size()); |
||||
|
|
||||
|
int successCount = 0; |
||||
|
int failCount = 0; |
||||
|
StringBuilder errorMessages = new StringBuilder(); |
||||
|
|
||||
|
// 2. 按照erp_orderNo和erp_orderLineNo分组 |
||||
|
Map<String, List<UspWorkOrderAllocData>> groupedData = unSyncedList.stream() |
||||
|
.collect(Collectors.groupingBy(item -> |
||||
|
item.getErpOrderNo() + "_" + item.getErpOrderLineNo() + "_" + |
||||
|
(item.getAllocDate() != null ? item.getAllocDate().getTime() : ""))); |
||||
|
|
||||
|
// 3. 逐组调用U8接口 |
||||
|
for (Map.Entry<String, List<UspWorkOrderAllocData>> entry : groupedData.entrySet()) { |
||||
|
List<UspWorkOrderAllocData> groupItems = entry.getValue(); |
||||
|
if (groupItems.isEmpty()) continue; |
||||
|
|
||||
|
UspWorkOrderAllocData firstItem = groupItems.get(0); |
||||
|
|
||||
|
try { |
||||
|
// 构建U8请求参数 |
||||
|
U8WorkHourRequestDto requestDto = new U8WorkHourRequestDto(); |
||||
|
requestDto.setMocode(firstItem.getErpOrderNo()); |
||||
|
requestDto.setIrowNo(firstItem.getErpOrderLineNo()); |
||||
|
requestDto.setDDate(firstItem.getAllocDate()); |
||||
|
|
||||
|
List<U8WorkHourRequestDto.DetailItem> detailList = new ArrayList<>(); |
||||
|
for (UspWorkOrderAllocData item : groupItems) { |
||||
|
U8WorkHourRequestDto.DetailItem detailItem = new U8WorkHourRequestDto.DetailItem(); |
||||
|
detailItem.setMesIrowNo(item.getRowNo()); |
||||
|
detailItem.setSortSeq(item.getItemNo()); |
||||
|
detailItem.setEqId(""); |
||||
|
detailItem.setDutyClassCode(""); |
||||
|
detailItem.setEmployCode(item.getOperator()); |
||||
|
detailItem.setQualifiedQty(item.getAllocApproveQty()); |
||||
|
detailItem.setRefusedQty(""); |
||||
|
detailItem.setScrapQty(item.getAllocScrapQty()); |
||||
|
|
||||
|
// 计算工时:调机时长 + 制造时长 |
||||
|
BigDecimal workHr = BigDecimal.ZERO; |
||||
|
if (item.getAllocSetupTime() != null) { |
||||
|
workHr = workHr.add(item.getAllocSetupTime()); |
||||
|
} |
||||
|
if (item.getAllocManfTime() != null) { |
||||
|
workHr = workHr.add(item.getAllocManfTime()); |
||||
|
} |
||||
|
detailItem.setWorkHr(workHr); |
||||
|
|
||||
|
detailList.add(detailItem); |
||||
|
} |
||||
|
requestDto.setDetailList(detailList); |
||||
|
|
||||
|
// 调用U8接口 |
||||
|
log.info("调用U8接口,请求参数: {}", JSON.toJSONString(requestDto)); |
||||
|
com.gaotao.modules.pms.util.ResponseData httpResponse = |
||||
|
HttpClientUtil.doPostByRaw(u8WorkHourAddUrl, requestDto); |
||||
|
|
||||
|
if (httpResponse.isSuccess()) { |
||||
|
// 解析响应 |
||||
|
U8WorkHourResponseDto u8Response = JSON.parseObject(httpResponse.getMsg(), U8WorkHourResponseDto.class); |
||||
|
|
||||
|
if ("success".equalsIgnoreCase(u8Response.getFlag())) { |
||||
|
// 接口调用成功,更新SFDC表 |
||||
|
String u8CCode = u8Response.getU8CCode(); |
||||
|
for (UspWorkOrderAllocData item : groupItems) { |
||||
|
workOrderAllocMapper.updateSfdcSyncedCode( |
||||
|
item.getSite(), |
||||
|
item.getOrderNo(), |
||||
|
item.getBatchNo(), |
||||
|
u8CCode); |
||||
|
} |
||||
|
successCount += groupItems.size(); |
||||
|
log.info("U8接口调用成功,返回单号: {}", u8CCode); |
||||
|
} else { |
||||
|
// 接口返回错误 |
||||
|
String errMsg = u8Response.getErrMsg(); |
||||
|
for (UspWorkOrderAllocData item : groupItems) { |
||||
|
workOrderAllocMapper.updateAllocSyncedError( |
||||
|
item.getSite(), |
||||
|
item.getOrderNo(), |
||||
|
item.getRowNo(), |
||||
|
new Date(), |
||||
|
errMsg); |
||||
|
} |
||||
|
failCount += groupItems.size(); |
||||
|
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
||||
|
.append("回传失败: ").append(errMsg).append("; "); |
||||
|
log.error("U8接口返回错误: {}", errMsg); |
||||
|
} |
||||
|
} else { |
||||
|
// HTTP请求失败 |
||||
|
String errMsg = "HTTP请求失败: " + httpResponse.getMsg(); |
||||
|
for (UspWorkOrderAllocData item : groupItems) { |
||||
|
workOrderAllocMapper.updateAllocSyncedError( |
||||
|
item.getSite(), |
||||
|
item.getOrderNo(), |
||||
|
item.getRowNo(), |
||||
|
new Date(), |
||||
|
errMsg); |
||||
|
} |
||||
|
failCount += groupItems.size(); |
||||
|
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
||||
|
.append("回传失败: ").append(errMsg).append("; "); |
||||
|
log.error("调用U8接口HTTP请求失败: {}", httpResponse.getMsg()); |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
// 异常处理 |
||||
|
String errMsg = "处理异常: " + e.getMessage(); |
||||
|
for (UspWorkOrderAllocData item : groupItems) { |
||||
|
workOrderAllocMapper.updateAllocSyncedError( |
||||
|
item.getSite(), |
||||
|
item.getOrderNo(), |
||||
|
item.getRowNo(), |
||||
|
new Date(), |
||||
|
errMsg); |
||||
|
} |
||||
|
failCount += groupItems.size(); |
||||
|
errorMessages.append("订单").append(firstItem.getErpOrderNo()) |
||||
|
.append("回传异常: ").append(e.getMessage()).append("; "); |
||||
|
log.error("工单数据回传处理异常,订单号: {}", firstItem.getErpOrderNo(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 返回结果 |
||||
|
String resultMsg = String.format("工单数据回传完成,成功%d条,失败%d条", successCount, failCount); |
||||
|
if (failCount > 0) { |
||||
|
resultMsg += "。失败详情: " + errorMessages.toString(); |
||||
|
} |
||||
|
|
||||
|
responseData.setCode(failCount > 0 ? "500" : "200"); |
||||
|
responseData.setSuccess(failCount == 0); |
||||
|
responseData.setMsg(resultMsg); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error("执行工单数据回传时发生异常", e); |
||||
|
responseData.setCode("500"); |
||||
|
responseData.setSuccess(false); |
||||
|
responseData.setMsg("执行工单数据回传时发生异常: " + e.getMessage()); |
||||
|
} |
||||
|
return responseData; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
package com.gaotao.modules.shopOrder.service; |
||||
|
|
||||
|
import com.gaotao.common.utils.PageUtils; |
||||
|
import com.gaotao.modules.pda.utils.ResponseData; |
||||
|
import com.gaotao.modules.shopOrder.entity.SearchShopOrder; |
||||
|
import com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 工单数据汇总服务接口 |
||||
|
* @author system |
||||
|
* @date 2026/01/05 |
||||
|
*/ |
||||
|
public interface WorkOrderAllocService { |
||||
|
|
||||
|
/** |
||||
|
* 分页查询生产订单(工单数据汇总专用) |
||||
|
* @param query 查询条件 |
||||
|
* @return 分页结果 |
||||
|
*/ |
||||
|
PageUtils searchShopOrderForAlloc(SearchShopOrder query); |
||||
|
|
||||
|
/** |
||||
|
* 根据allocType查询工单汇总数据 |
||||
|
* @param data 查询条件 |
||||
|
* @return 汇总数据列表 |
||||
|
*/ |
||||
|
List<UspWorkOrderAllocData> selectByAllocType(UspWorkOrderAllocData data); |
||||
|
|
||||
|
/** |
||||
|
* 执行工单数据汇总(调用存储过程) |
||||
|
* @param query 查询条件(用于汇总所有时) |
||||
|
* @param orderNoList 工单号列表(选择的工单) |
||||
|
* @param currentUser 当前登录人 |
||||
|
* @param allocAll 是否汇总所有(true:汇总查询条件下所有工单,false:只汇总选中的) |
||||
|
* @return 执行结果 |
||||
|
*/ |
||||
|
ResponseData executeWorkOrderAlloc(SearchShopOrder query, List<String> orderNoList, String currentUser, boolean allocAll); |
||||
|
|
||||
|
/** |
||||
|
* 执行工单数据回传(调用U8接口) |
||||
|
* @param data 查询条件(包含工单筛选条件) |
||||
|
* @return 执行结果 |
||||
|
*/ |
||||
|
ResponseData executeWorkOrderSync(UspWorkOrderAllocData data); |
||||
|
} |
||||
@ -0,0 +1,267 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.gaotao.modules.shopOrder.dao.WorkOrderAllocMapper"> |
||||
|
|
||||
|
<!-- 分页查询生产订单(工单数据汇总专用) --> |
||||
|
<select id="searchShopOrderForAlloc" parameterType="com.gaotao.modules.shopOrder.entity.SearchShopOrder" resultType="com.gaotao.modules.shopOrder.entity.SearchShopOrder"> |
||||
|
Select |
||||
|
T.OrderNo, |
||||
|
T.NeedDate, |
||||
|
T.OrderType, |
||||
|
T.PartNo, |
||||
|
p.PartDescription + ' / ' + isnull(p.Spec, '') AS PartDescription, |
||||
|
T.LotSize, |
||||
|
T.Planner, |
||||
|
T.Status, |
||||
|
T.CustomerID, |
||||
|
P.ConfigurationTemplateID AS CustomerName, |
||||
|
T.PlanStartDate, |
||||
|
T.Leadtime, |
||||
|
T.EnterDate, |
||||
|
T.Username, |
||||
|
T.FinishedQty, |
||||
|
T.ReleaseDate, |
||||
|
T.ReleaseGuys, |
||||
|
T.ScheduleDate, |
||||
|
T.Scheduler, |
||||
|
T.IssueDate, |
||||
|
T.ReportDate, |
||||
|
T.ReceiveDate, |
||||
|
T.Printed, |
||||
|
T.ProjectID, |
||||
|
pr.ProjectName, |
||||
|
T.BOMRevNo, |
||||
|
T.RoutingRevNo, |
||||
|
T.OriginalNeedDate, |
||||
|
T.OrderRef1, |
||||
|
T.OrderRef2, |
||||
|
T.Site, |
||||
|
T.Remark, |
||||
|
CostRollUpFlag, |
||||
|
T.ManualFlag, |
||||
|
T.OriSOOrderNo, |
||||
|
P.FamilyID, |
||||
|
dbo.Get_PartFamilyDesc (P.Site, P.FamilyID) AS FamilyName, |
||||
|
P.GroupID, |
||||
|
dbo.Get_PartGroupDesc (P.Site, P.GroupID) AS GroupName, |
||||
|
T.ReceiveStatus, |
||||
|
T.RepairSOFlag, |
||||
|
T.E_OriginalOrderType, |
||||
|
T.E_OriginalOrderNo, |
||||
|
T.E_Levels, |
||||
|
P.PartType, |
||||
|
P.Remark AS CustPartNo, |
||||
|
T.NeedDate AS COPlanShipDate, |
||||
|
T.batch_no batchNo, |
||||
|
(SELECT COUNT(1) FROM SOScheduledRouting where Site = T.site and OrderNo = T.OrderNo) AS apsResourceTotal, |
||||
|
(SELECT COUNT(1) FROM SOScheduledRouting where Site = T.site and OrderNo = T.OrderNo AND QtyReported <![CDATA[<=]]> 0 AND TimeReported <![CDATA[<=]]> 0) AS notYetStartedResourceTotal, |
||||
|
0 alreadyApplyTotal |
||||
|
from Part as p,ShopOrder as T |
||||
|
left join Project as pr on pr.Site=T.Site and pr.Projectid=T.ProjectID |
||||
|
<where> |
||||
|
AND T.Site = p.Site and T.PartNo = p.PartNo |
||||
|
and T.site in (Select Site from AccessSite where upper(UserID)=#{query.user}) |
||||
|
<if test="query.orderType != null and query.orderType != ''"> |
||||
|
AND T.OrderType like '%' + #{query.orderType} + '%' |
||||
|
</if> |
||||
|
<if test="query.planner != null and query.planner != ''"> |
||||
|
AND T.Planner like '%' + #{query.planner} + '%' |
||||
|
</if> |
||||
|
<if test="query.site != null and query.site != ''"> |
||||
|
AND T.Site like '%' + #{query.site} + '%' |
||||
|
</if> |
||||
|
<if test="query.buNo != null and query.buNo != ''"> |
||||
|
AND T.bu_no like '%' + #{query.buNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.partType != null and query.partType != ''"> |
||||
|
AND P.PartType like '%' + #{query.partType} + '%' |
||||
|
</if> |
||||
|
<if test="query.partNo != null and query.partNo != ''"> |
||||
|
AND T.PartNo like '%' + #{query.partNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.status != null and query.status != ''"> |
||||
|
AND T.Status = #{query.status} |
||||
|
</if> |
||||
|
<if test="query.statusList != null and query.statusList.size > 0"> |
||||
|
AND T.Status in |
||||
|
<foreach item="item" collection="query.statusList" open="(" separator="," close=")"> |
||||
|
#{item} |
||||
|
</foreach> |
||||
|
</if> |
||||
|
<if test="query.partDescription != null and query.partDescription != ''"> |
||||
|
AND p.PartDescription like '%' + #{query.partDescription} + '%' |
||||
|
</if> |
||||
|
<if test="query.projectID != null and query.projectID != ''"> |
||||
|
AND T.ProjectID like '%' + #{query.projectID} + '%' |
||||
|
</if> |
||||
|
<if test="query.remark != null and query.remark != ''"> |
||||
|
AND T.Remark like '%' + #{query.remark} + '%' |
||||
|
</if> |
||||
|
<if test="query.orderNo != null and query.orderNo != ''"> |
||||
|
AND T.OrderNo like '%' + #{query.orderNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.orderRef1 != null and query.orderRef1 != ''"> |
||||
|
AND T.OrderRef1 like '%' + #{query.orderRef1} + '%' |
||||
|
</if> |
||||
|
<if test="query.costRollUpFlag != null and query.costRollUpFlag != ''"> |
||||
|
AND CostRollUpFlag like '%' + #{query.costRollUpFlag} + '%' |
||||
|
</if> |
||||
|
<if test="query.date1 != null"> |
||||
|
AND T.EnterDate >= #{query.date1} |
||||
|
</if> |
||||
|
<if test="query.date2 != null"> |
||||
|
AND dateadd(DAY, 1, #{query.date2}) > T.EnterDate |
||||
|
</if> |
||||
|
<if test="query.date3 != null"> |
||||
|
AND T.NeedDate >= #{query.date3} |
||||
|
</if> |
||||
|
<if test="query.date4 != null"> |
||||
|
AND dateadd(DAY, 1, #{query.date4}) > T.NeedDate |
||||
|
</if> |
||||
|
</where> |
||||
|
ORDER BY T.EnterDate DESC |
||||
|
</select> |
||||
|
|
||||
|
<!-- 根据allocType查询工单汇总数据 --> |
||||
|
<select id="selectByAllocType" parameterType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData" |
||||
|
resultType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData"> |
||||
|
SELECT |
||||
|
site, |
||||
|
orderNo, |
||||
|
batchNo, |
||||
|
erp_orderNo as erpOrderNo, |
||||
|
erp_orderLineNo as erpOrderLineNo, |
||||
|
rowNo, |
||||
|
itemNo, |
||||
|
operator, |
||||
|
allocReportQty, |
||||
|
allocApproveQty, |
||||
|
allocScrapQty, |
||||
|
allocSetupTime, |
||||
|
allocManfTime, |
||||
|
allocBy, |
||||
|
allocDate, |
||||
|
synced_date as syncedDate, |
||||
|
synced_mes as syncedMes, |
||||
|
allocType |
||||
|
FROM UspWorkOrderAlloc |
||||
|
<where> |
||||
|
<if test="site != null and site != ''"> |
||||
|
AND site = #{site} |
||||
|
</if> |
||||
|
<if test="orderNo != null and orderNo != ''"> |
||||
|
AND orderNo = #{orderNo} |
||||
|
</if> |
||||
|
<if test="allocType != null and allocType != ''"> |
||||
|
AND allocType = #{allocType} |
||||
|
</if> |
||||
|
</where> |
||||
|
ORDER BY allocDate DESC |
||||
|
</select> |
||||
|
|
||||
|
<!-- 查询未传输的数据 --> |
||||
|
<select id="selectUnSyncedData" parameterType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData" |
||||
|
resultType="com.gaotao.modules.shopOrder.entity.UspWorkOrderAllocData"> |
||||
|
SELECT |
||||
|
site, |
||||
|
orderNo, |
||||
|
batchNo, |
||||
|
erp_orderNo as erpOrderNo, |
||||
|
erp_orderLineNo as erpOrderLineNo, |
||||
|
rowNo, |
||||
|
itemNo, |
||||
|
operator, |
||||
|
allocReportQty, |
||||
|
allocApproveQty, |
||||
|
allocScrapQty, |
||||
|
allocSetupTime, |
||||
|
allocManfTime, |
||||
|
allocBy, |
||||
|
allocDate, |
||||
|
synced_date as syncedDate, |
||||
|
synced_mes as syncedMes, |
||||
|
allocType |
||||
|
FROM UspWorkOrderAlloc |
||||
|
<where> |
||||
|
AND (allocType = '产量未传输' OR allocType = '工时未传输') |
||||
|
<if test="site != null and site != ''"> |
||||
|
AND site = #{site} |
||||
|
</if> |
||||
|
<if test="orderNoList != null and orderNoList.size() > 0"> |
||||
|
AND orderNo IN |
||||
|
<foreach collection="orderNoList" item="item" open="(" separator="," close=")"> |
||||
|
#{item} |
||||
|
</foreach> |
||||
|
</if> |
||||
|
</where> |
||||
|
ORDER BY allocDate ASC |
||||
|
</select> |
||||
|
|
||||
|
<!-- 更新SFDC表的同步信息 --> |
||||
|
<update id="updateSfdcSyncedCode"> |
||||
|
UPDATE SFDC |
||||
|
SET synced_code = #{syncedCode}, |
||||
|
synced_flag = 'Y' |
||||
|
WHERE Site = #{site} |
||||
|
AND OrderNo = #{orderNo} |
||||
|
AND ItemNo = #{batchNo} |
||||
|
</update> |
||||
|
|
||||
|
<!-- 更新UspWorkOrderAlloc的同步异常信息 --> |
||||
|
<update id="updateAllocSyncedError"> |
||||
|
UPDATE UspWorkOrderAlloc |
||||
|
SET synced_date = #{syncedDate}, |
||||
|
synced_mes = #{syncedMes} |
||||
|
WHERE site = #{site} |
||||
|
AND orderNo = #{orderNo} |
||||
|
AND rowNo = #{rowNo} |
||||
|
</update> |
||||
|
|
||||
|
<!-- 插入临时表(单条) --> |
||||
|
<insert id="insertAllocTemp"> |
||||
|
INSERT INTO UspWorkOrderAllocTemp (site, orderNo) |
||||
|
VALUES (#{site}, #{orderNo}) |
||||
|
</insert> |
||||
|
|
||||
|
<!-- 根据查询条件批量插入临时表 --> |
||||
|
<insert id="insertAllocTempByQuery"> |
||||
|
INSERT INTO UspWorkOrderAllocTemp (site, orderNo) |
||||
|
SELECT T.Site, T.OrderNo |
||||
|
FROM ShopOrder T |
||||
|
LEFT JOIN Part P ON T.Site = P.Site AND T.PartNo = P.PartNo |
||||
|
<where> |
||||
|
AND T.site in (Select Site from AccessSite where upper(UserID)=#{query.user}) |
||||
|
<if test="query.orderType != null and query.orderType != ''"> |
||||
|
AND T.OrderType like '%' + #{query.orderType} + '%' |
||||
|
</if> |
||||
|
<if test="query.site != null and query.site != ''"> |
||||
|
AND T.Site like '%' + #{query.site} + '%' |
||||
|
</if> |
||||
|
<if test="query.partNo != null and query.partNo != ''"> |
||||
|
AND T.PartNo like '%' + #{query.partNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.status != null and query.status != ''"> |
||||
|
AND T.Status = #{query.status} |
||||
|
</if> |
||||
|
<if test="query.partDescription != null and query.partDescription != ''"> |
||||
|
AND P.PartDescription like '%' + #{query.partDescription} + '%' |
||||
|
</if> |
||||
|
<if test="query.orderNo != null and query.orderNo != ''"> |
||||
|
AND T.OrderNo like '%' + #{query.orderNo} + '%' |
||||
|
</if> |
||||
|
<if test="query.date1 != null"> |
||||
|
AND T.EnterDate >= #{query.date1} |
||||
|
</if> |
||||
|
<if test="query.date2 != null"> |
||||
|
AND dateadd(DAY, 1, #{query.date2}) > T.EnterDate |
||||
|
</if> |
||||
|
<if test="query.date3 != null"> |
||||
|
AND T.NeedDate >= #{query.date3} |
||||
|
</if> |
||||
|
<if test="query.date4 != null"> |
||||
|
AND dateadd(DAY, 1, #{query.date4}) > T.NeedDate |
||||
|
</if> |
||||
|
</where> |
||||
|
</insert> |
||||
|
|
||||
|
</mapper> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue