24282 %!s(int64=2) %!d(string=hai) anos
pai
achega
0940796785

+ 36 - 0
hx-common/src/main/java/com/fjhx/common/controller/documentary/DocumentaryRecordController.java

@@ -0,0 +1,36 @@
+package com.fjhx.common.controller.documentary;
+
+import com.fjhx.common.entity.documentary.dto.DocumentaryRecordSelectDto;
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordInfoVo;
+import com.fjhx.common.service.documentary.DocumentaryRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 跟单记录 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-04-20
+ */
+@RestController
+@RequestMapping("/documentaryRecord")
+public class DocumentaryRecordController {
+
+    @Autowired
+    private DocumentaryRecordService documentaryRecordService;
+
+    /**
+     * 跟单记录信息
+     */
+    @PostMapping("/info")
+    public DocumentaryRecordInfoVo page(@RequestBody DocumentaryRecordSelectDto dto) {
+        return documentaryRecordService.getInfo(dto);
+    }
+
+}

+ 20 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/bo/DocumentaryData.java

@@ -0,0 +1,20 @@
+package com.fjhx.common.entity.documentary.bo;
+
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordVo;
+
+import java.util.List;
+import java.util.Map;
+
+public interface DocumentaryData {
+
+    /**
+     * 获取业务id
+     */
+    Long getId();
+
+    /**
+     * 赋值跟单记录
+     */
+    void setDocumentaryRecord(Map<Long, List<DocumentaryRecordVo>> documentaryRecord);
+
+}

+ 29 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/dto/DocumentaryRecordSelectDto.java

@@ -0,0 +1,29 @@
+package com.fjhx.common.entity.documentary.dto;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 跟单记录列表查询入参实体
+ *
+ * @author
+ * @since 2023-04-20
+ */
+@Getter
+@Setter
+public class DocumentaryRecordSelectDto extends BaseSelectDto {
+
+    /**
+     * 跟单类型
+     * {@link com.fjhx.common.entity.documentary.eums.DocumentaryTypeEnum}
+     */
+    private Integer type;
+
+    /**
+     * 搜索条件
+     */
+    private JSONObject condition;
+
+}

+ 57 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/eums/DocumentaryTypeEnum.java

@@ -0,0 +1,57 @@
+package com.fjhx.common.entity.documentary.eums;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.fjhx.common.service.documentary.GetDocumentaryBusinessTemplate;
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum DocumentaryTypeEnum {
+
+
+    sales(1, "销售跟单", "serviceContractServiceImpl"),
+    purchase(2, "采购跟单", "purchaseDocumentaryImpl");
+
+    /**
+     * 跟单类型
+     */
+    private final Integer key;
+
+    /**
+     * 类型名称
+     */
+    private final String name;
+
+    /**
+     * 实现bean名称
+     */
+    private final String beanName;
+
+    private final static Map<Integer, DocumentaryTypeEnum> map = new HashMap<>();
+
+    static {
+        for (DocumentaryTypeEnum value : DocumentaryTypeEnum.values()) {
+            map.put(value.key, value);
+        }
+    }
+
+    public static DocumentaryTypeEnum getEnum(Integer key) {
+        return map.computeIfAbsent(key, item -> {
+            throw new ServiceException("未知跟单类型");
+        });
+    }
+
+    public GetDocumentaryBusinessTemplate getBusinessBean() {
+        GetDocumentaryBusinessTemplate bean = SpringUtil.getBean(beanName, GetDocumentaryBusinessTemplate.class);
+        if (bean == null) {
+            throw new ServiceException("未配置 " + name + " 跟单业务bean");
+        }
+        return bean;
+    }
+
+}

+ 43 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/po/DocumentaryRecord.java

@@ -0,0 +1,43 @@
+package com.fjhx.common.entity.documentary.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 跟单记录
+ * </p>
+ *
+ * @author
+ * @since 2023-04-20
+ */
+@Getter
+@Setter
+@TableName("documentary_record")
+public class DocumentaryRecord extends BasePo {
+
+    /**
+     * 跟单id
+     */
+    private Long documentaryId;
+
+    /**
+     * 业务id
+     */
+    private Long businessId;
+
+    /**
+     * 完成时间
+     */
+    private Date completionTime;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+}

+ 24 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/vo/DocumentaryRecordInfoVo.java

@@ -0,0 +1,24 @@
+package com.fjhx.common.entity.documentary.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.documentary.bo.DocumentaryData;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class DocumentaryRecordInfoVo {
+
+    /**
+     * 跟单配置
+     */
+    private List<DocumentaryVo> documentaryList;
+
+    /**
+     * 分页
+     */
+    private Page<? extends DocumentaryData> page;
+
+}

+ 22 - 0
hx-common/src/main/java/com/fjhx/common/entity/documentary/vo/DocumentaryRecordVo.java

@@ -0,0 +1,22 @@
+package com.fjhx.common.entity.documentary.vo;
+
+import com.fjhx.common.entity.documentary.po.DocumentaryRecord;
+import com.fjhx.file.entity.FileInfoVo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 跟单记录列表查询返回值实体
+ *
+ * @author
+ * @since 2023-04-20
+ */
+@Getter
+@Setter
+public class DocumentaryRecordVo extends DocumentaryRecord {
+
+    private List<FileInfoVo> fileList;
+
+}

+ 6 - 1
hx-common/src/main/java/com/fjhx/common/entity/documentary/vo/DocumentaryVo.java

@@ -7,11 +7,16 @@ import lombok.Setter;
 /**
  * 跟单配置列表查询返回值实体
  *
- * @author 
+ * @author
  * @since 2023-04-19
  */
 @Getter
 @Setter
 public class DocumentaryVo extends Documentary {
 
+    /**
+     * 数量
+     */
+    private Long count;
+
 }

+ 21 - 0
hx-common/src/main/java/com/fjhx/common/mapper/documentary/DocumentaryRecordMapper.java

@@ -0,0 +1,21 @@
+package com.fjhx.common.mapper.documentary;
+
+import com.fjhx.common.entity.documentary.po.DocumentaryRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 跟单记录 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-20
+ */
+public interface DocumentaryRecordMapper extends BaseMapper<DocumentaryRecord> {
+
+}

+ 24 - 0
hx-common/src/main/java/com/fjhx/common/service/documentary/DocumentaryRecordService.java

@@ -0,0 +1,24 @@
+package com.fjhx.common.service.documentary;
+
+import com.fjhx.common.entity.documentary.dto.DocumentaryRecordSelectDto;
+import com.fjhx.common.entity.documentary.po.DocumentaryRecord;
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordInfoVo;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 跟单记录 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-04-20
+ */
+public interface DocumentaryRecordService extends BaseService<DocumentaryRecord> {
+
+    /**
+     * 跟单记录信息
+     */
+    DocumentaryRecordInfoVo getInfo(DocumentaryRecordSelectDto dto);
+
+}

+ 19 - 0
hx-common/src/main/java/com/fjhx/common/service/documentary/GetDocumentaryBusinessTemplate.java

@@ -0,0 +1,19 @@
+package com.fjhx.common.service.documentary;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.documentary.bo.DocumentaryData;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+
+public interface GetDocumentaryBusinessTemplate {
+
+    /**
+     * 获取跟单分页数据
+     *
+     * @param selectData 筛选条件
+     * @param dto        分页参数
+     * @return 分页数据
+     */
+    Page<? extends DocumentaryData> getDocumentaryPage(JSONObject selectData, BaseSelectDto dto);
+
+}

+ 161 - 0
hx-common/src/main/java/com/fjhx/common/service/documentary/impl/DocumentaryRecordServiceImpl.java

@@ -0,0 +1,161 @@
+package com.fjhx.common.service.documentary.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.entity.documentary.bo.DocumentaryData;
+import com.fjhx.common.entity.documentary.dto.DocumentaryRecordSelectDto;
+import com.fjhx.common.entity.documentary.eums.DocumentaryTypeEnum;
+import com.fjhx.common.entity.documentary.po.Documentary;
+import com.fjhx.common.entity.documentary.po.DocumentaryRecord;
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordInfoVo;
+import com.fjhx.common.entity.documentary.vo.DocumentaryRecordVo;
+import com.fjhx.common.entity.documentary.vo.DocumentaryVo;
+import com.fjhx.common.mapper.documentary.DocumentaryRecordMapper;
+import com.fjhx.common.service.documentary.DocumentaryRecordService;
+import com.fjhx.common.service.documentary.DocumentaryService;
+import com.fjhx.common.service.documentary.GetDocumentaryBusinessTemplate;
+import com.fjhx.file.entity.FileInfoVo;
+import com.fjhx.file.utils.ObsFileUtil;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * 跟单记录 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-04-20
+ */
+@Service
+public class DocumentaryRecordServiceImpl extends ServiceImpl<DocumentaryRecordMapper, DocumentaryRecord> implements DocumentaryRecordService {
+
+    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
+            4,
+            20,
+            60,
+            TimeUnit.SECONDS,
+            new ArrayBlockingQueue<>(20),
+            new ThreadPoolExecutor.CallerRunsPolicy()
+    );
+
+    @Autowired
+    private DocumentaryService documentaryService;
+
+    @Override
+    public DocumentaryRecordInfoVo getInfo(DocumentaryRecordSelectDto dto) {
+
+        // 获取跟单类型
+        DocumentaryTypeEnum typeEnum = DocumentaryTypeEnum.getEnum(dto.getType());
+
+        CompletableFuture<? extends Page<? extends DocumentaryData>> pageCompletableFuture =
+                CompletableFuture.supplyAsync(() -> {
+                    GetDocumentaryBusinessTemplate bean = typeEnum.getBusinessBean();
+                    Page<? extends DocumentaryData> page = bean.getDocumentaryPage(dto.getCondition(), dto);
+                    setDocumentaryRecord(page);
+                    return page;
+                }, threadPoolExecutor);
+
+        CompletableFuture<List<DocumentaryVo>> getDocumentaryListFuture =
+                CompletableFuture.supplyAsync(() -> {
+                    List<DocumentaryVo> documentaryList = getDocumentaryList(typeEnum.getKey());
+                    setDocumentaryRecordCount(documentaryList);
+                    return documentaryList;
+                }, threadPoolExecutor);
+
+        List<DocumentaryVo> documentaryList = getDocumentaryListFuture.join();
+        Page<? extends DocumentaryData> documentaryDataPage = pageCompletableFuture.join();
+
+        DocumentaryRecordInfoVo vo = new DocumentaryRecordInfoVo();
+        vo.setDocumentaryList(documentaryList);
+        vo.setPage(documentaryDataPage);
+        return vo;
+    }
+
+    /**
+     * 获取跟单配置
+     *
+     * @param type 跟单类型
+     * @return 跟单列表
+     */
+    private List<DocumentaryVo> getDocumentaryList(Integer type) {
+        List<Documentary> list = documentaryService.list(q -> q
+                .eq(Documentary::getType, type)
+                .orderByAsc(Documentary::getSort)
+        );
+        return BeanUtil.copyToList(list, DocumentaryVo.class);
+    }
+
+    /**
+     * 设置跟单记录总条数
+     *
+     * @param documentaryList 跟单配置
+     */
+    private void setDocumentaryRecordCount(List<DocumentaryVo> documentaryList) {
+        List<Long> documentaryIdList = documentaryList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+
+        Map<Object, Long> countMap = listMaps(Wrappers.<DocumentaryRecord>query()
+                .select("documentary_id as documentaryId", "count(0) as count")
+                .lambda()
+                .eq(DocumentaryRecord::getDocumentaryId, documentaryIdList)
+                .groupBy(DocumentaryRecord::getDocumentaryId)
+        ).stream().collect(Collectors.toMap(
+                item -> item.get("documentaryId"),
+                item -> (Long) item.get("count")));
+
+        for (DocumentaryVo documentaryVo : documentaryList) {
+            documentaryVo.setCount(countMap.getOrDefault(documentaryVo.getId(), 0L));
+        }
+
+    }
+
+    /**
+     * 赋值跟单记录明细
+     */
+    private void setDocumentaryRecord(Page<? extends DocumentaryData> page) {
+        List<? extends DocumentaryData> records = page.getRecords();
+
+        if (records.size() == 0) {
+            return;
+        }
+
+        // 业务id
+        List<Long> businessId = records.stream().map(DocumentaryData::getId).collect(Collectors.toList());
+
+        // 根据业务id查询跟单记录
+        List<DocumentaryRecord> list = list(q -> q.eq(DocumentaryRecord::getBusinessId, businessId));
+
+        // 查询跟单记录文件
+        List<Long> documentaryRecordList = list.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+        Map<Long, List<FileInfoVo>> fileMap = ObsFileUtil.getFileMap(documentaryRecordList);
+
+        List<DocumentaryRecordVo> documentaryRecordVoList = BeanUtil.copyToList(list, DocumentaryRecordVo.class);
+
+        Map<Long, Map<Long, List<DocumentaryRecordVo>>> map = documentaryRecordVoList.stream()
+                .peek(item -> item.setFileList(fileMap.getOrDefault(item.getId(), new ArrayList<>())))
+                .collect(Collectors.groupingBy(DocumentaryRecord::getBusinessId,
+                        Collectors.groupingBy(DocumentaryRecord::getDocumentaryId)));
+
+        // 赋值
+        for (DocumentaryData record : records) {
+            record.setDocumentaryRecord(map.getOrDefault(record.getId(), new HashMap<>()));
+        }
+
+    }
+
+
+}

+ 5 - 0
hx-common/src/main/resources/mapper/documentary/DocumentaryRecordMapper.xml

@@ -0,0 +1,5 @@
+<?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.fjhx.common.mapper.documentary.DocumentaryRecordMapper">
+
+</mapper>

+ 7 - 9
hx-sale/src/main/java/com/fjhx/sale/service/serviceContract/impl/ServiceContractServiceImpl.java

@@ -1,27 +1,25 @@
 package com.fjhx.sale.service.serviceContract.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.fjhx.sale.entity.sale.vo.SaleQuotationVo;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.sale.entity.serviceContract.dto.ServiceContractDto;
+import com.fjhx.sale.entity.serviceContract.dto.ServiceContractSelectDto;
 import com.fjhx.sale.entity.serviceContract.po.ServiceContract;
 import com.fjhx.sale.entity.serviceContract.po.ServiceContractPay;
 import com.fjhx.sale.entity.serviceContract.po.ServiceContractProduct;
+import com.fjhx.sale.entity.serviceContract.vo.ServiceContractVo;
 import com.fjhx.sale.mapper.serviceContract.ServiceContractMapper;
 import com.fjhx.sale.service.serviceContract.ServiceContractPayService;
 import com.fjhx.sale.service.serviceContract.ServiceContractProductService;
 import com.fjhx.sale.service.serviceContract.ServiceContractService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.system.utils.UserUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fjhx.sale.entity.serviceContract.vo.ServiceContractVo;
-import com.fjhx.sale.entity.serviceContract.dto.ServiceContractSelectDto;
-import com.ruoyi.common.utils.wrapper.IWrapper;
-import com.fjhx.sale.entity.serviceContract.dto.ServiceContractDto;
-import cn.hutool.core.bean.BeanUtil;
 
 import java.util.List;
 
@@ -36,13 +34,13 @@ import java.util.List;
  */
 @Service
 public class ServiceContractServiceImpl extends ServiceImpl<ServiceContractMapper, ServiceContract> implements ServiceContractService {
+
     @Autowired
     private ServiceContractProductService serviceContractProductService;
 
     @Autowired
     private ServiceContractPayService serviceContractPayService;
 
-
     /**
      * 服务合同表分页
      */