Parcourir la source

Merge remote-tracking branch 'origin/master'

徐滕 il y a 1 jour
Parent
commit
12191afb48
14 fichiers modifiés avec 417 ajouts et 138 suppressions
  1. 21 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/PsiManagementApiFallbackFactory.java
  2. 15 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IPsiManagementApi.java
  3. 4 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/AppNameConstants.java
  4. 2 5
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/collect/mapper/xml/PsiCollectDetailedMapper.xml
  5. 2 2
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/collect/service/PsiCollectService.java
  6. 24 0
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/feign/PsiManagementApiImpl.java
  7. 0 3
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/materialType/service/PsiMaterialTypeForTreeDataService.java
  8. 16 3
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/controller/PsiWareHouseController.java
  9. 6 0
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/mapper/PsiWareHouseBasicMapper.java
  10. 53 107
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/mapper/xml/PsiWareHouseBasicMapper.xml
  11. 248 12
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/service/PsiWareHouseBasicService.java
  12. 3 2
      jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/service/dto/PsiWareSummaryExportDto.java
  13. 9 0
      jeeplus-modules/jeeplus-xxl-job-executor-sample/src/main/java/com/xxl/job/executor/feign/PsiManagementFeignApi.java
  14. 14 4
      jeeplus-modules/jeeplus-xxl-job-executor-sample/src/main/java/com/xxl/job/executor/service/jobhandler/SampleXxlJob.java

+ 21 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/PsiManagementApiFallbackFactory.java

@@ -0,0 +1,21 @@
+package com.jeeplus.flowable.factory;
+
+import com.jeeplus.flowable.feign.IPsiManagementApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class PsiManagementApiFallbackFactory implements FallbackFactory<IPsiManagementApi> {
+
+    @Override
+    public IPsiManagementApi create(Throwable cause) {
+        log.error("psi-management service call failed:{}", cause.getMessage());
+        return new IPsiManagementApi() {
+            @Override
+            public void nearExpiryList() {
+            }
+        };
+    }
+}

+ 15 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IPsiManagementApi.java

@@ -0,0 +1,15 @@
+package com.jeeplus.flowable.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.factory.PsiManagementApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@FeignClient(contextId = "psiManagementApi", name = AppNameConstants.APP_PSI_MANAGEMENT_MODULES, fallbackFactory = PsiManagementApiFallbackFactory.class)
+public interface IPsiManagementApi {
+
+    String BASE_URL = "/feign/psi/management/wareHouse";
+
+    @GetMapping(value = BASE_URL + "/nearExpiryList")
+    void nearExpiryList();
+}

+ 4 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/AppNameConstants.java

@@ -45,4 +45,8 @@ public interface AppNameConstants {
      * 培训模块
      */
     String APP_CONSULT_MODULES = "jeeplus-consultancy";
+    /**
+     * psi管理模块
+     */
+    String APP_PSI_MANAGEMENT_MODULES = "jeeplus-psi-management";
 }

+ 2 - 5
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/collect/mapper/xml/PsiCollectDetailedMapper.xml

@@ -19,11 +19,8 @@
                c.spec,
         su.name AS recipientAgent, su.id AS recipientAgentId, so.name AS recipientOffice,
         d.id AS collectTypeId, d.name AS collectType,
-               IFNULL(
-                       SUM(trade_number) - (b.collect_number / c.spec),
-                       SUM(trade_number)
-               ) AS surplusNumber,
-                a.is_return
+        a.current_inventory AS surplusNumber,
+        a.is_return
              FROM psi_management_collect_detailed a
              LEFT JOIN sys_user su
              ON a.recipient_agent = su.id

+ 2 - 2
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/collect/service/PsiCollectService.java

@@ -451,7 +451,7 @@ public class PsiCollectService {
                     String warnInfo = String.join("、", warnInfoList);
                     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                     String day = format.format(new Date());
-                    String title = "管理员发起了 ["+ warnInfo +"] [库存提醒]";
+                    String title = "管理员发起了 ["+ warnInfo +"] [物资库存提醒]";
                     //向多个用户发起通知
                     List<UserDTO> usersInfo = psiWareHouseDetailedMapper.getUsersInfo();
                     //获取目前领用流程的taskid,根据procInsId去查taskId
@@ -465,7 +465,7 @@ public class PsiCollectService {
                             map.put("taskId",uuid);
                             map.put("title",title);
                             map.put("defId",dto.getId());
-                            map.put("taskName","进销存库存提醒");
+                            map.put("taskName","物资库存提醒");
                             map.put("createUser","管理员");
                             map.put("createTime",day);
                             map.put("noticeName",userDTO1.getLoginName());

+ 24 - 0
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/feign/PsiManagementApiImpl.java

@@ -0,0 +1,24 @@
+package com.jeeplus.psimanage.feign;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.flowable.feign.IPsiManagementApi;
+import com.jeeplus.psimanage.psiWareHouse.service.PsiWareHouseBasicService;
+import com.jeeplus.psimanage.psiWareHouse.service.dto.PsiWareHouseDto;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController
+public class PsiManagementApiImpl implements IPsiManagementApi {
+
+    @Resource
+    private PsiWareHouseBasicService psiWareHouseBasicService;
+
+    @Override
+    public void nearExpiryList() {
+        Page<PsiWareHouseDto> page = new Page<>();
+        page.setCurrent(1);
+        page.setSize(-1);
+        psiWareHouseBasicService.nearExpiryList(page, new PsiWareHouseDto());
+    }
+}

+ 0 - 3
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/materialType/service/PsiMaterialTypeForTreeDataService.java

@@ -98,9 +98,6 @@ public class PsiMaterialTypeForTreeDataService extends TreeService<PsiMaterialTy
      * @param root    根节点, 为空抛出空指针异常
      * @param allList 所有需要参与构造为树的列表
      * @param extId   需要排除在树之外的节点(子节点一并被排除)
-     * @return java.util.List<T>
-     * @Author 滕鑫源
-     * @Date 2020/10/23 17:04
      **/
     public List <PsiMaterialTypeInfo> formatListToTreeForType (PsiMaterialTypeInfo root, List <PsiMaterialTypeInfo> allList, String extId, String type) {
         String rootId = root.getId ( );

+ 16 - 3
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/controller/PsiWareHouseController.java

@@ -198,11 +198,24 @@ public class PsiWareHouseController {
         return ResponseEntity.ok(iPage);
     }
 
+    /**
+     * 查询所有库存数据,无限制
+     * @param dto
+     * @return
+     */
+    @ApiOperation(value = "查询所有库存数据,无限制")
+    @GetMapping("/getAllData")
+    public ResponseEntity<IPage<PsiWareHouseDto>> getAllData(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) throws Exception{
+        IPage<PsiWareHouseDto> iPage = basicService.getAllData(page, dto);
+        return ResponseEntity.ok(iPage);
+    }
+
+
+
     @ApiOperation(value = "即将过期物资查询")
     @GetMapping("/nearExpiryList")
-    public ResponseEntity<IPage<PsiWareHouseDto>> nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
-        IPage<PsiWareHouseDto> iPage = basicService.nearExpiryList(page, dto);
-        return ResponseEntity.ok(iPage);
+    public void nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
+       basicService.nearExpiryList(page, dto);
     }
 
 

+ 6 - 0
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/mapper/PsiWareHouseBasicMapper.java

@@ -1,5 +1,6 @@
 package com.jeeplus.psimanage.psiWareHouse.mapper;
 
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
@@ -57,11 +58,16 @@ public interface PsiWareHouseBasicMapper extends BaseMapper<PsiWareHouseBasic> {
 
     IPage<PsiWareHouseDto> summaryList2(Page<PsiWareHouseDto> page,@Param(Constants.WRAPPER) QueryWrapper<PsiWareHouseDto> queryWrapper);
 
+    @InterceptorIgnore(tenantLine = "true")
     IPage<PsiWareHouseDto> getByProduceDateAndName(Page<PsiWareHouseDto> page,@Param(Constants.WRAPPER) QueryWrapper<PsiWareHouseDto> queryWrapper);
 
 
     IPage<PsiWareHouseDto> getByProduceDateNotMerge(Page<PsiWareHouseDto> page,@Param(Constants.WRAPPER) QueryWrapper<PsiWareHouseDto> queryWrapper);
 
+    @InterceptorIgnore(tenantLine = "true")
+    IPage<PsiWareHouseDto> getAllData(Page<PsiWareHouseDto> page,@Param(Constants.WRAPPER) QueryWrapper<PsiWareHouseDto> queryWrapper);
+
+    @InterceptorIgnore(tenantLine = "true")
     IPage<PsiWareHouseDto> nearExpiryList(Page<PsiWareHouseDto> page, @Param("dto") PsiWareHouseDto dto);
 
     IPage<PsiWareHouseDto> wareHouseHistoryList(Page<PsiWareHouseDto> page,@Param(Constants.WRAPPER) QueryWrapper<PsiWareHouseDto> queryWrapper);

+ 53 - 107
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/mapper/xml/PsiWareHouseBasicMapper.xml

@@ -152,12 +152,15 @@
 			sum( trade_number ) AS allNumber,
 			b.collect_number AS borrowNumber,
 			loss.loss_number AS lossNumber,
-			a.current_inventory AS tradeNumber,
+			sum(a.current_inventory) AS tradeNumber,
 			a.warn_num,
 			a.warn_flag,
 			a.produce_date,
 			a.shelf_life,
-			a.shelf_life_unit
+			a.shelf_life_unit,
+			a.spec,
+			pmcdra.returned_num as returnedNum,
+			pmcdra.not_surplus_stock as notSurplusStock
 		FROM
 			psi_management_warehouse_detailed a
 				left join
@@ -168,7 +171,7 @@
 					status
 				from psi_management_collect_detailed e
 						 left join psi_management_collect_basics f on e.basic_id = f.id and f.del_flag = 0
-				WHERE f.`status` = 5 and e.del_flag = 0
+				WHERE f.`status` = 5 and e.del_flag = 0 and e.is_return = '0'
 				GROUP BY e.goods_name
 			) b
 			on a.trade_name = b.goods_name
@@ -184,6 +187,20 @@
 				GROUP BY e.goods_name
 			) loss
 			on a.trade_name = loss.goods_name
+				left join
+			(
+				select
+					sum(returned_num) AS returned_num,
+					sum(not_surplus_stock) AS not_surplus_stock,
+					inventory_id,
+					goods_name,
+					status
+				from psi_management_collect_detailed_record e
+						 left join psi_management_collect_basics pmcba on e.basic_id = pmcba.id and pmcba.del_flag = 0
+				WHERE pmcba.`status` = 5 and e.del_flag = 0
+				group BY e.goods_name
+			) pmcdra
+			on a.trade_name = pmcdra.goods_name
 				LEFT JOIN psi_management_warehouse_basics bas on a.basic_id = bas.id
 				left join psi_management_type c on a.ware_house_type = c.id
 			${ew.customSqlSegment}
@@ -253,113 +270,42 @@
 		GROUP BY a.trade_name,a.ware_house_type,a.produce_date
 		ORDER BY a.produce_date asc
 	</select>
-
-	<select id="nearExpiryList"
+	<select id="getAllData"
 			resultType="com.jeeplus.psimanage.psiWareHouse.service.dto.PsiWareHouseDto">
 		SELECT
-			t.id,
-			t.basic_id AS basicId,
-			t.ware_house_type,
-			t.trade_name,
-			t.spec,
-			t.company,
-			t.current_inventory AS currentInventory,
-			t.current_inventory AS tradeNumber,
-			t.produce_date,
-			t.shelf_life,
-			t.shelf_life_unit,
-			t.expiryDate AS expiryDate,
-			CAST(t.remainingDays AS SIGNED) AS remainingDays,
-			CAST(t.warnDays AS SIGNED) AS warnDays,
-			t.ware_house_number,
-			t.ware_house_name,
-			t.ware_house_date,
-			tp.name AS wareHouseTypeName
+			a.id,
+			a.produce_date as produce_date,
+			a.trade_name,
+			a.spec,
+			a.company,
+			a.current_inventory,
+			a.shelf_life,
+			a.shelf_life_unit,
+			pmwd.warn_num,
+			pmwd.warn_flag
 		FROM
-		(
-			SELECT
-				src.*,
-				DATEDIFF(src.expiryDate, CURDATE()) AS remainingDays,
-				CASE
-					WHEN src.totalShelfDays &lt;= 30 THEN CAST(GREATEST(1, CEILING(src.totalShelfDays / 3)) AS SIGNED)
-					ELSE CAST(GREATEST(1, CEILING(src.totalShelfDays / 4)) AS SIGNED)
-				END AS warnDays
-			FROM
-			(
-				SELECT
-					a.id,
-					a.basic_id,
-					a.ware_house_type,
-					a.trade_name,
-					a.spec,
-					a.company,
-					a.current_inventory,
-					a.produce_date,
-					a.shelf_life,
-					a.shelf_life_unit,
-					a.supplier_id,
-					bas.ware_house_number,
-					bas.ware_house_name,
-					bas.ware_house_date,
-					CASE
-						WHEN TRIM(a.shelf_life_unit) = '年' THEN DATE_ADD(a.produce_date, INTERVAL CAST(a.shelf_life AS UNSIGNED) YEAR)
-						WHEN TRIM(a.shelf_life_unit) = '月' THEN DATE_ADD(a.produce_date, INTERVAL CAST(a.shelf_life AS UNSIGNED) MONTH)
-						WHEN TRIM(a.shelf_life_unit) = '天' OR TRIM(a.shelf_life_unit) = '日' THEN DATE_ADD(a.produce_date, INTERVAL CAST(a.shelf_life AS UNSIGNED) DAY)
-						ELSE NULL
-					END AS expiryDate,
-					CASE
-						WHEN TRIM(a.shelf_life_unit) = '年' THEN CAST(a.shelf_life AS DECIMAL(10, 2)) * 365
-						WHEN TRIM(a.shelf_life_unit) = '月' THEN CAST(a.shelf_life AS DECIMAL(10, 2)) * 30
-						WHEN TRIM(a.shelf_life_unit) = '天' OR TRIM(a.shelf_life_unit) = '日' THEN CAST(a.shelf_life AS DECIMAL(10, 2))
-						ELSE NULL
-					END AS totalShelfDays
-				FROM
-					psi_management_warehouse_detailed a
-					LEFT JOIN psi_management_warehouse_basics bas ON a.basic_id = bas.id
-				WHERE
-					a.del_flag = '0'
-					AND bas.del_flag = '0'
-					AND (bas.`status` = '0' OR bas.`status` = '5')
-					AND a.produce_date IS NOT NULL
-					AND a.shelf_life IS NOT NULL
-					AND a.shelf_life &lt;&gt; ''
-					AND a.shelf_life REGEXP '^[0-9]+([.][0-9]+)?$'
-					AND a.shelf_life_unit IS NOT NULL
-					AND a.shelf_life_unit &lt;&gt; ''
-					AND CAST(IFNULL(NULLIF(a.current_inventory, ''), '0') AS DECIMAL(18, 6)) &gt; 0
-					<if test="dto.tradeName != null and dto.tradeName != ''">
-						AND a.trade_name LIKE concat('%', #{dto.tradeName}, '%')
-					</if>
-					<if test="dto.wareHouseType != null and dto.wareHouseType != ''">
-						AND a.ware_house_type = #{dto.wareHouseType}
-					</if>
-					<if test="dto.produceDate != null">
-						AND a.produce_date = #{dto.produceDate}
-					</if>
-					<if test="dto.supplierId != null and dto.supplierId != ''">
-						AND a.supplier_id = #{dto.supplierId}
-					</if>
-					<if test="dto.spec != null and dto.spec != ''">
-						AND a.spec LIKE concat('%', #{dto.spec}, '%')
-					</if>
-					<if test="dto.wareHouseNumber != null and dto.wareHouseNumber != ''">
-						AND bas.ware_house_number LIKE concat('%', #{dto.wareHouseNumber}, '%')
-					</if>
-					<if test="dto.wareHouseName != null and dto.wareHouseName != ''">
-						AND bas.ware_house_name LIKE concat('%', #{dto.wareHouseName}, '%')
-					</if>
-			) src
-			WHERE
-				src.expiryDate IS NOT NULL
-		) t
-		LEFT JOIN psi_management_type tp ON t.ware_house_type = tp.id
-		WHERE
-			t.remainingDays &gt;= 0
-			AND (
-				t.remainingDays &lt;= t.warnDays
-				OR t.remainingDays IN (30, 60, 90)
-			)
-		ORDER BY t.remainingDays ASC, t.expiryDate ASC, t.trade_name ASC
+			psi_management_warehouse_detailed a
+				LEFT JOIN psi_management_warehouse_basics bas on a.basic_id = bas.id
+				LEFT JOIN psi_management_warehouse_detailed pmwd on bas.id = pmwd.basic_id
+				left join psi_management_type c on a.ware_house_type = c.id
+			${ew.customSqlSegment}
+
+		GROUP BY a.trade_name,a.ware_house_type,a.produce_date
+		ORDER BY a.produce_date asc
+	</select>
+
+	<select id="nearExpiryList"
+			resultType="com.jeeplus.psimanage.psiWareHouse.service.dto.PsiWareHouseDto">
+		select
+		    a.trade_name,
+		    a.produce_date,
+		    a.shelf_life,
+		    a.spec,
+		    a.shelf_life_unit,
+		    a.current_inventory
+		from psi_management_warehouse_detailed a
+		left join psi_management_warehouse_basics pmwb on pmwb.id = a.basic_id and pmwb.del_flag= '0'
+		where a.del_flag = '0'
 	</select>
 
     <select id="findRequestId" resultType="java.lang.String">

+ 248 - 12
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/service/PsiWareHouseBasicService.java

@@ -43,6 +43,9 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -972,11 +975,6 @@ public class PsiWareHouseBasicService {
                 String s = convertByBigDecimal(item.getAllNumber());
                 item.setAllNumber(s);
             }
-            //领用量  格式化
-            if (StringUtils.isNotBlank(item.getBorrowNumber())) {
-                String s = convertByBigDecimal(item.getBorrowNumber());
-                item.setBorrowNumber(s);
-            }
             //剩余量  格式化
             if (StringUtils.isNotBlank(item.getTradeNumber())) {
                 String s = convertByBigDecimal(item.getTradeNumber());
@@ -997,6 +995,47 @@ public class PsiWareHouseBasicService {
             if(StringUtils.isBlank(item.getLossNumber())){
                 item.setLossNumber("0");
             }
+
+            if (StringUtils.isNotBlank(item.getNotSurplusStock())) {
+                String notSurplusStockStr = item.getNotSurplusStock();
+                String specStr = item.getSpec();
+
+                if (StringUtils.isBlank(notSurplusStockStr) || StringUtils.isBlank(specStr)) {
+                    item.setNotSurplusStock(item.getNotSurplusStock());
+                }else{
+                    double notSurplusStock = Double.parseDouble(notSurplusStockStr);
+                    double spec = Double.parseDouble(specStr);
+
+                    if (spec == 0) {
+                        item.setNotSurplusStock(item.getNotSurplusStock());
+                    }else{
+                        double total = notSurplusStock / spec;
+                        String totalStr = String.valueOf( total);
+                        item.setNotSurplusStock(totalStr);
+                    }
+                }
+            }
+
+            if (StringUtils.isNotBlank(item.getLossNumber())) {
+                String specStr = item.getSpec();
+                String lossNumberStr = item.getLossNumber();
+
+                if (StringUtils.isBlank(specStr)) {
+                    item.setLossNumber(item.getLossNumber());
+                }else{
+                    double spec = Double.parseDouble(specStr);
+                    double lossNumber = Double.parseDouble(lossNumberStr);
+                    if (spec == 0) {
+                        item.setLossNumber(item.getLossNumber());
+                    }else{
+                        double total = lossNumber / spec;
+                        String totalStr = String.valueOf( total);
+                        item.setLossNumber(totalStr);
+                    }
+                }
+            }
+
+
         });
         return wareHouseDtoIPage;
     }
@@ -1069,22 +1108,137 @@ public class PsiWareHouseBasicService {
         return wareHouseDtoIPage;
     }
 
-    public IPage<PsiWareHouseDto> nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
-        IPage<PsiWareHouseDto> iPage = basicMapper.nearExpiryList(page, dto);
+    /**
+     * 根据库存的保质期和生产日期,进行临期规则筛选
+     * @param page
+     * @param dto
+     */
+    public void nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
+        Page<PsiWareHouseDto> queryPage = new Page<>();
+        queryPage.setCurrent(1);
+        queryPage.setSize(-1);
+        IPage<PsiWareHouseDto> iPage = basicMapper.nearExpiryList(queryPage, dto);
+        List<PsiWareHouseDto> list = new ArrayList<>();
+        LocalDate today = LocalDate.now(ZoneId.systemDefault());
         iPage.getRecords().forEach(item -> {
-            if (StringUtils.isNotBlank(item.getCurrentInventory())) {
-                item.setCurrentInventory(convertByBigDecimal(item.getCurrentInventory()));
+            if (!canCheckNearExpiry(item)) {
+                return;
             }
-            if (StringUtils.isNotBlank(item.getTradeNumber())) {
-                item.setTradeNumber(convertByBigDecimal(item.getTradeNumber()));
+            Integer shelfLifeValue = parseShelfLifeValue(item.getShelfLife());
+            if (shelfLifeValue == null) {
+                return;
+            }
+            LocalDate produceDate = toLocalDate(item.getProduceDate());
+            LocalDate expiryDate = calculateExpiryDate(produceDate, shelfLifeValue, item.getShelfLifeUnit());
+            if (expiryDate == null) {
+                return;
+            }
+            long totalDays = ChronoUnit.DAYS.between(produceDate, expiryDate);
+            long remainingDays = ChronoUnit.DAYS.between(today, expiryDate);
+            if (!shouldIncludeNearExpiry(totalDays, remainingDays)) {
+                return;
             }
+            item.setExpiryDate(Date.from(expiryDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
+            item.setRemainingDays((int) remainingDays);
+            list.add(item);
         });
-        return iPage;
+        if(CollectionUtil.isNotEmpty(list)){
+            String warnInfo = list.stream()
+                    .map(item -> item.getTradeName())
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.joining("、"));
+            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+            String day = format.format(new Date());
+            String title = "管理员发起了 ["+ warnInfo +"] [物资临期提醒]";
+            //向多个用户发起通知
+            List<UserDTO> usersInfo = psiDetailedMapper.getUsersInfo();
+            //获取目前领用流程的taskid,根据procInsId去查taskId
+            String uuid = "";
+            if (null != usersInfo) {
+                for (UserDTO userDTO1 : usersInfo) {
+                    uuid = UUID.randomUUID().toString();
+                    //发送通知
+                    Map<String ,String > map = new HashMap<>();
+                    map.put("taskId",uuid);
+                    map.put("title",title);
+                    map.put("defId",dto.getId());
+                    map.put("taskName","物资临期提醒");
+                    map.put("createUser","管理员");
+                    map.put("createTime",day);
+                    map.put("noticeName",userDTO1.getLoginName());
+                    map.put("noticeId",userDTO1.getId());
+                    map.put("createById","1");
+                    flowTaskService.add(map);
+                }
+            }
+        }
     }
 
     /**
      * 列表查询
      */
+    private boolean canCheckNearExpiry(PsiWareHouseDto item) {
+        return item != null
+                && item.getProduceDate() != null
+                && StringUtils.isNotBlank(item.getShelfLife())
+                && StringUtils.isNotBlank(item.getShelfLifeUnit());
+    }
+
+    private Integer parseShelfLifeValue(String shelfLife) {
+        try {
+            BigDecimal value = new BigDecimal(shelfLife.trim()).stripTrailingZeros();
+            if (value.scale() > 0 || value.compareTo(BigDecimal.ZERO) <= 0) {
+                return null;
+            }
+            return value.intValueExact();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private LocalDate toLocalDate(Date date) {
+        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+    }
+
+    private LocalDate calculateExpiryDate(LocalDate produceDate, Integer shelfLife, String shelfLifeUnit) {
+        String unit = shelfLifeUnit == null ? "" : shelfLifeUnit.trim();
+        if (unit.contains("年")) {
+            return produceDate.plusYears(shelfLife);
+        }
+        if (unit.contains("月")) {
+            return produceDate.plusMonths(shelfLife);
+        }
+        if (unit.contains("天") || unit.contains("日")) {
+            return produceDate.plusDays(shelfLife);
+        }
+        return null;
+    }
+
+    private boolean shouldIncludeNearExpiry(long totalDays, long remainingDays) {
+        if (totalDays <= 0 || remainingDays < 0) {
+            return false;
+        }
+        if (totalDays <= 30) {
+            return remainingDays * 3 <= totalDays;
+        }
+        return remainingDays * 4 <= totalDays
+                || remainingDays == 30
+                || remainingDays == 60
+                || remainingDays == 90;
+    }
+
+    private List<PsiWareHouseDto> buildNearExpiryPageRecords(List<PsiWareHouseDto> list, long current, long size) {
+        if (size <= 0) {
+            return list;
+        }
+        long start = (current - 1) * size;
+        if (start >= list.size()) {
+            return new ArrayList<>();
+        }
+        long end = Math.min(start + size, list.size());
+        return new ArrayList<>(list.subList((int) start, (int) end));
+    }
+
     public IPage<PsiWareHouseDto> getByProduceDateNotMerge(Page<PsiWareHouseDto> page , PsiWareHouseDto dto) throws Exception{
         QueryWrapper<PsiWareHouseDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiWareHouseDto.class);
 
@@ -1150,6 +1304,88 @@ public class PsiWareHouseBasicService {
     }
 
 
+    public IPage<PsiWareHouseDto> getAllData(Page<PsiWareHouseDto> page , PsiWareHouseDto dto) throws Exception{
+        QueryWrapper<PsiWareHouseDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiWareHouseDto.class);
+
+        queryWrapper.eq("a.del_flag", "0");
+
+        if (StringUtils.isNotEmpty(dto.getTradeName())) {
+            queryWrapper.like("a.trade_name", dto.getTradeName());
+        }
+        queryWrapper.and(wq ->{
+            wq.eq("bas.`status`","0")
+                    .or()
+                    .eq("bas.`status`","5");
+        });
+
+        //入库类型
+        if (StringUtils.isNotEmpty(dto.getWareHouseType())) {
+            queryWrapper.eq("c.id", dto.getWareHouseType());
+        }
+
+        //生产日期
+        if (dto.getProduceDate() != null) {
+            queryWrapper.eq("a.produce_date", dto.getProduceDate());
+        }
+
+        if (StringUtils.isNotEmpty(dto.getSupplierId())) {
+            List<PsiWareHouseDetailed> wareHouseDetaileds = psiDetailedMapper.selectList(new LambdaQueryWrapper<PsiWareHouseDetailed>().eq(PsiWareHouseDetailed::getSupplierId, dto.getSupplierId()));
+            if (CollectionUtil.isNotEmpty(wareHouseDetaileds)) {
+                List<String> containsIds = wareHouseDetaileds.stream().map(PsiWareHouseDetailed::getId).collect(Collectors.toList());
+                if (CollectionUtil.isNotEmpty(containsIds)) {
+                    queryWrapper.in("a.id", containsIds);
+                } else {
+                    return new Page<>();
+                }
+            } else {
+                return new Page<>();
+            }
+        }
+        LocalDate today = LocalDate.now(ZoneId.systemDefault());
+        IPage<PsiWareHouseDto> wareHouseDtoIPage = basicMapper.getAllData(page, queryWrapper);
+        wareHouseDtoIPage.getRecords().forEach(item -> {
+            // 将小数点后无效的0删除
+            // 总量  格式化
+            if (StringUtils.isNotBlank(item.getAllNumber())) {
+                String s = convertByBigDecimal(item.getAllNumber());
+                item.setAllNumber(s);
+            }
+            //领用量  格式化
+            if (StringUtils.isNotBlank(item.getBorrowNumber())) {
+                String s = convertByBigDecimal(item.getBorrowNumber());
+                item.setBorrowNumber(s);
+            }
+            //剩余量  格式化
+            if (StringUtils.isNotBlank(item.getTradeNumber())) {
+                String s = convertByBigDecimal(item.getTradeNumber());
+                item.setTradeNumber(s);
+            }
+            //提醒数量  格式化
+            if (StringUtils.isNotBlank(item.getWarnNum())) {
+                String s = convertByBigDecimal(item.getWarnNum());
+                item.setWarnNum(s);
+            }
+
+            if (!canCheckNearExpiry(item)) {
+                return;
+            }
+            Integer shelfLifeValue = parseShelfLifeValue(item.getShelfLife());
+            if (shelfLifeValue == null) {
+                return;
+            }
+            LocalDate produceDate = toLocalDate(item.getProduceDate());
+            LocalDate expiryDate = calculateExpiryDate(produceDate, shelfLifeValue, item.getShelfLifeUnit());
+            if (expiryDate == null) {
+                return;
+            }
+            long totalDays = ChronoUnit.DAYS.between(produceDate, expiryDate);
+            long remainingDays = ChronoUnit.DAYS.between(today, expiryDate);
+            item.setExpiryDate(Date.from(expiryDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
+            item.setRemainingDays((int) remainingDays);
+        });
+        return wareHouseDtoIPage;
+    }
+
 
     // 去除小数点后无效的0
     public String convertByBigDecimal(String value) {

+ 3 - 2
jeeplus-modules/jeeplus-psi-management/src/main/java/com/jeeplus/psimanage/psiWareHouse/service/dto/PsiWareSummaryExportDto.java

@@ -17,7 +17,7 @@ public class PsiWareSummaryExportDto {
     private String allNumber;
 
     @ExcelProperty("领用量")
-    private String borrowNumber;
+    private String notSurplusStock;
 
     @ExcelProperty("报损量")
     private String lossNumber;
@@ -34,5 +34,6 @@ public class PsiWareSummaryExportDto {
     @ExcelProperty("是否提醒")
     private String warnFlag;
 
-
+    @ExcelIgnore
+    private String spec;
 }

+ 9 - 0
jeeplus-modules/jeeplus-xxl-job-executor-sample/src/main/java/com/xxl/job/executor/feign/PsiManagementFeignApi.java

@@ -0,0 +1,9 @@
+package com.xxl.job.executor.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.feign.IPsiManagementApi;
+import org.springframework.cloud.openfeign.FeignClient;
+
+@FeignClient(contextId = "psiManagementFeignApi", name = AppNameConstants.APP_PSI_MANAGEMENT_MODULES)
+public interface PsiManagementFeignApi extends IPsiManagementApi {
+}

+ 14 - 4
jeeplus-modules/jeeplus-xxl-job-executor-sample/src/main/java/com/xxl/job/executor/service/jobhandler/SampleXxlJob.java

@@ -5,10 +5,7 @@ import cn.hutool.extra.spring.SpringUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
 import com.jeeplus.domain.*;
-import com.jeeplus.flowable.feign.IAssessApi;
-import com.jeeplus.flowable.feign.IFinanceApi;
-import com.jeeplus.flowable.feign.IFlowableApi;
-import com.jeeplus.flowable.feign.IHumanApi;
+import com.jeeplus.flowable.feign.*;
 import com.jeeplus.sys.feign.*;
 import com.jeeplus.sys.service.dto.UserDTO;
 import com.xxl.job.core.context.XxlJobHelper;
@@ -1204,4 +1201,17 @@ public class SampleXxlJob {
         }
     }
 
+
+    /**
+     * 查询即将过期的物资
+     */
+    @XxlJob("nearExpiryList")
+    public void nearExpiryList() {
+        try {
+            SpringUtil.getBean(IPsiManagementApi.class).nearExpiryList();
+        } catch (Exception e) {
+            logger.warn("调用失败,可能服务不存在", e);
+        }
+    }
+
 }