zss
12 小时以前 3b8f1579d4a4eced3e5547f619b892fa2b7fa96d
宜搭获取销售发货明细
已添加7个文件
已修改5个文件
437 ■■■■■ 文件已修改
doc/宁夏-中盛建材.sql 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/CodeGenerator.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/task/CustomerTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/config/AliDingConfig.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/controller/SalesDeliveryController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/mapper/SalesDeliveryMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/pojo/SalesDelivery.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/SalesDeliveryService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/service/impl/SalesDeliveryServiceImpl.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/productionPlan/task/SalesDeliveryTask.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/productionPlan/SalesDeliveryMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>