Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/ScrmStores' into ScrmStores

吴树波 4 dienas atpakaļ
vecāks
revīzija
90b82d03f2
53 mainītis faili ar 800 papildinājumiem un 269 dzēšanām
  1. 4 4
      fs-admin/src/main/java/com/fs/company/controller/CompanyController.java
  2. 4 4
      fs-admin/src/main/java/com/fs/his/controller/FsCompanyController.java
  3. 32 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java
  4. 26 0
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  5. 4 4
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreProductScrmController.java
  6. 0 10
      fs-admin/src/main/java/com/fs/web/controller/system/SysUserController.java
  7. 1 1
      fs-service/src/main/java/com/fs/company/service/ICompanyService.java
  8. 1 5
      fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  9. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  10. 3 3
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  11. 2 1
      fs-service/src/main/java/com/fs/his/mapper/FsDoctorMapper.java
  12. 3 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreAfterSalesScrm.java
  13. 4 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java
  14. 5 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreScrm.java
  15. 2 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreVerifyCodeScrm.java
  16. 36 0
      fs-service/src/main/java/com/fs/hisStore/enums/StoreProductTypeEnum.java
  17. 9 3
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java
  18. 12 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  19. 18 2
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  20. 5 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreVerifyCodeScrmMapper.java
  21. 2 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreCartNumParam.java
  22. 2 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreCartParam.java
  23. 3 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderParam.java
  24. 5 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreScrmInfoParam.java
  25. 2 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  26. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreProductScrmService.java
  27. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/AbstractHandler.java
  28. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/CommonCheck.java
  29. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IIIMedicalDeviceCheck.java
  30. 4 6
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IIMedicalDeviceCheck.java
  31. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IMedicalDeviceCheck.java
  32. 2 1
      fs-service/src/main/java/com/fs/hisStore/service/categoryVal/WellnessFoodCheck.java
  33. 74 15
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreCartScrmServiceImpl.java
  34. 170 93
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  35. 4 3
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java
  36. 3 1
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreScrmServiceImpl.java
  37. 3 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesVO.java
  38. 4 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreDetailsScrmVo.java
  39. 2 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java
  40. 1 1
      fs-service/src/main/java/com/fs/hospital580/util/ThumbnailatorWatermark.java
  41. 8 1
      fs-service/src/main/java/com/fs/system/service/impl/SysDeptServiceImpl.java
  42. 25 2
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  43. 38 25
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  44. 5 23
      fs-service/src/main/resources/mapper/hisStore/FsStoreScrmMapper.xml
  45. 14 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreVerifyCodeScrmMapper.xml
  46. 1 1
      fs-service/src/main/resources/mapper/system/SysDeptMapper.xml
  47. 30 0
      fs-store/src/main/java/com/fs/hisStore/controller/store/FsStoreOrderScrmController.java
  48. 4 1
      fs-store/src/main/java/com/fs/hisStore/controller/store/FsStoreProductScrmController.java
  49. 14 0
      fs-user-app/pom.xml
  50. 7 2
      fs-user-app/src/main/java/com/fs/app/controller/store/ProductScrmController.java
  51. 18 2
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java
  52. 124 0
      fs-user-app/src/main/java/com/fs/app/redis/OrderExpireHandler.java
  53. 49 47
      fs-user-app/src/main/java/com/fs/app/redis/RedisKeyExpirationListener.java

+ 4 - 4
fs-admin/src/main/java/com/fs/company/controller/CompanyController.java

@@ -116,9 +116,9 @@ public class CompanyController extends BaseController
     public R add(@RequestBody Company company)
     {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-//        if(company.getDeptId() != null){//位置迁移到实现类中
-//            company.setDeptId(loginUser.getDeptId());
-//        }
+        if(company.getDeptId() != null){
+            company.setDeptId(loginUser.getDeptId());
+        }
         company.setCreateBy(loginUser.getUsername());
         company.setOldDeptId(loginUser.getDeptId());
         company.setAdmin(loginUser.isAdmin());
@@ -126,7 +126,7 @@ public class CompanyController extends BaseController
         company.setAppId(Md5Utils.hash(company.getUserName()));
         company.setAppKey(Md5Utils.hash(company.getPassword()));
         company.setOmsCode("SF.1");
-        return companyService.insertCompany(company,loginUser.getDeptId());
+        return companyService.insertCompany(company);
     }
 
     /**

+ 4 - 4
fs-admin/src/main/java/com/fs/his/controller/FsCompanyController.java

@@ -152,13 +152,13 @@ public class FsCompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-//        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
-//            company.setDeptId(loginUser.getDeptId());
-//        }
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
+            company.setDeptId(loginUser.getDeptId());
+        }
         company.setAdmin(loginUser.isAdmin());
         company.setOldDeptId(loginUser.getDeptId());
         company.setCreateBy(loginUser.getUsername());
-        return companyService.insertCompany(company,loginUser.getDeptId());
+        return companyService.insertCompany(company);
     }
 
     /**

+ 32 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java

@@ -1,5 +1,7 @@
 package com.fs.hisStore.controller;
 
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -14,6 +16,7 @@ import com.fs.framework.web.service.TokenService;
 import com.fs.his.domain.FsUser;
 import com.fs.his.service.IFsUserService;
 import com.fs.hisStore.domain.*;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
 import com.fs.hisStore.param.FsStoreAfterSalesAudit1Param;
 import com.fs.hisStore.param.FsStoreAfterSalesAudit2Param;
 import com.fs.hisStore.param.FsStoreAfterSalesCancelParam;
@@ -25,7 +28,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import java.text.ParseException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 售后记录Controller
@@ -53,6 +58,10 @@ public class FsStoreAfterSalesScrmController extends BaseController
 
     @Autowired
     private TokenService tokenService;
+
+    @Autowired
+    private FsStoreVerifyCodeScrmMapper fsStoreVerifyCodeService;
+
     /**
      * 查询售后记录列表
      */
@@ -106,9 +115,31 @@ public class FsStoreAfterSalesScrmController extends BaseController
         statusMap.setStoreAfterSalesId(id);
         List<FsStoreAfterSalesStatusScrm> logs=storeAfterSalesStatusService.selectFsStoreAfterSalesStatusList(statusMap);
         FsUser user=userService.selectFsUserById(afterSales.getUserId());
-        user.setPhone(ParseUtils.parsePhone(user.getPhone()));
+//        user.setPhone(ParseUtils.parsePhone(user.getPhone()));
         FsStoreOrderScrm order=fsStoreOrderService.selectFsStoreOrderByOrderCode(afterSales.getOrderCode());
         FsStoreScrm storeScrm = storeScrmService.selectFsStoreByStoreId(order.getStoreId());
+
+        //获取溯源码相关数据
+        List<FsStoreVerifyCodeScrm> verifyCodes = fsStoreVerifyCodeService.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().select(FsStoreVerifyCodeScrm::getVerifyCode,FsStoreVerifyCodeScrm::getProductId).eq(FsStoreVerifyCodeScrm::getOrderId, order.getId()));
+        if(!verifyCodes.isEmpty()){
+            Map<Long, String> verifyCodMap=new HashMap<>();
+            for (FsStoreVerifyCodeScrm v : verifyCodes){
+                if(verifyCodMap.containsKey(v.getProductId())){
+                    verifyCodMap.put(v.getProductId(),verifyCodMap.get(v.getProductId())+","+v.getVerifyCode());
+                }else {
+                    verifyCodMap.put(v.getProductId(),v.getVerifyCode());
+                }
+            }
+
+            for (FsStoreAfterSalesItemScrm item : items){
+                if(verifyCodMap.containsKey(item.getProductId())){
+                    JSONObject jsonObject = JSONObject.parseObject(item.getJsonInfo());
+                    jsonObject.put("verifyCods", verifyCodMap.get(item.getProductId()));
+                    item.setJsonInfo(jsonObject.toJSONString());
+                }
+            }
+
+        }
         return R.ok().put("afterSales",afterSales).put("items",items).put("logs",logs).put("user",user).put("order",order).put("store",storeScrm);
     }
 

+ 26 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -48,6 +49,7 @@ import com.fs.his.dto.ExpressInfoDTO;
 import com.fs.hisStore.dto.StoreOrderExpressExportDTO;
 import com.fs.hisStore.dto.StoreOrderProductDTO;
 import com.fs.hisStore.enums.ShipperCodeEnum;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.*;
 import com.fs.hisStore.vo.*;
@@ -140,6 +142,9 @@ public class FsStoreOrderScrmController extends BaseController {
     @Autowired
     private  IFsStoreScrmService iFsStoreScrmService;
 
+    @Autowired
+    private FsStoreVerifyCodeScrmMapper fsStoreVerifyCodeService;
+
     private IErpOrderService getErpService(){
         //判断是否开启erp
         IErpOrderService erpOrderService = null;
@@ -576,6 +581,27 @@ public class FsStoreOrderScrmController extends BaseController {
             tuiMoneyLogs=moneyLogsService.selectCompanyStoreOrderMoneyLogsList(moneyLogsMap);
         }
 
+        //获取溯源码相关数据
+        List<FsStoreVerifyCodeScrm> verifyCodes = fsStoreVerifyCodeService.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().select(FsStoreVerifyCodeScrm::getVerifyCode,FsStoreVerifyCodeScrm::getProductId).eq(FsStoreVerifyCodeScrm::getOrderId, order.getId()));
+        if(!verifyCodes.isEmpty()){
+            Map<Long, String> verifyCodMap=new HashMap<>();
+            for (FsStoreVerifyCodeScrm v : verifyCodes){
+                if(verifyCodMap.containsKey(v.getProductId())){
+                    verifyCodMap.put(v.getProductId(),verifyCodMap.get(v.getProductId())+","+v.getVerifyCode());
+                }else {
+                    verifyCodMap.put(v.getProductId(),v.getVerifyCode());
+                }
+            }
+
+            for (FsStoreOrderItemScrm item : items){
+                if(verifyCodMap.containsKey(item.getProductId())){
+                    JSONObject jsonObject = JSONObject.parseObject(item.getJsonInfo());
+                    jsonObject.put("verifyCods", verifyCodMap.get(item.getProductId()));
+                    item.setJsonInfo(jsonObject.toJSONString());
+                }
+            }
+
+        }
         List<FsStoreOrderAuditLogVO> auditLogs = orderAuditLogService.selectStoreOrderAuditLogVOByOrderId(order.getId());
         return R.ok().put("order", order).put("items", items).put("logs", logs).put("user", user).put("payments",payments).put("tuiMoneyLogs",tuiMoneyLogs)
                 .put("auditLogs",auditLogs).put("storeScrm",storeScrm);

+ 4 - 4
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreProductScrmController.java

@@ -93,7 +93,9 @@ public class FsStoreProductScrmController extends BaseController {
     @PostMapping("/checkStoreDrugLicense")
     public R checkStoreDrugLicense(@RequestBody FsStoreProductAddEditParam fsStoreProduct) {
         return R.ok().put("data", fsStoreProductService.checkStoreDrugLicense(fsStoreProduct.getStoreId(), fsStoreProduct.getCateId(),
-                org.apache.commons.lang3.StringUtils.isEmpty(fsStoreProduct.getMedicalDeviceCode())?null:fsStoreProduct.getMedicalDeviceCode()));
+                org.apache.commons.lang3.StringUtils.isEmpty(fsStoreProduct.getMedicalDeviceCode())?null:fsStoreProduct.getMedicalDeviceCode(),
+                ObjectUtils.isNotNull(fsStoreProduct.getProductType())?fsStoreProduct.getProductType().toString():null)
+        );
     }
 
     /**
@@ -298,12 +300,11 @@ public class FsStoreProductScrmController extends BaseController {
         return R.ok("操作完成");
     }
 
-    @Log(title = "总后台商品协议过期提醒", businessType = BusinessType.OTHERe)
     /**
      * 商品资质信息提示
-     *
      * @return
      */
+    @Log(title = "总后台商品协议过期提醒", businessType = BusinessType.OTHERe)
     @GetMapping("/productNoticeInfo")
     public R getProductNoticeInfo() {
         List<String> productNoticeInfo = fsStoreProductService.getProductNoticeInfo(null);
@@ -313,7 +314,6 @@ public class FsStoreProductScrmController extends BaseController {
         return R.ok().put("code", 0);
     }
 
-
     /**
      * 商品审核日志
      * */

+ 0 - 10
fs-admin/src/main/java/com/fs/web/controller/system/SysUserController.java

@@ -293,16 +293,6 @@ public class SysUserController extends BaseController
     @Log(title = "总后台:商家证件即将过期或已过期提醒", businessType = BusinessType.OTHER)
     @GetMapping("/storeRecommendNotice")
     public R storeRecommendNotice(){
-//        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        //判断是否有权限
-//        if(userService.checkUserAuthority(loginUser.getUserId())){
-//            //有权限则进入判断是否协议过期
-//            List<String> storeList=storeScrmService.queryValidStoreQualifications();
-//            if(!storeList.isEmpty()){
-//                //拼接提示语句
-//                return R.ok().put("code",200).put("data",storeList);
-//            }
-//        }
         //有权限则进入判断是否协议过期
         List<String> storeList=storeScrmService.queryValidStoreQualifications();
         if(!storeList.isEmpty()){

+ 1 - 1
fs-service/src/main/java/com/fs/company/service/ICompanyService.java

@@ -53,7 +53,7 @@ public interface ICompanyService
      * @param company 企业
      * @return 结果
      */
-    public R insertCompany(Company company,Long userDeptId);
+    public R insertCompany(Company company);
 
     /**
      * 修改企业

+ 1 - 5
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -159,7 +159,7 @@ public class CompanyServiceImpl implements ICompanyService
      */
     @Override
     @Transactional
-    public R insertCompany(Company company,Long userDeptId)
+    public R insertCompany(Company company)
     {
         //帐号是否存在
         if(userMapper.checkUserName(company.getUserName())>0){
@@ -183,10 +183,6 @@ public class CompanyServiceImpl implements ICompanyService
             sysDeptConfigService.updateById(deptConfig);
         }
 
-        if(company.getDeptId() != null){
-            company.setDeptId(userDeptId);
-        }
-
         if(companyMapper.insertCompany(company)>0){
             //写入帐号信息
             //创建部门

+ 1 - 1
fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -857,7 +857,7 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
                 query = URLEncoder.encode(query, StandardCharsets.UTF_8.toString());
 
 
-                List<FsCoursePlaySourceConfig> list = fsCoursePlaySourceConfigService.list(new QueryWrapper<FsCoursePlaySourceConfig>().ne("type", 2).eq("is_del", 0));
+                List<FsCoursePlaySourceConfig> list = fsCoursePlaySourceConfigService.list(new QueryWrapper<FsCoursePlaySourceConfig>().eq("appid",appId).ne("type", 2).eq("is_del", 0));
 //                SysConfig sysConfig3 = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
 //                List<CourseMaConfig> courseMaConfigs = JSON.parseArray(sysConfig3.getConfigValue(), CourseMaConfig.class);
                 if (list!=null&& !list.isEmpty()){

+ 3 - 3
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -496,9 +496,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             return R.error(401,"未授权");
         }
 
-        if (StringUtil.strIsNullOrEmpty(fsUser.getMpOpenId())){
-            return R.error(401,"授权后可继续!");
-        }
+//        if (StringUtil.strIsNullOrEmpty(fsUser.getMpOpenId())){
+//            return R.error(401,"授权后可继续!");
+//        }
 
         if (fsUser.getStatus()==0){
             return R.error("会员被停用,无权限,请联系客服!");

+ 2 - 1
fs-service/src/main/java/com/fs/his/mapper/FsDoctorMapper.java

@@ -218,7 +218,8 @@ public interface FsDoctorMapper
      */
     List<FsDoctorListUVO> getFsDoctorListUVOListByIds(@Param("doctorIds") List<Long> doctorIds);
 
-    @Select("SELECT * FROM fs_doctor WHERE store_id=#{storeId} and doctor_type = 2 and  `status`=1 and is_audit=1 and sign_url is not null ORDER BY RAND() LIMIT 1; ")
+//    @Select("SELECT * FROM fs_doctor WHERE store_id=#{storeId} and doctor_type = 2 and  `status`=1 and is_audit=1 and sign_url is not null ORDER BY RAND() LIMIT 1; ")
+    @Select("SELECT * FROM fs_doctor WHERE store_id=#{storeId} and doctor_type = 2 and  `status`=1 and is_audit=1  ORDER BY RAND() LIMIT 1; ")
     FsDoctor findByStoreId(@Param("storeId") Long storeId);
     String selectDoctorNameByIds(@Param("doctorIds") String doctorIds);
 

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreAfterSalesScrm.java

@@ -175,4 +175,7 @@ public class FsStoreAfterSalesScrm extends BaseEntity
     private Integer transactionStatus;
     //评价投诉
     private String complaint;
+
+    //核销溯源码
+    private String verifyCodes;
 }

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -386,4 +386,8 @@ public class FsStoreOrderScrm extends BaseEntity
     //组合订单标识
     private String combinationOrderId;
 
+    //溯源码
+    @TableField(exist = false)
+    private String verifyCodes;
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreScrm.java

@@ -495,5 +495,10 @@ public class FsStoreScrm extends BaseEntity {
      **/
     private String medicalDevice3BusinessScope;
 
+    /**
+     * 药店经营范围
+     **/
+    private String drugLicenseBusinessScope;
+
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreVerifyCodeScrm.java

@@ -55,5 +55,7 @@ public class FsStoreVerifyCodeScrm extends BaseEntity{
     //是否回收(0否1是)
     private Long isRecycle;
 
+    //购物车ID
+    private Long carId;
 
 }

+ 36 - 0
fs-service/src/main/java/com/fs/hisStore/enums/StoreProductTypeEnum.java

@@ -0,0 +1,36 @@
+package com.fs.hisStore.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.stream.Stream;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/12/3 下午4:11
+ */
+@Getter
+@AllArgsConstructor
+public enum StoreProductTypeEnum {
+
+    OTC("1","OTC"),
+    RX("2","Rx"),
+    QI_XIE("4","器械"),
+    FYP("3","非药品"),
+    QI_MIAN("5","器免");
+
+    private String value;
+
+    private String desc;
+
+    public static AfterSalesStatusEnum toType(String value) {
+        return Stream.of(AfterSalesStatusEnum.values())
+                .filter(p -> p.getValue().equals(value))
+                .findFirst()
+                .orElse(null);
+    }
+
+
+
+}

+ 9 - 3
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -88,7 +88,7 @@ public interface FsStoreAfterSalesScrmMapper
 
     @Select({"<script> " +
             "select DISTINCT s.*,o.delivery_status,o.delivery_id,u.phone as user_phone,c.company_name ," +
-            "cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,ssc.store_name as storeName,ssc.store_seq as storeSeq,ssc.merchant_id as merchantId,hps.serial_no  " +
+            "cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,ssc.store_name as storeName,ssc.store_seq as storeSeq,ssc.merchant_id as merchantId,hps.serial_no,vc.verify_code AS verifyCodes  " +
             "from fs_store_after_sales_scrm s INNER join fs_store_order_scrm o on o.order_code=s.order_code " +
             "inner join fs_store_order_item_scrm ois on o.id = ois.order_id " +
             "inner join fs_store_product_scrm p on  p.product_id = ois.product_id " +
@@ -96,6 +96,7 @@ public interface FsStoreAfterSalesScrmMapper
             "left join company_user cu on cu.user_id=s.company_user_id " +
             "left join fs_store_scrm ssc on o.store_id=ssc.store_id " +
             "left join fs_store_hospital580_prescription_scrm hps on hps.store_order_id = o.id " +
+            "LEFT JOIN fs_store_verify_code_scrm vc ON o.id = vc.order_id " +
             "<if test = 'maps.complaint != null and maps.complaint.trim() !=  \"\" '> " +
             "inner join fs_user_complaint uc on FIND_IN_SET(p.product_id, uc.product_ids) " +
             "</if>" +
@@ -142,6 +143,9 @@ public interface FsStoreAfterSalesScrmMapper
             "<if test = 'maps.consigneePhone != null and  maps.consigneePhone !=\"\"     '> " +
             "and o.user_phone like CONCAT('%',#{maps.consigneePhone},'%') " +
             "</if>" +
+            "          <if test=\"maps.verifyCodes != null and  maps.verifyCodes !=  '' \">\n" +
+            "                and vc.verify_code like concat('%', #{maps.verifyCodes}, '%')\n" +
+            "            </if>" +
             "<if test = 'maps.endTime != null and maps.endTime != \"\"   '> " +
             " AND date_format(s.create_time,'%y%m%d') &lt;= date_format(#{maps.endTime},'%y%m%d') " +
             "</if>" +
@@ -270,12 +274,14 @@ public interface FsStoreAfterSalesScrmMapper
             "</script>"})
     List<FsStoreAfterSalesExcelVO> selectFsStoreAfterSalesExcelListVO(@Param("maps") FsStoreAfterSalesParam fsStoreAfterSales);
 
-    @Select("select so.*,st.store_name,us.nick_name,us.phone,fso.order_code " +
+
+    @Select("select so.*,st.store_name,us.nick_name,us.phone,fso.order_code, GROUP_CONCAT(cs.verify_code) AS verifyCodes " +
             "FROM fs_store_after_sales_scrm so " +
             "LEFT JOIN fs_store_scrm st ON so.store_id =st.store_id " +
             "LEFT JOIN fs_user us ON us.user_id=so.user_id " +
             "LEFT JOIN fs_store_order_scrm fso ON fso.id=so.order_code " +
-            "WHERE so.id=#{id} ")
+            "LEFT JOIN fs_store_verify_code_scrm cs ON cs.order_id = fso.id " +
+            "WHERE so.id=#{id} GROUP BY so.id, st.store_name, us.nick_name, us.phone, fso.order_code;")
     FsStoreAfterSalesVO selectFsStoreAfterSalesVOById(Long id);
 
     @Select("select * FROM fs_store_after_sales_item_scrm WHERE store_after_sales_id =#{id}")

+ 12 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java

@@ -6,6 +6,7 @@ import java.util.List;
 import java.util.Map;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.api.param.OrderListParam;
 import com.fs.api.vo.OrderListVO;
 import com.fs.company.param.CompanyStatisticsParam;
@@ -31,7 +32,7 @@ import org.apache.ibatis.annotations.Update;
  * @author fs
  * @date 2022-03-15
  */
-public interface FsStoreOrderScrmMapper
+public interface FsStoreOrderScrmMapper extends BaseMapper<FsStoreOrderScrm>
 {
     /**
      * 查询订单
@@ -1414,4 +1415,14 @@ public interface FsStoreOrderScrmMapper
      * @return lsit
      * **/
     List<FsStoreOrderCodeOpenIdVo> selectOrderCodeOpenIdInOrderCode(@Param("list") List<String> list);
+
+    /**
+     * 查询超时未支付的订单
+     * @param params 包含以下参数:
+     *               - now: LocalDateTime 当前时间
+     *               - prescribeTimeoutMinutes: 处方订单超时分钟数
+     *               - unPayTime: 非处方订单超时分钟数
+     * @return 超时订单列表
+     */
+    List<FsStoreOrderScrm> selectTimeoutUnpaidOrders(Map<String, Object> params);
 }

+ 18 - 2
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -329,12 +329,23 @@ public interface FsStoreProductScrmMapper
 
     @Select({"<script> " +
             "  select p.*,pc.cate_name,hs.push_status from (SELECT ave.bar_code as bar_code,p.product_id, p.image, p.slider_image,p.product_name, p.product_info,p.keyword, p.cate_id, p.price, p.vip_price, " +
-            " p.ot_price,p.agent_price, p.postage,p.unit_name,p.sort,( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 1 AND is_del = 0) AS sales,( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 0 AND is_del = 0) AS stock,p.is_show,p.is_hot,p.is_benefit,p.is_best,p.is_new,p.description,p.create_time,p.update_time,p.is_postage,p.is_del,p.give_integral," +
+            " p.ot_price,p.agent_price, p.postage,p.unit_name,p.sort,CASE \n" +
+            "\tWHEN p.cate_id = '202' OR p.cate_id = '232' OR p.cate_id = '201' OR P.cate_id = '233' THEN\n" +
+            "\t\tp.stock\n" +
+            "\tELSE\n" +
+            "\t\t( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 0 AND is_del = 0)\n" +
+            "END AS stock,\n" +
+            " CASE \n" +
+            "\tWHEN p.cate_id = '202' OR p.cate_id = '232' OR p.cate_id = '201' OR P.cate_id = '233' THEN\n" +
+            "\t\tp.sales\n" +
+            "\tELSE\n" +
+            "\t\t( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 1 AND is_del = 0)\n" +
+            "END AS sales,p.is_show,p.is_hot,p.is_benefit,p.is_best,p.is_new,p.description,p.create_time,p.update_time,p.is_postage,p.is_del,p.give_integral," +
             " p.cost,p.is_good,p.browse,p.code_path,p.temp_id,p.spec_type,p.is_integral,p.integral,p.product_type,p.prescribe_code, p.prescribe_spec,p.prescribe_factory,p.prescribe_name,p.is_display,p.tui_cate_id" +
             " FROM fs_store_product_scrm p LEFT JOIN fs_store_product_attr_value_scrm ave on p.product_id=ave.product_id  WHERE ave.bar_code != '' and p.product_id is not null" +
             ") p left join fs_store_product_category_scrm pc on p.cate_id=pc.cate_id   " +
             "left join (select product_id, push_status from fs_store_hospital580_product_push_scrm h1 where h1.id = (select max(h2.id) from fs_store_hospital580_product_push_scrm h2 where h2.product_id = h1.product_id)) hs on hs.product_id = p.product_id " +
-            " where 1=1 " +
+            " where 1=1  and p.is_drug = 1" +
             "<if test = 'maps.productName != null and  maps.productName !=\"\"  '> " +
             "and p.product_name like CONCAT('%',#{maps.productName},'%') " +
             "</if>" +
@@ -696,4 +707,9 @@ public interface FsStoreProductScrmMapper
      * 普通商品我猜你喜欢列表
      * **/
     List<FsStoreProductListQueryVO> selectFsStoreProductGoodListList();
+
+    /**
+     * 批量更新商品信息
+     * **/
+    int updateBatchById(@Param("updateProducts") List<FsStoreProductScrm> updateProducts);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreVerifyCodeScrmMapper.java

@@ -84,4 +84,9 @@ public interface FsStoreVerifyCodeScrmMapper extends BaseMapper<FsStoreVerifyCod
     List<FsStoreVerifyCodeScrm> selectUnOutboundVerifyCodesWithLock(
             @Param("productId") Long productId,
             @Param("count") Integer count);
+
+    /**
+     * 批量更新状态
+     * **/
+    void updateOutboundStatus(@Param("list") List<FsStoreVerifyCodeScrm> list);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreCartNumParam.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.param;
 
 import io.swagger.annotations.ApiModelProperty;
+import io.swagger.models.auth.In;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -21,5 +22,6 @@ public class FsStoreCartNumParam {
     @ApiModelProperty(value = "购物车ID")
     private Long id;
 
+    private Integer type;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreCartParam.java

@@ -28,5 +28,7 @@ public class FsStoreCartParam {
     @ApiModelProperty(value = "是否购买")
     private Integer isBuy=0;
 
+    //类型null默认1医药
+    private Integer type;
 
 }

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreOrderParam.java

@@ -149,4 +149,7 @@ public class FsStoreOrderParam extends BaseEntity implements Serializable
      private Integer transactionStatus;
      //评价投诉
      private String complaint;
+
+     //核销溯源码
+     private String verifyCodes;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreScrmInfoParam.java

@@ -276,6 +276,11 @@ public class FsStoreScrmInfoParam extends BaseEntity
      **/
     private String medicalDevice3BusinessScope;
 
+    /**
+     * 药店经营范围
+     **/
+    private String drugLicenseBusinessScope;
+
 
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -351,4 +351,6 @@ public interface IFsStoreOrderScrmService
     R dfOrderResult(String body);
 
     R receiveWaybillPush(String body);
+
+    void cancelOrderReuse(FsStoreOrderScrm order);
 }

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreProductScrmService.java

@@ -197,8 +197,9 @@ public interface IFsStoreProductScrmService
      * @param storeId 店铺Id
      * @param cateId 分类id
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    ContainsResult checkStoreDrugLicense(Long storeId, Long cateId, String medicalDeviceCode);
+    ContainsResult checkStoreDrugLicense(Long storeId, Long cateId, String medicalDeviceCode, String productType);
 
     /**
      * 普通商品查询

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/AbstractHandler.java

@@ -15,8 +15,9 @@ public abstract class AbstractHandler implements InitializingBean {
      * @param cateName 分类名称
      * @param storeId 店铺id
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode){
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         throw new UnsupportedOperationException();
     }
 

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/CommonCheck.java

@@ -37,8 +37,9 @@ public class CommonCheck extends AbstractHandler {
      * @param cateName 分类名称
      * @param storeId  店铺id
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode) {
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType) {
         FsStoreScrm fsStoreScrm = fsStoreScrmService.selectFsStoreByStoreId(storeId);
         //没有搜索到就调用一次识别
         ContainsResult result = new ContainsResult();

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IIIMedicalDeviceCheck.java

@@ -34,8 +34,9 @@ public class IIIMedicalDeviceCheck extends AbstractHandler{
      * @param cateName
      * @param storeId
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode){
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         log.info("3类器械验证");
         FsStoreScrm fsStoreScrm = fsStoreScrmService.selectFsStoreByStoreId(storeId);
         ContainsResult result = new ContainsResult();

+ 4 - 6
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IIMedicalDeviceCheck.java

@@ -5,6 +5,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.txocr.ContainsResult;
 import com.fs.common.utils.txocr.TxOcrClient;
 import com.fs.hisStore.domain.FsStoreScrm;
+import com.fs.hisStore.enums.StoreProductTypeEnum;
 import com.fs.hisStore.service.impl.FsStoreScrmServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -12,7 +13,6 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
 
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,9 +30,6 @@ public class IIMedicalDeviceCheck extends AbstractHandler{
 
     private static final List<String> medicalDeviceCodes = Arrays.asList("07", "14", "6840", "18", "19", "22");
 
-
-
-
     @Override
     public void afterPropertiesSet() throws Exception {
         ProductCategoryCheckFactory.register("232", this);
@@ -43,8 +40,9 @@ public class IIMedicalDeviceCheck extends AbstractHandler{
      * @param cateName
      * @param storeId
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode){
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         log.info("2类器械验证");
         FsStoreScrm fsStoreScrm = fsStoreScrmService.selectFsStoreByStoreId(storeId);
         ContainsResult result = new ContainsResult();
@@ -58,7 +56,7 @@ public class IIMedicalDeviceCheck extends AbstractHandler{
             result.setMessage("没有上传2类证书不允许选择该分类!");
             return result;
         }
-        if(medicalDeviceCodes.contains(medicalDeviceCode)){
+        if(StoreProductTypeEnum.QI_MIAN.getValue().equals(productType) && medicalDeviceCodes.contains(medicalDeviceCode)){
             result.setFlag(true);
             result.setMessage("符合所选商品分类标准");
             return result;

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/IMedicalDeviceCheck.java

@@ -40,8 +40,9 @@ public class IMedicalDeviceCheck extends AbstractHandler{
      * @param cateName
      * @param storeId
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode){
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         log.info("第一类医疗器械销售检查");
         FsStoreScrmOcr fsStoreScrmOcr = fsStoreScrmOcrMapper.selectById(storeId);
         if (ObjectUtil.isEmpty(fsStoreScrmOcr)) {

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/service/categoryVal/WellnessFoodCheck.java

@@ -30,8 +30,9 @@ public class WellnessFoodCheck extends AbstractHandler{
      * @param cateName 分类名称
      * @param storeId 店铺id
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
-    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode){
+    public ContainsResult check(String cateName, Long storeId, String medicalDeviceCode, String productType){
         FsStoreScrm fsStoreScrm = fsStoreScrmService.selectFsStoreByStoreId(storeId);
         ContainsResult result = new ContainsResult();
         boolean flag = StringUtils.isNotEmpty(fsStoreScrm.getFoodLicense());

+ 74 - 15
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreCartScrmServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.hisStore.service.impl;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
@@ -13,15 +14,9 @@ import com.fs.erp.service.IErpGoodsService;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.hisStore.config.FsErpConfig;
 import com.fs.hisStore.config.MedicalMallConfig;
-import com.fs.hisStore.domain.FsStoreCartScrm;
-import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
-import com.fs.hisStore.domain.FsStoreProductGroupScrm;
-import com.fs.hisStore.domain.FsStoreScrm;
+import com.fs.hisStore.domain.*;
 import com.fs.hisStore.dto.StoreProductGroupDTO;
-import com.fs.hisStore.mapper.FsStoreCartScrmMapper;
-import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
-import com.fs.hisStore.mapper.FsStoreProductGroupScrmMapper;
-import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
+import com.fs.hisStore.mapper.*;
 import com.fs.hisStore.param.FsStoreCartCountParam;
 import com.fs.hisStore.param.FsStoreCartDelParam;
 import com.fs.hisStore.param.FsStoreCartNumParam;
@@ -35,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import com.fs.hisStore.vo.FsStoreCartGroupStoreVO;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -74,6 +70,9 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private FsStoreVerifyCodeScrmMapper verifyCodeScrmMapper;
+
 
 
     /**
@@ -165,7 +164,13 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
                     .isBuy(cartParam.getIsBuy())
                     .build();
             storeCart.setCreateTime(new Date());
-            checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+            if(cartParam.getType() == 1 && checkProductCater(storeCart.getProductId())){//加入校验
+                if(checkCarNumber(storeCart.getProductId(),storeCart.getCartNum())){
+                    return R.error("商品数量大于库存数量!");
+                }
+            }else {
+                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+            }
             fsStoreCartMapper.insertFsStoreCart(storeCart);
             return R.ok().put("id",storeCart.getId());
 
@@ -191,7 +196,13 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
                         .isBuy(0)
                         .build();
                 storeCart.setCreateTime(new Date());
-                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                if(cartParam.getType() == 1 && checkProductCater(storeCart.getProductId())){//加入校验
+                    if(checkCarNumber(storeCart.getProductId(),storeCart.getCartNum())){
+                        return R.error("商品数量大于库存数量!");
+                    }
+                }else {
+                    checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                }
                 fsStoreCartMapper.insertFsStoreCart(storeCart);
                 return R.ok().put("id",storeCart.getId());
             }
@@ -199,7 +210,13 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
                 storeCart=cart.get(0);
                 storeCart.setCartNum(cartParam.getCartNum() + cart.get(0).getCartNum());
                 storeCart.setUpdateTime(new Date());
-                checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                if(cartParam.getType() == 1 && checkProductCater(storeCart.getProductId())){//加入校验
+                    if(checkCarNumber(storeCart.getProductId(),storeCart.getCartNum())){
+                        return R.error("商品数量大于库存数量!");
+                    }
+                }else {
+                    checkProductStock(cartParam.getProductId(),storeCart.getProductAttrValueId());
+                }
                 fsStoreCartMapper.updateFsStoreCart(storeCart);
                 return R.ok().put("id",storeCart.getId());
             }
@@ -221,13 +238,33 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R changeNum(long userId, FsStoreCartNumParam cartParam) {
-        FsStoreCartScrm cart=fsStoreCartMapper.selectFsStoreCartById(cartParam.getId());
-        checkProductStock(cart.getProductId(),cart.getProductAttrValueId());
-        cart.setCartNum(cartParam.getNumber());
+        FsStoreCartScrm cart = fsStoreCartMapper.selectFsStoreCartById(cartParam.getId());
+        if (cart == null) {
+            return R.error("购物车商品不存在!");
+        }
+        int targetNum = cartParam.getNumber();
+        if(cartParam.getType() != null){
+            checkProductStock(cart.getProductId(), cart.getProductAttrValueId());
+        }else {
+            Integer availableStock = verifyCodeScrmMapper.selectCount(
+                    new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
+                            .eq(FsStoreVerifyCodeScrm::getProductId, cart.getProductId())
+                            .eq(FsStoreVerifyCodeScrm::getOutboundStatus, 0L)
+                            .eq(FsStoreVerifyCodeScrm::getIsDel, 0L)
+            );
+            if (targetNum > availableStock) {
+                FsStoreProductScrm product = fsStoreProductMapper.selectFsStoreProductById(cart.getProductId());
+                return R.error("商品" + product.getProductName() + ":库存不足!当前可用库存:" + availableStock);
+            }
+        }
+
+        cart.setCartNum(targetNum);
         cart.setUpdateTime(new Date());
         fsStoreCartMapper.updateFsStoreCart(cart);
-        return R.ok();
+
+        return R.ok("购物车数量修改成功");
     }
 
     @Override
@@ -383,5 +420,27 @@ public class FsStoreCartScrmServiceImpl implements IFsStoreCartScrmService
         return goodsService;
     }
 
+    //校验购物车数量
+    public boolean checkCarNumber(Long productId,Integer num){
+        Integer availableStock = verifyCodeScrmMapper.selectCount(
+                new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
+                        .eq(FsStoreVerifyCodeScrm::getProductId, productId)
+                        .eq(FsStoreVerifyCodeScrm::getOutboundStatus, 0L)
+                        .eq(FsStoreVerifyCodeScrm::getIsDel, 0L)
+        );
+        if (num > availableStock) {
+            return true;
+        }
+        return false;
+    }
+
+    //校验商品类型
+    public boolean checkProductCater(Long productId){
+        FsStoreProductScrm product = fsStoreProductMapper.selectFsStoreProductById(productId);
+        if(product.getCateId().equals(202L) || product.getCateId().equals(232L) || product.getCateId().equals(201L) || product.getCateId().equals(233L)){
+            return false;
+        }
+        return true;
+    }
 
 }

+ 170 - 93
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -448,9 +448,11 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             log.error("修改商城订单地址推送到聚水潭ERP失败,orderId: {}", fsStoreOrder.getId(), e);
         }
 
+        FsStoreOrderScrm fsStoreOrderScrm=fsStoreOrderMapper.selectFsStoreOrderById(fsStoreOrder.getId());
+
         //判断发货类型
-        if(fsStoreOrder.getStatus() == 2 || fsStoreOrder.getStatus() == 3) {//待收货
-            List<FsStoreOrderItemVO> scrmList = fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(fsStoreOrder.getId());
+        if(fsStoreOrderScrm.getStatus() == 2 || fsStoreOrderScrm.getStatus() == 3) {//待收货
+            List<FsStoreOrderItemVO> scrmList = fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(fsStoreOrderScrm.getId());
             if (!scrmList.isEmpty()) {
                 List<Long> orderItemIds = scrmList.stream().map(FsStoreOrderItemVO::getItemId).collect(Collectors.toList());
                 //获取溯源码,进行回退
@@ -990,33 +992,35 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 }
                 fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
 
-                // ===================== 溯源码核心逻辑 ==================
-                Integer buyCount = vo.getCartNum();
-                Long productId = vo.getProductId();
-                String productName = vo.getProductName();
+                if(checkProductCater(vo.getProductId())){
+                    // ===================== 溯源码核心逻辑 ==================
+                    Integer buyCount = vo.getCartNum();
+                    Long productId = vo.getProductId();
+                    String productName = vo.getProductName();
 
-                if (buyCount <= 0) {
-                    throw new ServiceException("商品[" + productName + "]购买数量不能为0");
-                }
+                    if (buyCount <= 0) {
+                        throw new ServiceException("商品[" + productName + "]购买数量不能为0");
+                    }
 
-                //查询并锁定未出库溯源码带行锁
-                List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
-                if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
-                    String errorMsg = String.format("商品[%s]库存不足,需%s个,仅剩余%s个",
-                            productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
-                    throw new ServiceException(errorMsg);
-                }
+                    //查询并锁定未出库溯源码带行锁
+                    List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
+                    if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
+                        String errorMsg = String.format("商品[%s]库存不足,需%s个,仅剩余%s个",
+                                productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
+                        throw new ServiceException(errorMsg);
+                    }
 
-                for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
-                    code.setOutboundStatus(1L);
-                    code.setOrderId(storeOrder.getId());
-                    code.setOrderItemId(item.getItemId());
-                    code.setUpdateTime(new Date());
-                }
-                if (!availableVerifyCodes.isEmpty()) {
-                    verifyCodeService.updateBatchById(availableVerifyCodes);
+                    for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
+                        code.setOutboundStatus(1L);
+                        code.setOrderId(storeOrder.getId());
+                        code.setOrderItemId(item.getItemId());
+                        code.setUpdateTime(new Date());
+                    }
+                    if (!availableVerifyCodes.isEmpty()) {
+                        verifyCodeService.updateBatchById(availableVerifyCodes);
+                    }
+                    // ===================== 溯源码逻辑END =====================
                 }
-                // ===================== 溯源码逻辑END =====================
                 listOrderItem.add(item);
             }
             if (listOrderItem.size() > 0) {
@@ -1044,19 +1048,17 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if (config.getUnPayTime() != null && config.getUnPayTime() > 0) {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药72小时
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
                 }
+//                else {
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                }
             } else {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药
                     if(config == null){
                         config = new StoreConfig();
                     }
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
                 }
             }
             //添加支付到期时间
@@ -1185,33 +1187,36 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 item.setOrderId(order.getId());
                 fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
 
-                // ===================== 溯源码核心逻辑 ==================
-                Integer buyCount = item.getNum();
-                Long productId = item.getProductId();
-                String productName = productMap.get(productId) == null ? "商品" : productMap.get(productId);
+                if(checkProductCater(item.getProductId())){
+                    // ===================== 溯源码核心逻辑 ==================
+                    Integer buyCount = item.getNum();
+                    Long productId = item.getProductId();
+                    String productName = productMap.get(productId) == null ? "商品" : productMap.get(productId);
 
-                if (buyCount <= 0) {
-                    throw new ServiceException("商品[" + productName + "]购买数量不能为0");
-                }
+                    if (buyCount <= 0) {
+                        throw new ServiceException("商品[" + productName + "]购买数量不能为0");
+                    }
 
-                //查询并锁定未出库溯源码带行锁
-                List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
-                if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
-                    String errorMsg = String.format("商品[%s]库存不足",
-                            productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
-                    throw new ServiceException(errorMsg);
-                }
+                    //查询并锁定未出库溯源码带行锁
+                    List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
+                    if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
+                        String errorMsg = String.format("商品[%s]库存不足",
+                                productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
+                        throw new ServiceException(errorMsg);
+                    }
 
-                for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
-                    code.setOutboundStatus(1L);
-                    code.setOrderId(order.getId());
-                    code.setOrderItemId(item.getItemId());
-                    code.setUpdateTime(new Date());
-                }
-                if (!availableVerifyCodes.isEmpty()) {
-                    verifyCodeService.updateBatchById(availableVerifyCodes);
+                    for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
+                        code.setOutboundStatus(1L);
+                        code.setOrderId(order.getId());
+                        code.setOrderItemId(item.getItemId());
+                        code.setUpdateTime(new Date());
+                    }
+                    if (!availableVerifyCodes.isEmpty()) {
+                        verifyCodeService.updateBatchById(availableVerifyCodes);
+                    }
+                    // ===================== 溯源码逻辑END =====================
                 }
-                // ===================== 溯源码逻辑END =====================
+
             }
             fsStoreOrderLogsService.create(order.getId(), FsStoreOrderLogEnum.CREATE_ORDER.getValue(),
                     FsStoreOrderLogEnum.CREATE_ORDER.getDesc());
@@ -1776,20 +1781,21 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if (config.getUnPayTime() != null && config.getUnPayTime() > 0) {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药72小时
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
                 }
+//                else {
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                }
             } else {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药
                     if(config == null){
                         config = new StoreConfig();
                     }
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
                 }
+//                else {
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
+//                }
             }
             Calendar calendar = Calendar.getInstance();
             calendar.setTime(storeOrder.getCreateTime());
@@ -2946,9 +2952,27 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     private void refundStock(FsStoreOrderScrm order) {
         //获取订单下的商品
         List<FsStoreOrderItemVO> orderItemVOS = fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderId(order.getId());
+        List<Long> itemIds = new ArrayList<>();
         for (FsStoreOrderItemVO vo : orderItemVOS) {
-            productService.incProductStock(vo.getNum(), vo.getProductId()
-                    , vo.getProductAttrValueId());
+            if (checkProductCater(vo.getProductId())) {
+                itemIds.add(vo.getItemId());
+            }else {
+                productService.incProductStock(vo.getNum(), vo.getProductId()
+                        , vo.getProductAttrValueId());
+            }
+        }
+
+        if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(itemIds)) {
+            List<FsStoreVerifyCodeScrm> codes = verifyCodeScrmMapper.selectList(
+                    new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
+                            .eq(FsStoreVerifyCodeScrm::getOrderId, order.getId())
+                            .in(FsStoreVerifyCodeScrm::getOrderItemId, itemIds)
+                            .eq(FsStoreVerifyCodeScrm::getIsDel, "0")
+            );
+            if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(codes)) {
+                verifyCodeScrmMapper.updateOutboundStatus(codes);
+                log.info("订单{}共更新{}个核销码关联状态", order.getId(), codes.size());
+            }
         }
 
     }
@@ -4960,9 +4984,14 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             //检测库存
             //如果是美乳产品,发武汉仓库
             Integer meiruCount = 0;
-
+            Map<Long,Boolean> checkMap = new HashMap<>();
             for (FsStoreCartScrmQueryVO cart : carts) {
-                cartService.checkProductStocks(cart.getProductId(), cart.getProductAttrValueId(), cart.getCartNum());
+                if(checkProductCater(cart.getProductId())){
+                    checkMap.put(cart.getProductId(),true);
+                }else {
+                    checkMap.put(cart.getProductId(),false);
+                    cartService.checkProductStocks(cart.getProductId(), cart.getProductAttrValueId(), cart.getCartNum());
+                }
                 totalNum += cart.getCartNum();
                 integral = NumberUtil.add(integral,
                         NumberUtil.mul(cart.getCartNum(), cart.getIntegral()));
@@ -5125,33 +5154,35 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 }
                 fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
 
-                // ===================== 溯源码核心逻辑 ==================
-                Integer buyCount = vo.getCartNum();
-                Long productId = vo.getProductId();
-                String productName = vo.getProductName();
+                if(checkMap.get(vo.getProductId())){
+                    // ===================== 溯源码核心逻辑 ==================
+                    Integer buyCount = vo.getCartNum();
+                    Long productId = vo.getProductId();
+                    String productName = vo.getProductName();
 
-                if (buyCount <= 0) {
-                    throw new ServiceException("商品[" + productName + "]购买数量不能为0");
-                }
+                    if (buyCount <= 0) {
+                        throw new ServiceException("商品[" + productName + "]购买数量不能为0");
+                    }
 
-                //查询并锁定未出库溯源码带行锁
-                List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
-                if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
-                    String errorMsg = String.format("商品[%s]库存不足",
-                            productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
-                    throw new ServiceException(errorMsg);
-                }
+                    //查询并锁定未出库溯源码带行锁
+                    List<FsStoreVerifyCodeScrm> availableVerifyCodes = verifyCodeMapper.selectUnOutboundVerifyCodesWithLock(productId, buyCount);
+                    if (availableVerifyCodes == null || availableVerifyCodes.size() < buyCount) {
+                        String errorMsg = String.format("商品[%s]库存不足",
+                                productName, buyCount, (availableVerifyCodes == null ? 0 : availableVerifyCodes.size()));
+                        throw new ServiceException(errorMsg);
+                    }
 
-                for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
-                    code.setOutboundStatus(1L);
-                    code.setOrderId(storeOrder.getId());
-                    code.setOrderItemId(item.getItemId());
-                    code.setUpdateTime(new Date());
-                }
-                if (!availableVerifyCodes.isEmpty()) {
-                    verifyCodeService.updateBatchById(availableVerifyCodes);
+                    for (FsStoreVerifyCodeScrm code : availableVerifyCodes) {
+                        code.setOutboundStatus(1L);
+                        code.setOrderId(storeOrder.getId());
+                        code.setOrderItemId(item.getItemId());
+                        code.setUpdateTime(new Date());
+                    }
+                    if (!availableVerifyCodes.isEmpty()) {
+                        verifyCodeService.updateBatchById(availableVerifyCodes);
+                    }
+                    // ===================== 溯源码逻辑END =====================
                 }
-                // ===================== 溯源码逻辑END =====================
                 listOrderItem.add(item);
             }
             if (listOrderItem.size() > 0) {
@@ -5179,20 +5210,22 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             if (config.getUnPayTime() != null && config.getUnPayTime() > 0) {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药72小时
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);//
                 }
+//                else {
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(), config.getUnPayTime(), TimeUnit.MINUTES);
+//                }
             } else {
                 if(storeOrder.getIsPrescribe() != null && storeOrder.getIsPrescribe() == 1){//处方药
                     if(config == null){
                         config = new com.fs.store.config.StoreConfig();
                     }
                     config.setUnPayTime(4320);
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
-                }else {
-                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(),4320, TimeUnit.MINUTES);
                 }
+//                else {
+//                    redisCache.setCacheObject(redisKey, storeOrder.getId(), 30, TimeUnit.MINUTES);
+//                }
             }
             //添加支付到期时间
             Calendar calendar = Calendar.getInstance();
@@ -5858,4 +5891,48 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             return false;
         }
     }
+
+    @Override
+    public void cancelOrderReuse(FsStoreOrderScrm order) {
+        if (order.getStatus() == OrderInfoEnum.STATUS_0.getValue()) {
+            if (!StringUtils.isEmpty(order.getExtendOrderId())) {
+                redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
+            }
+            //退回积分
+            this.refundIntegral(order);
+            //退回优惠券
+            this.refundCoupon(order);
+            //退回库存
+            this.refundStock(order);
+            fsStoreOrderMapper.cancelOrder(order.getId());
+            //添加记录
+            orderStatusService.create(order.getId(), OrderLogEnum.CANCEL_ORDER.getValue(),
+                    OrderLogEnum.CANCEL_ORDER.getDesc());
+//            if(order.getPaid()==1){
+//                //更新OMS
+//                ErpRefundUpdateRequest request=new ErpRefundUpdateRequest();
+//                request.setTid(order.getOrderCode());
+//                request.setOid(order.getOrderCode());
+//                request.setRefund_state(1);
+//                erpOrderService.refundUpdate(request);
+//            }
+            TemplateBean templateBean = TemplateBean.builder()
+                    .orderId(order.getId().toString())
+                    .orderCode(order.getOrderCode().toString())
+                    .remark("您的订单已取消")
+                    .userId(order.getUserId())
+                    .templateType(TemplateListenEnum.TYPE_1.getValue())
+                    .build();
+            publisher.publishEvent(new TemplateEvent(this, templateBean));
+        }
+    }
+
+    //校验商品类型
+    public boolean checkProductCater(Long productId){
+        FsStoreProductScrm product = fsStoreProductMapper.selectFsStoreProductById(productId);
+        if(product.getCateId().equals(202L) || product.getCateId().equals(232L) || product.getCateId().equals(201L) || product.getCateId().equals(233L)){
+            return false;
+        }
+        return true;
+    }
 }

+ 4 - 3
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java

@@ -1414,9 +1414,10 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
      * @param storeId 店铺Id
      * @param cateId 分类id
      * @param medicalDeviceCode 器械编码
+     * @param productType 商品分类
      */
     @Override
-    public ContainsResult checkStoreDrugLicense(Long storeId, Long cateId, String medicalDeviceCode) {
+    public ContainsResult checkStoreDrugLicense(Long storeId, Long cateId, String medicalDeviceCode, String productType) {
         //先通过分类id获取具体的分类名称
         FsStoreProductCategoryScrm fsStoreProductCategoryScrm = fsStoreProductCategoryService.selectFsStoreProductCategoryById(cateId);
         String cateName = fsStoreProductCategoryScrm.getCateName();//分类名称
@@ -1425,10 +1426,10 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
         //新增分类校验就去 categoryVal 包下面去新加
         try{
             AbstractHandler invokeStrategy = ProductCategoryCheckFactory.getInvokeStrategy(String.valueOf(cateId));
-            return invokeStrategy.check(cateName, storeId, medicalDeviceCode);
+            return invokeStrategy.check(cateName, storeId, medicalDeviceCode, productType);
         }catch (NullPointerException e){
             AbstractHandler invokeStrategy = ProductCategoryCheckFactory.getInvokeStrategy(String.valueOf("1101165230"));
-            return invokeStrategy.check(cateName, storeId, medicalDeviceCode);
+            return invokeStrategy.check(cateName, storeId, medicalDeviceCode, productType);
         }
     }
 

+ 3 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreScrmServiceImpl.java

@@ -242,7 +242,9 @@ public class FsStoreScrmServiceImpl implements IFsStoreScrmService {
         fsStore.setQualificationUpdateTime(LocalDate.now());
         int updateRowNum = fsStoreMapper.updateFsStore(fsStore);
         //信息发布
-        applicationEventPublisher.publishEvent(fsStore);
+        if(updateRowNum > 0){
+            applicationEventPublisher.publishEvent(fsStore);
+        }
         return updateRowNum;
     }
 

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreAfterSalesVO.java

@@ -117,4 +117,7 @@ public class FsStoreAfterSalesVO implements Serializable
      * 处方编号
      * **/
     private String serialNo;
+
+    //溯源码
+    private String verifyCodes;
 }

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreDetailsScrmVo.java

@@ -294,5 +294,9 @@ public class FsStoreDetailsScrmVo extends BaseEntity
      **/
     private String medicalDevice3BusinessScope;
 
+    /**
+     * 药店经营范围
+     **/
+    private String drugLicenseBusinessScope;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java

@@ -274,4 +274,6 @@ public class FsStoreOrderVO implements Serializable
      * **/
     private String serialNo;
 
+    //溯源码
+    private String verifyCodes;
 }

+ 1 - 1
fs-service/src/main/java/com/fs/hospital580/util/ThumbnailatorWatermark.java

@@ -34,7 +34,7 @@ public class ThumbnailatorWatermark {
 
     public String addWatermarkToNetworkImage(Long preId, Integer orderStatus, String signUrl) {
         try {
-            log.error("添加水印处方水印:{} {} {}0", preId, orderStatus, signUrl);
+            log.info("添加水印处方水印:{} {} {}0", preId, orderStatus, signUrl);
             // 处方原图
             String imageUrl = redisCache.getCacheObject("prescription:dstFilePath:" + preId);
             if (ObjectUtil.isEmpty(imageUrl)) {

+ 8 - 1
fs-service/src/main/java/com/fs/system/service/impl/SysDeptServiceImpl.java

@@ -27,6 +27,7 @@ import com.fs.common.utils.spring.SpringUtils;
 import com.fs.system.mapper.SysDeptMapper;
 import com.fs.system.mapper.SysRoleMapper;
 import com.fs.system.service.ISysDeptService;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 部门管理 服务实现
@@ -198,6 +199,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
      * @return 结果
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int insertDept(SysDept dept) {
         SysDept info = deptMapper.selectDeptById(dept.getParentId());
         // 如果父节点不为正常状态,则不允许新增子节点
@@ -205,7 +207,12 @@ public class SysDeptServiceImpl implements ISysDeptService {
             throw new ServiceException("部门停用,不允许新增");
         }
         dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
-        return deptMapper.insertDept(dept);
+        if(deptMapper.insertDept(dept) > 0){
+            SysDeptConfig config =new SysDeptConfig();
+            config.setDeptId(dept.getDeptId());
+            sysDeptConfigMapper.insertSysDeptConfig(config);
+        }
+        return 1;
     }
 
     /**

+ 25 - 2
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -1579,15 +1579,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select DISTINCT o.*,u.phone,u.register_code,u.register_date,u.source, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber
         , csc.name miniProgramName,ssc.store_name,
         ssc.store_seq,
-        ssc.merchant_id,hps.serial_no
+        ssc.merchant_id,hps.serial_no,vc.verify_code AS verifyCodes
         from fs_store_order_scrm o
         left join fs_store_hospital580_prescription_scrm hps on hps.store_order_id = o.id
         left join fs_user u on o.user_id=u.user_id
         left join company c on c.company_id=o.company_id
         left join company_user cu on cu.user_id=o.company_user_id
+        LEFT JOIN fs_store_verify_code_scrm vc ON o.id = vc.order_id
         <if test="maps.erpAccount != null and maps.erpAccount != ''">
             LEFT JOIN fs_store_order_df df on df.order_id=o.id
-
         </if>
 
         left join fs_store_order_item_scrm oi on o.id = oi.order_id
@@ -1686,6 +1686,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.productName != null and  maps.productName !=  '' ">
                 and fsp.product_name like concat('%', #{maps.productName}, '%')
             </if>
+            <if test="maps.verifyCodes != null and  maps.verifyCodes !=  '' ">
+                and vc.verify_code like concat('%', #{maps.verifyCodes}, '%')
+            </if>
             <if test="maps.orderType != null    ">
                 and o.order_type =#{maps.orderType}
             </if>
@@ -2133,4 +2136,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
 
     </select>
+
+    <!-- 根据条件查询超时未支付订单 -->
+    <select id="selectTimeoutUnpaidOrders"
+            parameterType="java.util.Map"
+            resultType="com.fs.hisStore.domain.FsStoreOrderScrm">
+        SELECT
+        *
+        FROM
+        fs_store_order_scrm
+        WHERE
+        status = 0
+        AND create_time IS NOT NULL
+        AND is_prescribe IS NOT NULL
+        AND create_time &lt; DATE_SUB(#{now}, INTERVAL
+        CASE
+        WHEN is_prescribe = 1 THEN #{prescribeTimeoutMinutes}
+        ELSE #{unPayTime}
+        END
+        MINUTE)
+    </select>
 </mapper>

+ 38 - 25
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -579,7 +579,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             WHERE
             fsp.is_del = 0
             AND fsp.is_show = 1
-            AND fsp.is_good = 1
             AND fsp.is_best = 1
             AND fsp.is_display = 1
             <if test='config.isAudit == "1" and (isDrug == null or isDrug != null and isDrug == 1)'>
@@ -723,10 +722,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE business_end IS NOT NULL
           AND business_end &lt;= DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
           AND is_business_permanent != 1
+        and is_show = 1 and is_audit = 1 and is_drug = 1
         <if test="storeId != null">AND store_id = #{storeId}</if>
-
         UNION ALL
-
         SELECT
             CONCAT(
                     product_name,
@@ -741,10 +739,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE license_end IS NOT NULL
           AND license_end &lt;= DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
           AND is_license_permanent != 1
+        and is_show = 1 and is_audit = 1 and is_drug = 1
         <if test="storeId != null">AND store_id = #{storeId}</if>
-
         UNION ALL
-
         SELECT
             CONCAT(
                     product_name,
@@ -759,23 +756,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE certificate_end IS NOT NULL
           AND certificate_end &lt;= DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
           AND is_certificate_permanent != 1
-        <if test="storeId != null">AND store_id = #{storeId}</if>
-
-        UNION ALL
-        SELECT
-            CONCAT(
-                    product_name,
-                    '商品的',
-                    'GMP/GSP认证证书有效期',
-                    CASE
-                        WHEN gmp_auth_end &lt; CURDATE() THEN '已过期'
-                        ELSE '即将1个月内过期'
-                        END
-                ) AS status_text
-        FROM fs_store_product_scrm
-        WHERE  gmp_auth_end IS NOT NULL
-          AND gmp_auth_end &lt;= DATE_ADD(CURDATE(), INTERVAL 1 MONTH)
-          AND is_gmp_auth_permanent != 1
+            and is_show = 1 and is_audit = 1 and is_drug = 1
         <if test="storeId != null">AND store_id = #{storeId}</if>
     </select>
     <select id="getDrugExportList" resultType="com.fs.hisStore.vo.FsDrugExportVO">
@@ -872,7 +853,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <sql id="baseSql">
        DISTINCT p.product_id, p.image,p.video, p.slider_image, p.product_name, p.product_info, p.keyword, p.bar_code,
-       p.cate_id, p.price, p.vip_price, p.ot_price, p.postage, p.unit_name, p.sort, ( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 0 AND is_del = 0) AS stock,( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 1 AND is_del = 0) AS sales,
+       p.cate_id, p.price, p.vip_price, p.ot_price, p.postage, p.unit_name, p.sort, CASE
+	WHEN p.cate_id = '202' OR p.cate_id = '232' OR p.cate_id = '201' OR P.cate_id = '233' THEN
+		p.stock
+	ELSE
+		( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 0 AND is_del = 0)
+       END AS stock,
+ CASE
+	WHEN p.cate_id = '202' OR p.cate_id = '232' OR p.cate_id = '201' OR P.cate_id = '233' THEN
+		p.sales
+	ELSE
+		( SELECT COUNT(*) FROM fs_store_verify_code_scrm vc WHERE vc.product_id = p.product_id AND vc.outbound_status = 1 AND is_del = 0)
+       END AS sales,
        p.is_hot, p.is_benefit, p.is_best, p.is_new, p.description, p.create_time, p.update_time, p.is_postage,
        p.is_del, p.give_integral, p.cost, p.is_good, p.browse, p.code_path, p.temp_id, p.spec_type, p.is_integral,
        p.integral, p.product_type, p.prescribe_code, p.prescribe_spec, p.prescribe_factory, p.prescribe_name,
@@ -921,7 +913,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 INNER JOIN fs_user_complaint uc ON FIND_IN_SET(p.product_id, uc.product_ids)
             </if>
             WHERE 1=1
-            and p.is_del = 0
+            and p.is_del = 0 and p.is_drug = 1
             <if test="maps.isAudit == null and maps.isShow != null">
                 <if test="maps.isShow == 1">
                     AND p.is_audit = 1
@@ -1026,5 +1018,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             ORDER BY
             p.product_id DESC
     </select>
-
+    <update id="updateBatchById">
+        UPDATE fs_store_product_scrm
+        <set>
+            sales = CASE
+            <foreach collection="updateProducts" item="item" separator="">
+                WHEN product_id = #{item.productId} THEN #{item.sales}
+            </foreach>
+            ELSE sales
+            END,
+            stock = CASE
+            <foreach collection="updateProducts" item="item" separator="">
+                WHEN product_id = #{item.productId} THEN #{item.stock}
+            </foreach>
+            ELSE stock
+            END,
+            update_time = NOW()
+        </set>
+        WHERE product_id IN
+        <foreach collection="updateProducts" item="item" open="(" separator="," close=")">
+            #{item.productId}
+        </foreach>
+    </update>
 </mapper>

+ 5 - 23
fs-service/src/main/resources/mapper/hisStore/FsStoreScrmMapper.xml

@@ -88,6 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="otherSpecialQualificationFileName" column="other_special_qualification_fileName" />
         <result property="medicalDevice2BusinessScope" column="medical_device2_business_scope" />
         <result property="medicalDevice3BusinessScope" column="medical_device3_business_scope" />
+        <result property="drugLicenseBusinessScope" column="drug_license_business_scope" />
     </resultMap>
 
     <sql id="selectFsStoreVo">
@@ -106,7 +107,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                quality_assurance_agreement_code,settlement_agreement_code,is_medical_device1_expiry_permanent,
                is_drug_license_permanent,is_medical_device2_expiry_permanent,is_medical_device3_expiry_permanent,is_food_license_expiry_permanent,is_medical_license_expiry_permanent,
                title_Name_one,title_Name_two,title_Name_three,settlement_agreement_file_name,quality_assurance_agreement_fileName,other_special_qualification_fileName,
-               is_effective_permanent1,is_effective_permanent2,is_effective_permanent3,medical_device2_business_scope,medical_device3_business_scope
+               is_effective_permanent1,is_effective_permanent2,is_effective_permanent3,medical_device2_business_scope,medical_device3_business_scope,drug_license_business_scope
         from fs_store_scrm
     </sql>
 
@@ -228,6 +229,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="otherSpecialQualificationFileName !=null ">other_special_qualification_fileName , </if>
             <if test="medicalDevice2BusinessScope !=null ">medical_device2_business_scope,</if>
             <if test="medicalDevice3BusinessScope !=null ">medical_device3_business_scope,</if>
+            <if test="drugLicenseBusinessScope !=null ">drug_license_business_scope, </if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="cityIds != null">#{cityIds},</if>
@@ -324,6 +326,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="otherSpecialQualificationFileName !=null ">#{otherSpecialQualificationFileName} , </if>
             <if test="medicalDevice2BusinessScope !=null ">#{medicalDevice2BusinessScope},</if>
             <if test="medicalDevice3BusinessScope !=null ">#{medicalDevice3BusinessScope},</if>
+            <if test="drugLicenseBusinessScope !=null ">#{drugLicenseBusinessScope}, </if>
         </trim>
     </insert>
 
@@ -422,6 +425,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="otherSpecialQualificationFileName !=null ">other_special_qualification_fileName = #{otherSpecialQualificationFileName} , </if>
             <if test="medicalDevice2BusinessScope !=null ">medical_device2_business_scope = #{medicalDevice2BusinessScope} , </if>
             <if test="medicalDevice3BusinessScope !=null ">medical_device3_business_scope = #{medicalDevice3BusinessScope} , </if>
+            <if test="drugLicenseBusinessScope !=null ">drug_license_business_scope = #{drugLicenseBusinessScope} , </if>
         </trim>
         where store_id = #{storeId}
     </update>
@@ -625,23 +629,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             THEN '药品经营许可证3个月内过期,请注意更新;'
                         ELSE ''
                         END,
-                -- 一类器械生产备案
-                    CASE
-                        WHEN medical_device1 IS NOT NULL
-                            AND medical_device1_expiry_end IS NOT NULL
-                            AND medical_device1_expiry_end &lt; CURDATE()
-                            AND is_medical_device1_expiry_permanent != 1
-            THEN '一类器械生产备案已过期,需要商家更新;'
-                        ELSE ''
-                        END,
-                    CASE
-                        WHEN medical_device1 IS NOT NULL
-                            AND medical_device1_expiry_end IS NOT NULL
-                            AND medical_device1_expiry_end BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 MONTH)
-                            AND is_medical_device1_expiry_permanent != 1
-            THEN '一类器械生产备案3个月内过期,请注意更新;'
-                        ELSE ''
-                        END,
                 -- 二类医疗器械备案
                     CASE
                         WHEN medical_device2 IS NOT NULL
@@ -724,11 +711,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 AND drug_license_expiry_end IS NOT NULL
                 AND (drug_license_expiry_end &lt; CURDATE() OR drug_license_expiry_end BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 MONTH))
                 AND is_drug_license_permanent != 1)
-                -- 一类器械生产备案
-                OR (medical_device1 IS NOT NULL
-                AND medical_device1_expiry_end IS NOT NULL
-                AND (medical_device1_expiry_end &lt; CURDATE() OR medical_device1_expiry_end BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 3 MONTH))
-                AND is_medical_device1_expiry_permanent != 1)
                 -- 二类医疗器械备案
                 OR (medical_device2 IS NOT NULL
                 AND medical_device2_expiry_end IS NOT NULL

+ 14 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreVerifyCodeScrmMapper.xml

@@ -89,6 +89,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="storeId != null">store_id = #{storeId} ,</if>
             <if test="isRecycle != null">is_recycle = #{isRecycle} ,
             </if>
+            <if test="carId != null">car_id = #{carId} ,
+            </if>
             </trim>
         where id = #{id}
     </update>
@@ -134,4 +136,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             )
         </foreach>
     </insert>
+
+    <update id="updateOutboundStatus">
+        <foreach collection="list" item="item" separator=";">
+            UPDATE fs_store_verify_code_scrm
+            SET verify_status = 0,
+            outbound_status = 0,
+            order_id = null,
+            order_item_id = null,
+            update_time = NOW()
+            WHERE id = #{item.id}
+        </foreach>
+    </update>
 </mapper>

+ 1 - 1
fs-service/src/main/resources/mapper/system/SysDeptMapper.xml

@@ -85,7 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		where dept_name=#{deptName} and parent_id = #{parentId} limit 1
 	</select>
     
-    <insert id="insertDept" parameterType="SysDept">
+    <insert id="insertDept" parameterType="SysDept" useGeneratedKeys="true" keyProperty="deptId">
  		insert into sys_dept(
  			<if test="deptId != null and deptId != 0">dept_id,</if>
  			<if test="parentId != null and parentId != 0">parent_id,</if>

+ 30 - 0
fs-store/src/main/java/com/fs/hisStore/controller/store/FsStoreOrderScrmController.java

@@ -2,6 +2,8 @@ package com.fs.hisStore.controller.store;
 
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
@@ -33,6 +35,7 @@ import com.fs.his.vo.FsStoreOrderExcelVO;
 import com.fs.his.vo.FsStoreOrderStoreExcelVO;
 import com.fs.hisStore.domain.*;
 import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
 import com.fs.hisStore.param.FsStoreOrderExpressEditParam;
 import com.fs.hisStore.param.FsStoreOrderParam;
 import com.fs.hisStore.service.*;
@@ -48,7 +51,9 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 订单Controller
@@ -109,6 +114,9 @@ public class FsStoreOrderScrmController extends BaseController
     @Autowired
     private IFsStoreOrderAuditLogScrmService orderAuditLogService;
 
+    @Autowired
+    private FsStoreVerifyCodeScrmMapper fsStoreVerifyCodeService;
+
     /**
      * 查询订单列表
      */
@@ -220,6 +228,28 @@ public class FsStoreOrderScrmController extends BaseController
             tuiMoneyLogs=moneyLogsService.selectCompanyStoreOrderMoneyLogsList(moneyLogsMap);
         }
 
+        //获取溯源码相关数据
+        List<FsStoreVerifyCodeScrm> verifyCodes = fsStoreVerifyCodeService.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().select(FsStoreVerifyCodeScrm::getVerifyCode,FsStoreVerifyCodeScrm::getProductId).eq(FsStoreVerifyCodeScrm::getOrderId, order.getId()));
+        if(!verifyCodes.isEmpty()){
+            Map<Long, String> verifyCodMap=new HashMap<>();
+            for (FsStoreVerifyCodeScrm v : verifyCodes){
+                if(verifyCodMap.containsKey(v.getProductId())){
+                    verifyCodMap.put(v.getProductId(),verifyCodMap.get(v.getProductId())+","+v.getVerifyCode());
+                }else {
+                    verifyCodMap.put(v.getProductId(),v.getVerifyCode());
+                }
+            }
+
+            for (FsStoreOrderItemScrm item : items){
+                if(verifyCodMap.containsKey(item.getProductId())){
+                    JSONObject jsonObject = JSONObject.parseObject(item.getJsonInfo());
+                    jsonObject.put("verifyCods", verifyCodMap.get(item.getProductId()));
+                    item.setJsonInfo(jsonObject.toJSONString());
+                }
+            }
+
+        }
+
         List<FsStoreOrderAuditLogVO> auditLogs = orderAuditLogService.selectStoreOrderAuditLogVOByOrderId(order.getId());
         return R.ok().put("order", order).put("items", items).put("logs", logs).put("user", user).put("payments",payments).put("tuiMoneyLogs",tuiMoneyLogs)
                 .put("auditLogs",auditLogs);

+ 4 - 1
fs-store/src/main/java/com/fs/hisStore/controller/store/FsStoreProductScrmController.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.controller.store;
 
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -84,7 +85,9 @@ public class FsStoreProductScrmController extends BaseController
         StoreLoginUserScrm loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         fsStoreProduct.setStoreId(loginUser.getFsStore().getStoreId());
         return R.ok().put("data", fsStoreProductService.checkStoreDrugLicense(fsStoreProduct.getStoreId(), fsStoreProduct.getCateId(),
-                org.apache.commons.lang3.StringUtils.isEmpty(fsStoreProduct.getMedicalDeviceCode())?null:fsStoreProduct.getMedicalDeviceCode()));
+                org.apache.commons.lang3.StringUtils.isEmpty(fsStoreProduct.getMedicalDeviceCode())?null:fsStoreProduct.getMedicalDeviceCode(),
+                ObjectUtils.isNotNull(fsStoreProduct.getProductType())?fsStoreProduct.getProductType().toString():null)
+        );
     }
 
 

+ 14 - 0
fs-user-app/pom.xml

@@ -103,11 +103,25 @@
             <groupId>com.fs</groupId>
             <artifactId>fs-service</artifactId>
         </dependency>
+
         <dependency>
             <groupId>org.apache.rocketmq</groupId>
             <artifactId>rocketmq-spring-boot-starter</artifactId>
             <version>2.2.3</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>3.16.8</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.data</groupId>
+                    <artifactId>spring-data-redis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 7 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/ProductScrmController.java

@@ -154,8 +154,13 @@ public class ProductScrmController extends AppBaseController {
         List<FsStoreProductAttrScrm> productAttr=attrService.selectFsStoreProductAttrByProductId(product.getProductId());
         List<FsStoreProductAttrValueScrm> productValues=attrValueService.selectFsStoreProductAttrValueByProductId(product.getProductId());
 
-        //获取商品溯源码库存
-        int number = verifyCodeScrmMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getProductId,product.getProductId()).eq(FsStoreVerifyCodeScrm::getOutboundStatus,0L).eq(FsStoreVerifyCodeScrm::getIsDel,0L));
+        //根据商品类型区分显示库存
+        int number;
+        if(product.getCateId().equals(202L) || product.getCateId().equals(232L) || product.getCateId().equals(201L) || product.getCateId().equals(233L)){
+        number = product.getStock().intValue();
+        }else {
+           number = verifyCodeScrmMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getProductId,product.getProductId()).eq(FsStoreVerifyCodeScrm::getOutboundStatus,0L).eq(FsStoreVerifyCodeScrm::getIsDel,0L));
+        }
 
 
 //        for(FsStoreProductAttrValue value:productValues){

+ 18 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java

@@ -31,6 +31,7 @@ import com.fs.hisStore.domain.*;
 import com.fs.hisStore.dto.FsStoreOrderComputeDTO;
 import com.fs.hisStore.enums.OrderInfoEnum;
 import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.*;
 import com.fs.hisStore.vo.FsHuiFuPayInfo;
@@ -146,6 +147,9 @@ public class StoreOrderScrmController extends AppBaseController {
     @Autowired
     private IFsStoreScrmService storeScrmService;
 
+    @Autowired
+    private FsStoreVerifyCodeScrmMapper verifyCodeScrmMapper;
+
     //TODO 应该没用到
     private IErpOrderService getErpService(){
         //判断是否开启erp
@@ -205,8 +209,11 @@ public class StoreOrderScrmController extends AppBaseController {
         List<FsStoreOrderItemVO> list=itemService.selectFsStoreOrderItemListByOrderId(orderId);
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(order.getCreateTime());
-        String json=configService.selectConfigByKey("his.store");
+        String json=configService.selectConfigByKey("store.config");
         StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
+        if(order.getIsPrescribe() != null && order.getIsPrescribe() == 1){
+            config.setUnPayTime(4320);
+        }
         calendar.add(Calendar.MINUTE,config.getUnPayTime());
         SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String payLimitTime = format.format(calendar.getTime() );
@@ -256,6 +263,12 @@ public class StoreOrderScrmController extends AppBaseController {
                 storeName=storeScrm.getStoreName();
             }
         }
+
+        //获取订单下的溯源码
+        List<FsStoreVerifyCodeScrm> verifyCodes = verifyCodeScrmMapper.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().select(FsStoreVerifyCodeScrm::getVerifyCode).eq(FsStoreVerifyCodeScrm::getOrderId, orderId).eq(FsStoreVerifyCodeScrm::getOutboundStatus,1L).eq(FsStoreVerifyCodeScrm::getIsDel,0L));
+        if(!verifyCodes.isEmpty()){
+            order.setVerifyCodes(verifyCodes.stream().map(FsStoreVerifyCodeScrm::getVerifyCode).collect(Collectors.joining()));
+        }
         return R.ok().put("isAfterSales",isAfterSales).put("order",order).put("items",list).put("payLimitTime",payLimitTime).put("prescribe",prescribe).put("prescriptionAuditStatus",prescriptionAuditStatus)
                 .put("storeName",storeName);
     }
@@ -269,10 +282,13 @@ public class StoreOrderScrmController extends AppBaseController {
         order.setUserPhone(ParseUtils.parsePhone(order.getUserPhone()));
         order.setUserAddress(ParseUtils.parseIdCard(order.getUserAddress()));
 
-        String json=configService.selectConfigByKey("his.store");
+        String json=configService.selectConfigByKey("store.config");
         StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(order.getCreateTime());
+       if(order.getIsPrescribe() != null && order.getIsPrescribe() == 1){
+           config.setUnPayTime(4320);
+       }
         calendar.add(Calendar.MINUTE,config.getUnPayTime());
         SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String payLimitTime = format.format(calendar.getTime() );

+ 124 - 0
fs-user-app/src/main/java/com/fs/app/redis/OrderExpireHandler.java

@@ -0,0 +1,124 @@
+package com.fs.app.redis;
+
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.fs.hisStore.domain.FsStoreOrderScrm;
+import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
+import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
+import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
+import com.fs.hisStore.service.IFsStoreOrderScrmService;
+import com.fs.hisStore.service.IFsStoreVerifyCodeScrmService;
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
+import com.fs.hisStore.vo.FsStoreOrderItemVO;
+import com.fs.system.service.ISysConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.checker.units.qual.A;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @description: 订单过期处理
+ * @author: Guos
+ * @time: 2025/12/4 上午10:23
+ */
+@Slf4j
+@Component
+public class OrderExpireHandler {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private FsStoreOrderScrmMapper orderScrmMapper;
+
+    // 处方药固定超时时间:4320分钟三天过期
+    private static final int PRESCRIBE_TIMEOUT_MINUTES = 4320;
+    @Autowired
+    private ISysConfigService configService;
+
+    private static final String LOCK_KEY_PREFIX = "order-expire-product-lock:";
+
+    private static final int LOCK_WAIT_TIME = 3; // 锁等待时间
+    private static final int LOCK_LEASE_TIME = 30; // 锁持有时间
+
+    @Autowired
+    private IFsStoreOrderScrmService fsStoreOrderService;
+
+
+    @Scheduled(fixedDelay = 60_000) // 每分钟跑一次
+    public void handleUnpaidOrders() {
+        // 全局锁:防止多实例同时执行任务(粒度粗,仅控制任务入口)
+        RLock globalLock = redissonClient.getLock("order-expire-handler-global-lock");
+        try {
+            if (globalLock.tryLock(LOCK_WAIT_TIME, LOCK_LEASE_TIME, TimeUnit.SECONDS)) {
+                LocalDateTime now = LocalDateTime.now();
+                log.info("开始处理超时未支付订单,当前时间:{}", now);
+
+                // 获取配置时间
+                String json = configService.selectConfigByKey("store.config");
+                com.fs.store.config.StoreConfig config = JSONUtil.toBean(json, com.fs.store.config.StoreConfig.class);
+                if (config == null || config.getUnPayTime() == null) {
+                    log.error("未获取到门店配置,unPayTime为空");
+                    return;
+                }
+
+                // 查询所有待处理订单
+                Map<String, Object> params = new HashMap<>(3);
+                params.put("now", now);
+                params.put("prescribeTimeoutMinutes", PRESCRIBE_TIMEOUT_MINUTES);
+                params.put("unPayTime", config.getUnPayTime());
+                List<FsStoreOrderScrm> orders = orderScrmMapper.selectTimeoutUnpaidOrders(params);
+
+                if (CollectionUtils.isEmpty(orders)) {
+                    log.info("暂无超时未支付订单需要处理");
+                    return;
+                }
+                log.info("共查询到{}个超时未支付订单,开始逐个处理", orders.size());
+
+                for (FsStoreOrderScrm order : orders) {
+                    try {
+                        processExpiredOrder(order);
+                        log.info("订单{}处理完成,状态已更新为-3", order.getId());
+                    } catch (Exception e) {
+                        log.error("处理订单{}失败", order.getId(), e);
+                        // 记录失败订单,可后续补偿
+                        // failOrderService.recordFailOrder(order.getId(), "库存恢复失败:" + e.getMessage());
+                    }
+                }
+            } else {
+                log.warn("获取全局分布式锁失败,跳过本次订单处理");
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            log.error("获取全局锁时线程中断", e);
+        } finally {
+            if (globalLock.isHeldByCurrentThread()) {
+                globalLock.unlock();
+            }
+        }
+    }
+    @Transactional(rollbackFor = Exception.class)
+    void processExpiredOrder(FsStoreOrderScrm order) {
+        Long orderId = order.getId();
+        if (orderId == null) {
+            log.warn("订单ID为空,跳过处理");
+            return;
+        }
+        fsStoreOrderService.cancelOrderReuse(order);
+    }
+
+}

+ 49 - 47
fs-user-app/src/main/java/com/fs/app/redis/RedisKeyExpirationListener.java

@@ -109,53 +109,55 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
 //            }
 //
 //        }else
-        if (key.contains(FsConstants.REDIS_ORDER_UNPAY)) {//未支付支付订单过期
-            log.info("监听商城过期appKey-redis过期:pattern={},channel={},key={}", new String(pattern), channel, key);
-            String lockKey = "lockStoreAppKey:" + key;  // 分布式锁的 key
-            Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
-            if (Boolean.TRUE.equals(lockAcquired)) {  // 只有一个实例会成功获取锁
-                try {
-                    String[] parts = key.split(":");
-                    if (parts.length == 3) {
-                        Long orderId = Long.parseLong(parts[parts.length - 1].trim());
-                        if (orderId != null) {
-                            //获取订单信息
-                            FsStoreOrderScrm orderScrm = orderScrmMapper.selectFsStoreOrderById(orderId);
-                            if (orderScrm != null && orderScrm.getStatus() == 0) {
-                                //获取订单下的详情信息
-                                List<FsStoreOrderItemVO> scrmList = orderItemScrmMapper.selectMyFsStoreOrderItemListByOrderId(orderId);
-                                if (!scrmList.isEmpty()) {
-                                    List<Long> orderItemIds = scrmList.stream().map(FsStoreOrderItemVO::getItemId).collect(Collectors.toList());
-                                    //获取溯源码,进行回退
-                                    List<FsStoreVerifyCodeScrm> verifyCodes = verifyCodeScrmMapper.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getOrderId, orderId).in(FsStoreVerifyCodeScrm::getOrderItemId, orderItemIds).eq(FsStoreVerifyCodeScrm::getIsDel, "0"));
-                                    if(!verifyCodes.isEmpty()){
-                                        verifyCodes.forEach(v->{
-                                            v.setVerifyStatus(0L);
-                                            v.setOutboundStatus(0L);
-                                        });
-                                        //批量更新数据
-                                        verifyCodeScrmService.updateBatchById(verifyCodes);
-                                    }
-                                }
-                                //更新订单状态
-                                FsStoreOrderScrm updateOrder = new FsStoreOrderScrm();
-                                updateOrder.setId(orderId);
-                                updateOrder.setStatus(-3);
-                                orderScrmMapper.updateFsStoreOrder(updateOrder);
-                            }
-                        }
-                    } else {
-                        System.out.println("监听appKey失效!");
-                    }
-                } finally {
-                    // 释放锁,避免影响后续任务
-                    redisTemplate.delete(lockKey);
-                }
-            } else {
-                log.info("另一个实例已经处理了 key={},当前实例跳过", key);
-            }
-
-        }
+//        if (key.contains(FsConstants.REDIS_ORDER_UNPAY)) {//未支付支付订单过期
+//            log.info("监听商城过期appKey-redis过期:pattern={},channel={},key={}", new String(pattern), channel, key);
+//            String lockKey = "lockStoreAppKey:" + key;  // 分布式锁的 key
+//            Boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
+//            if (Boolean.TRUE.equals(lockAcquired)) {  // 只有一个实例会成功获取锁
+//                try {
+//                    String[] parts = key.split(":");
+//                    if (parts.length == 3) {
+//                        Long orderId = Long.parseLong(parts[parts.length - 1].trim());
+//                        if (orderId != null) {
+//                            //获取订单信息
+//                            FsStoreOrderScrm orderScrm = orderScrmMapper.selectFsStoreOrderById(orderId);
+//                            if (orderScrm != null && orderScrm.getStatus() == 0) {
+//                                //获取订单下的详情信息
+//                                List<FsStoreOrderItemVO> scrmList = orderItemScrmMapper.selectMyFsStoreOrderItemListByOrderId(orderId);
+//                                if (!scrmList.isEmpty()) {
+//                                    List<Long> orderItemIds = scrmList.stream().map(FsStoreOrderItemVO::getItemId).collect(Collectors.toList());
+//                                    //获取溯源码,进行回退
+//                                    List<FsStoreVerifyCodeScrm> verifyCodes = verifyCodeScrmMapper.selectList(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getOrderId, orderId).in(FsStoreVerifyCodeScrm::getOrderItemId, orderItemIds).eq(FsStoreVerifyCodeScrm::getIsDel, "0"));
+//                                    if(!verifyCodes.isEmpty()){
+//                                        verifyCodes.forEach(v->{
+//                                            v.setVerifyStatus(0L);
+//                                            v.setOutboundStatus(0L);
+//                                            v.setOrderId(0L);
+//                                            v.setOrderItemId(0L);
+//                                        });
+//                                        //批量更新数据
+//                                        verifyCodeScrmService.updateBatchById(verifyCodes);
+//                                    }
+//                                }
+//                                //更新订单状态
+//                                FsStoreOrderScrm updateOrder = new FsStoreOrderScrm();
+//                                updateOrder.setId(orderId);
+//                                updateOrder.setStatus(-3);
+//                                orderScrmMapper.updateFsStoreOrder(updateOrder);
+//                            }
+//                        }
+//                    } else {
+//                        log.error("监听appKey失效!");
+//                    }
+//                } finally {
+//                    // 释放锁,避免影响后续任务
+//                    redisTemplate.delete(lockKey);
+//                }
+//            } else {
+//                log.info("另一个实例已经处理了 key={},当前实例跳过", key);
+//            }
+//
+//        }
     }
 
 //    /**