doc/ÄþÏÄ-ÖÐÊ¢½¨²Ä.sql
@@ -375,3 +375,29 @@ ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; CREATE TABLE `product-inventory-management-zsjc`.`sales_delivery` ( `id` int NOT NULL AUTO_INCREMENT, `delivery_date` date NULL COMMENT 'ä¾è´§æ¥æ', `delivery_code` varchar(255) NULL COMMENT 'åè´§åç¼å·', `project_name` varchar(255) NULL COMMENT '项ç®åç§°', `delivery_place` varchar(255) NULL COMMENT 'éè´§å°ç¹', `link_man` varchar(255) NULL COMMENT 'è系人', `link_phone` varchar(255) NULL COMMENT 'èç³»çµè¯', `delivery_remark` varchar(255) NULL COMMENT 'åè´§å¤æ³¨', `material_code` varchar(255) NULL COMMENT 'ç©æä»£ç ', `product_name` varchar(255) NULL COMMENT '产ååç§°', `model` varchar(255) NULL COMMENT '产åè§æ ¼', `volume` decimal(10, 4) NULL COMMENT 'æ¹é', `unit_price` decimal(10, 2) NULL COMMENT 'åä»·', `price` decimal(10, 2) NULL COMMENT 'ä»·æ ¼', `product_remark` varchar(255) NULL COMMENT '产å夿³¨', `customer` varchar(255) NULL COMMENT '客æ·åç§°', `salesman` varchar(255) NULL COMMENT 'ä¸å¡å', `delivery_method` varchar(255) NULL COMMENT 'åè´§æ¹å¼', `form_instance_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'å®æè¡¨åå®ä¾ID', `form_modified_time` datetime(0) NULL DEFAULT NULL COMMENT 'å®æä¿®æ¹æ¶é´', `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0), `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`id`) ) COMMENT = 'éå®åè´§æç»(宿)'; src/main/java/com/ruoyi/CodeGenerator.java
@@ -23,7 +23,7 @@ public static String database_username = "root"; public static String database_password= "xd@123456.."; public static String author = "è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸"; public static String model = "energy"; // 模å public static String model = "productionPlan"; // 模å public static String setParent = "com.ruoyi."+ model; // å è·¯å¾ public static String tablePrefix = ""; // è®¾ç½®è¿æ»¤è¡¨åç¼ public static void main(String[] args) { src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -276,7 +276,7 @@ @Override public void syncCustomerJob() { syncCustomerData(2); syncCustomerData(); } @Override @@ -322,11 +322,7 @@ * åæ¥æ°æ® */ @Transactional(rollbackFor = Exception.class) public void syncCustomerData(Integer dataSyncType) { if (!syncLock.tryLock()) { log.warn("忥æ£å¨è¿è¡ä¸ï¼æ¬æ¬¡ {} åæ¥è¯·æ±è¢«è·³è¿", dataSyncType == 1 ? "æå¨" : "宿¶ä»»å¡"); return; } public void syncCustomerData() { try { JSONArray searchConditions = new JSONArray(); JSONObject statusCondition = new JSONObject(); @@ -368,9 +364,6 @@ } catch (Exception e) { log.error("忥客æ·ä¿¡æ¯å¼å¸¸", e); } finally { // éæ¾é syncLock.unlock(); } } src/main/java/com/ruoyi/basic/task/CustomerTask.java
@@ -11,7 +11,7 @@ @Autowired private ICustomerService customerService; @Scheduled(cron = "0 0 * * * ?") @Scheduled(cron = "0 0 0 * * ?") public void syncCustomerDataJob() { customerService.syncCustomerJob(); } src/main/java/com/ruoyi/framework/config/AliDingConfig.java
@@ -58,6 +58,11 @@ private String customerCodeFormUuid; /** * éå®åè´§æç»-å®æè¡¨åID */ private String salesDeliveryFormUuid; /** * 宿åºç¨å¯é¥ * ç¨äºè®¿é®å®æè¡¨å API */ src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package com.ruoyi.productionPlan.controller; import io.swagger.annotations.Api; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * éå®åè´§æç»(宿) å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-19 11:49:57 */ @RestController @RequestMapping("/salesDelivery") @Api(tags = "éå®åè´§æç»") public class SalesDeliveryController { } src/main/java/com/ruoyi/productionPlan/mapper/SalesDeliveryMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package com.ruoyi.productionPlan.mapper; import com.ruoyi.productionPlan.pojo.SalesDelivery; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; /** * <p> * éå®åè´§æç»(宿) Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-19 11:49:57 */ @Mapper public interface SalesDeliveryMapper extends BaseMapper<SalesDelivery> { } src/main/java/com/ruoyi/productionPlan/pojo/SalesDelivery.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,105 @@ package com.ruoyi.productionPlan.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; /** * <p> * éå®åè´§æç»(宿) * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-19 11:49:57 */ @Getter @Setter @TableName("sales_delivery") @ApiModel(value = "SalesDelivery对象", description = "éå®åè´§æç»(宿)") public class SalesDelivery implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty("ä¾è´§æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate deliveryDate; @ApiModelProperty("åè´§åç¼å·") private String deliveryCode; @ApiModelProperty("项ç®åç§°") private String projectName; @ApiModelProperty("éè´§å°ç¹") private String deliveryPlace; @ApiModelProperty("è系人") private String linkMan; @ApiModelProperty("èç³»çµè¯") private String linkPhone; @ApiModelProperty("åè´§å¤æ³¨") private String deliveryRemark; @ApiModelProperty("ç©æä»£ç ") private String materialCode; @ApiModelProperty("产ååç§°") private String productName; @ApiModelProperty("产åè§æ ¼") private String model; @ApiModelProperty("æ¹é") private BigDecimal volume; @ApiModelProperty("åä»·") private BigDecimal unitPrice; @ApiModelProperty("ä»·æ ¼") private BigDecimal price; @ApiModelProperty("产å夿³¨") private String productRemark; @ApiModelProperty("客æ·åç§°") private String customer; @ApiModelProperty("ä¸å¡å") private String salesman; @ApiModelProperty("åè´§æ¹å¼") private String deliveryMethod; @ApiModelProperty("å®æè¡¨åå®ä¾ID") private String formInstanceId; @ApiModelProperty("å®æä¿®æ¹æ¶é´") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime formModifiedTime; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; } src/main/java/com/ruoyi/productionPlan/service/SalesDeliveryService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package com.ruoyi.productionPlan.service; import com.ruoyi.productionPlan.pojo.SalesDelivery; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * éå®åè´§æç»(宿) æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-19 11:49:57 */ public interface SalesDeliveryService extends IService<SalesDelivery> { void syncSalesDeliveryJob(); } src/main/java/com/ruoyi/productionPlan/service/impl/SalesDeliveryServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,176 @@ package com.ruoyi.productionPlan.service.impl; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.AliDingConfig; import com.ruoyi.framework.util.AliDingUtils; import com.ruoyi.production.pojo.ProductMaterialSku; import com.ruoyi.productionPlan.enums.DataSourceTypeEnum; import com.ruoyi.productionPlan.pojo.ProductionPlan; import com.ruoyi.productionPlan.pojo.SalesDelivery; import com.ruoyi.productionPlan.mapper.SalesDeliveryMapper; import com.ruoyi.productionPlan.service.SalesDeliveryService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * <p> * éå®åè´§æç»(宿) æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-19 11:49:57 */ @Service @Slf4j public class SalesDeliveryServiceImpl extends ServiceImpl<SalesDeliveryMapper, SalesDelivery> implements SalesDeliveryService { @Autowired private SalesDeliveryMapper salesDeliveryMapper; @Autowired private AliDingConfig aliDingConfig; @Override public void syncSalesDeliveryJob() { syncSalesDelivery(); } /** * åæ¥æ°æ® */ @Transactional(rollbackFor = Exception.class) public void syncSalesDelivery() { try { JSONArray searchConditions = new JSONArray(); JSONObject condition = new JSONObject(); condition.put("key", "processApprovedResult"); JSONArray valueArray = new JSONArray(); valueArray.add("agree"); condition.put("value", valueArray); condition.put("type", "ARRAY"); condition.put("operator", "in"); condition.put("componentName", "SelectField"); searchConditions.add(condition); JSONObject statusCondition = new JSONObject(); statusCondition.put("key", "processInstanceStatus"); JSONArray statusValueArray = new JSONArray(); statusValueArray.add("COMPLETED"); statusCondition.put("value", statusValueArray); statusCondition.put("type", "ARRAY"); statusCondition.put("operator", "in"); statusCondition.put("componentName", "SelectField"); searchConditions.add(statusCondition); String searchFieldJson = searchConditions.toJSONString(); JSONArray dataArr = AliDingUtils.getFormDataList(aliDingConfig, aliDingConfig.getSalesDeliveryFormUuid(), searchFieldJson, this, SalesDelivery::getFormModifiedTime); if (dataArr.isEmpty()) { return; } // è§£æå¹¶ä¿åæ°æ® List<SalesDelivery> list = parseSalesDeliverys(dataArr); if (!list.isEmpty()) { // å¤çæ´æ°ææ°å¢ int affected = processSaveOrUpdate(list); log.info("æ°æ®åæ¥å®æï¼å ±åæ¥ {} æ¡æ°æ®", affected); } } catch (Exception e) { log.error("忥ç产计åå¼å¸¸", e); } } private List<SalesDelivery> parseSalesDeliverys(JSONArray dataArr) { List<SalesDelivery> list = new ArrayList<>(); for (int i = 0; i < dataArr.size(); i++) { JSONObject item = dataArr.getJSONObject(i); String formInstanceId = item.getString("formInstanceId"); JSONObject formData = item.getJSONObject("formData"); JSONArray tableArr = formData.getJSONArray("tableField_kt8b0qse"); if (tableArr == null || tableArr.isEmpty()) { continue; } for (int j = 0; j < tableArr.size(); j++) { JSONObject row = tableArr.getJSONObject(j); SalesDelivery salesDelivery = new SalesDelivery(); salesDelivery.setFormInstanceId(formInstanceId); Long time = formData.getLong("dateField_kt8b0qsm"); LocalDate date = Instant.ofEpochMilli(time).atZone(ZoneId.of("Asia/Shanghai")).toLocalDate(); salesDelivery.setDeliveryDate(date);//ä¾è´§æ¥æ salesDelivery.setDeliveryCode(formData.getString("textField_kt8b0qrp"));//åè´§åç¼å· salesDelivery.setProjectName(formData.getString("textField_l92dg1tg"));//项ç®åç§° salesDelivery.setDeliveryPlace(formData.getString("textField_kt8b0qsd"));//éè´§å°ç¹ salesDelivery.setLinkMan(formData.getString("textField_kt8b0qsb"));//è系人 salesDelivery.setLinkPhone(formData.getString("textField_kt8b0qsc"));//èç³»çµè¯ salesDelivery.setDeliveryRemark(formData.getString("textareaField_kt8b0qsl"));//åè´§å¤æ³¨ salesDelivery.setCustomer(formData.getString("textField_la98q3sg"));//客æ·åç§° salesDelivery.setSalesman(formData.getString("textField_ladnkyu1"));//ä¸å¡å salesDelivery.setDeliveryMethod(formData.getString("radioField_ldoc0027"));//åè´§æ¹å¼ String materialCode = row.getString("textField_l92dg1tc"); // æ ¹æ®ç©æç¼ç æ¥è¯¢ç©æä¿¡æ¯è¡¨ï¼å ³èç©æID // if (StringUtils.isNotEmpty(materialCode)) { // LambdaQueryWrapper<ProductMaterialSku> skuQueryWrapper = new LambdaQueryWrapper<>(); // skuQueryWrapper.eq(ProductMaterialSku::getMaterialCode, materialCode); // ProductMaterialSku sku = productMaterialSkuService.getOne(skuQueryWrapper); // if (sku != null) { // salesDelivery.setProductMaterialSkuId(sku.getId()); // } // } salesDelivery.setMaterialCode(materialCode);//ç©æç¼ç salesDelivery.setProductName(row.getString("textField_l96srw8x"));//产ååç§° salesDelivery.setModel(row.getString("textField_l9tljfl8"));//产åè§æ ¼ salesDelivery.setVolume(row.getBigDecimal("numberField_kt8b0qsg_value"));//æ¹é salesDelivery.setUnitPrice(row.getBigDecimal("numberField_la0tb2x9_value"));//åä»· salesDelivery.setPrice(row.getBigDecimal("numberField_l9w2piwf"));//ä»·æ ¼ salesDelivery.setProductRemark(row.getString("textField_kt8b0qsi"));//产å夿³¨ salesDelivery.setFormModifiedTime(AliDingUtils.parseUtcTime(item.getString("modifiedTimeGMT"))); list.add(salesDelivery); } } return list; } private int processSaveOrUpdate(List<SalesDelivery> list) { if (list == null || list.isEmpty()) { return 0; } int affected = 0; for (SalesDelivery salesDelivery : list) { LambdaQueryWrapper<SalesDelivery> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SalesDelivery::getFormInstanceId, salesDelivery.getFormInstanceId()); SalesDelivery exist = this.getOne(wrapper); if (exist == null) { this.save(salesDelivery); affected++; } else { if (exist.getFormModifiedTime() == null || !exist.getFormModifiedTime().equals(salesDelivery.getFormModifiedTime())) { salesDelivery.setId(exist.getId()); this.updateById(salesDelivery); affected++; } } } return affected; } } src/main/java/com/ruoyi/productionPlan/task/SalesDeliveryTask.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,23 @@ package com.ruoyi.productionPlan.task; import com.ruoyi.productionPlan.service.ProductionPlanService; import com.ruoyi.productionPlan.service.SalesDeliveryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; //éå®åè´§æç»å¯¹æ¥å®æå®æ¶ä»»å¡ @Component public class SalesDeliveryTask { @Autowired private SalesDeliveryService salesDeliveryService; @Scheduled(cron = "0 04 15 * * ?") public void syncSalesDeliveryJob() { salesDeliveryService.syncSalesDeliveryJob(); } } src/main/resources/mapper/productionPlan/SalesDeliveryMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,31 @@ <?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.ruoyi.productionPlan.mapper.SalesDeliveryMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.productionPlan.pojo.SalesDelivery"> <id column="id" property="id" /> <result column="delivery_date" property="deliveryDate" /> <result column="delivery_code" property="deliveryCode" /> <result column="project_name" property="projectName" /> <result column="delivery_place" property="deliveryPlace" /> <result column="link_man" property="linkMan" /> <result column="link_phone" property="linkPhone" /> <result column="delivery_remark" property="deliveryRemark" /> <result column="material_code" property="materialCode" /> <result column="product_name" property="productName" /> <result column="model" property="model" /> <result column="volume" property="volume" /> <result column="unit_price" property="unitPrice" /> <result column="price" property="price" /> <result column="product_remark" property="productRemark" /> <result column="customer" property="customer" /> <result column="salesman" property="salesman" /> <result column="delivery_method" property="deliveryMethod" /> <result column="form_instance_id" property="formInstanceId" /> <result column="form_modified_time" property="formModifiedTime" /> <result column="create_time" property="createTime" /> <result column="update_time" property="updateTime" /> </resultMap> </mapper>