package com.aps.job.service.impl; import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aps.common.core.utils.DateUtils; import com.aps.job.domain.ApsWorkOrderJob; import com.aps.job.domain.ApsWorkOrderJobLog; import com.aps.job.mapper.ApsWorkOrderJobLogMapper; import com.aps.job.mapper.ApsWorkOrderJobMapper; import com.aps.job.param.ApsWorkOrderJobParam; import com.aps.job.service.IApsWorkOrderJobService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 工单同步Service业务层处理 * * @author zhl * @date 2025-04-17 */ @Slf4j @Service public class ApsWorkOrderJobServiceImpl implements IApsWorkOrderJobService { @Autowired private ApsWorkOrderJobMapper apsWorkOrderJobMapper; /** * 获取订单接口 * */ @Value("${u9.workOrderJobUrl}") private String getWorkOrderUrl; @Autowired private RestTemplate restTemplate; @Autowired private ApsWorkOrderJobLogMapper jobLogMapper; /** * 查询工单同步 * * @param id 工单同步主键 * @return 工单同步 */ @Override public ApsWorkOrderJob selectApsWorkOrderJobById(Long id) { return apsWorkOrderJobMapper.selectApsWorkOrderJobById(id); } /** * 查询工单同步列表 * * @param apsWorkOrderJob 工单同步 * @return 工单同步 */ @Override public List selectApsWorkOrderJobList(ApsWorkOrderJob apsWorkOrderJob) { return apsWorkOrderJobMapper.selectApsWorkOrderJobList(apsWorkOrderJob); } /** * 新增工单同步 * * @param apsWorkOrderJob 工单同步 * @return 结果 */ @Override public int insertApsWorkOrderJob(ApsWorkOrderJob apsWorkOrderJob) { apsWorkOrderJob.setCreateTime(DateUtils.getNowDate()); return apsWorkOrderJobMapper.insertApsWorkOrderJob(apsWorkOrderJob); } /** * 修改工单同步 * * @param apsWorkOrderJob 工单同步 * @return 结果 */ @Override public int updateApsWorkOrderJob(ApsWorkOrderJob apsWorkOrderJob) { apsWorkOrderJob.setUpdateTime(DateUtils.getNowDate()); return apsWorkOrderJobMapper.updateApsWorkOrderJob(apsWorkOrderJob); } /** * 批量删除工单同步 * * @param ids 需要删除的工单同步主键 * @return 结果 */ @Override public int deleteApsWorkOrderJobByIds(Long[] ids) { return apsWorkOrderJobMapper.deleteApsWorkOrderJobByIds(ids); } /** * 删除工单同步信息 * * @param id 工单同步主键 * @return 结果 */ @Override public int deleteApsWorkOrderJobById(Long id) { return apsWorkOrderJobMapper.deleteApsWorkOrderJobById(id); } /** * 根据页码全量同步数据 * */ @Override public void batchInsertApsWorkOrderJob(ApsWorkOrderJobParam param) { /*根据参数中当前页面 和 要目标页面 进行循环*/ for (int idx=param.getPageIndex(); idx<=param.getToPageIndex(); idx++){ param.setPageIndex(idx); if (!batchSaveByPager(param)) { return; } } } /** * 根据时间段每日更新,页面自动递增循环同步数据 * */ @Override public void SyncWorkOrderByTime(){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime today = LocalDateTime.now(); LocalDate yesterday = LocalDate.now().minusDays(1); LocalDateTime yesterdayMidnight = yesterday.atStartOfDay(); boolean continueFlag = true; Integer currentPage = 1; ApsWorkOrderJobParam param=new ApsWorkOrderJobParam(); param.setPageIndex(currentPage); param.setDocState(Arrays.asList(0,1,2,4)); param.setBeginDate(yesterdayMidnight.format(formatter)); param.setEndDate(today.format(formatter)); param.setPageSize(500); while (continueFlag){ param.setPageIndex(currentPage); continueFlag= batchSaveByPager(param); currentPage++; } } @Transactional @Override public boolean batchSaveByPager(ApsWorkOrderJobParam param) { String requestString = JSONObject.toJSONString(param); ApsWorkOrderJobLog jobLog = new ApsWorkOrderJobLog(); jobLog.setRequestData(requestString); jobLog.setPageNum(Long.valueOf(param.getPageIndex())); jobLog.setPageCount(Long.valueOf(param.getPageSize())); jobLog.setCreateTime(DateUtils.getNowDate()); jobLog.setBizType("work_order"); jobLogMapper.insertApsWorkOrderJobLog(jobLog); log.info("work_order_request:{}", JSONObject.toJSONString(jobLog)); return requestOnePage(jobLog); } /** * 请求一页数据进行保存 * */ @Transactional @Override public boolean requestOnePage(ApsWorkOrderJobLog jobLog) { // 定义常量,避免硬编码 final String STATUS_KEY = "status"; final String DATA_KEY = "data"; final String SUCCESS_STATUS = "200"; /*设置日志更新时间,Retry后与创建时间不同*/ jobLog.setUpdateTime(DateUtils.getNowDate()); try { // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity request = new HttpEntity<>(jobLog.getRequestData(), headers); // 发起HTTP请求 ResponseEntity response; try { response = restTemplate.postForEntity(getWorkOrderUrl, request, String.class); } catch (Exception e) { // 捕获网络异常或其他异常 String msg = String.format("Error occurred while making HTTP request: {}", e.getMessage()); log.error(msg); jobLog.setResponseData(msg); jobLog.setResult("fail:"+e.getMessage()); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } // 解析响应体 String responseBody = response.getBody(); // 检查响应状态码 if (!response.getStatusCode().is2xxSuccessful()) { String msg = String.format("Non-2xx response received: {}", response.getStatusCode()); log.warn(msg); jobLog.setResponseData(responseBody); jobLog.setResult("fail"); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } if (responseBody == null) { String responseBodyIsNull = "Response body is null"; log.warn(responseBodyIsNull); jobLog.setResponseData(responseBodyIsNull); jobLog.setResult("fail"); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } JSONObject responseBodyJson = JSONObject.parseObject(responseBody); String status = responseBodyJson.getString(STATUS_KEY); if (!SUCCESS_STATUS.equals(status)) { log.warn("Unexpected status in response: {}", status); jobLog.setResponseData(responseBody); jobLog.setResult("fail"); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } // 处理数据 JSONArray result = responseBodyJson.getJSONArray(DATA_KEY); if (result == null || result.isEmpty()) { jobLog.setResult("ok receive 0"); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } int ct = batchInsertApsWorkOrderJob(jobLog.getPageNum().intValue(), result); jobLog.setResult("ok save " + ct); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return true; } catch (Exception e) { // 捕获所有异常并记录日志 log.error("An unexpected error occurred: {}", e.getMessage(), e); jobLog.setResponseData(null); jobLog.setResult("fail"); jobLogMapper.updateApsWorkOrderJobLog(jobLog); return false; } } @Transactional(rollbackFor = Exception.class) public int batchInsertApsWorkOrderJob(Integer pageNum, JSONArray result) { // 边界条件检查 if (result == null || result.isEmpty()) { log.warn("Result is empty or null, no data to process."); return 0; } if (pageNum == null) { log.warn("PageNum is null, setting default value to 1."); pageNum = 1; } List jobs = new ArrayList<>(); List orderIds = new ArrayList<>(); for (int i = 0; i < result.size(); i++) { try { JSONObject jsonObject = result.getJSONObject(i); // 校验必要字段是否存在 if (!jsonObject.containsKey("ID")) { log.error("Missing 'ID' field in result at index: {}", i); continue; // 跳过无效数据 } ApsWorkOrderJob order = result.getObject(i, ApsWorkOrderJob.class); order.setId(IdUtil.getSnowflakeNextId()); order.setOrderId(jsonObject.getString("ID")); order.setCreateTime(DateUtils.getNowDate()); order.setPageIndex(i); order.setPageNum(pageNum); order.setDelFlag("0"); order.setProcessStatus("0"); order.setOpStatus(jsonObject.getString("OpStatus")); order.setNextOpName(jsonObject.getString("NextOpName")); order.setLowOrderCode(jsonObject.getString("LowLevelCode")); order.setOrderCreateTime(jsonObject.getDate("CreatedOn")); order.setApproveOn(jsonObject.getDate("ApproveOn")); order.setStartWorkDate(jsonObject.getDate("StartDatetime")); jobs.add(order); orderIds.add(order.getOrderId()); } catch (Exception e) { log.error("Error processing result at index {}: {}", i, e.getMessage(), e); // 继续处理其他数据 } } if (!orderIds.isEmpty()) { // 删除旧数据 apsWorkOrderJobMapper.deleteWorkOrderJobByOrderIds(orderIds); } // 批量插入新数据 int affectedRows = apsWorkOrderJobMapper.batchInsertApsWorkOrderJob(jobs); if (affectedRows != jobs.size()) { log.warn("Not all records were inserted successfully. Expected: {}, Actual: {}", jobs.size(), affectedRows); } return affectedRows; } /** * 同步零件工单信息 * */ @Transactional @Override public void syncPartOrderData() { apsWorkOrderJobMapper.deleteAllPartPlan(); apsWorkOrderJobMapper.batchInsertPartPlan(); } /** * 同步钣金工单信息 * */ @Transactional @Override public void syncPlateOrderData() { apsWorkOrderJobMapper.deleteAllPlatePlan(); apsWorkOrderJobMapper.batchInsertPlatePlan(); } /** * 同步钣金工单信息 * */ @Transactional @Override public void syncGasPipingData() { apsWorkOrderJobMapper.deleteAllGasPiping(); apsWorkOrderJobMapper.batchInsertGasPiping(); } @Override public void deleteAllWorkOrderJob(){ apsWorkOrderJobMapper.deleteAllWorkOrderJob(); } }