Przeglądaj źródła

销售代下单

wangxy 3 tygodni temu
rodzic
commit
8f7cb30e73
36 zmienionych plików z 1140 dodań i 177 usunięć
  1. 12 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  2. 16 0
      fs-admin/src/main/java/com/fs/hisStore/task/ErpTask.java
  3. 13 0
      fs-admin/src/main/java/com/fs/web/controller/tool/TestController.java
  4. 7 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java
  5. 10 0
      fs-company/src/main/java/com/fs/company/controller/store/FsCouponController.java
  6. 17 0
      fs-company/src/main/java/com/fs/company/controller/store/FsInquiryOrderController.java
  7. 16 0
      fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java
  8. 2 0
      fs-company/src/main/java/com/fs/company/controller/store/FsStoreOrderController.java
  9. 30 0
      fs-company/src/main/java/com/fs/company/controller/store/FsUserController.java
  10. 3 0
      fs-company/src/main/java/com/fs/hisStore/controller/FsIntegralOrderController.java
  11. 15 0
      fs-service/src/main/java/com/fs/his/domain/FsIntegralOrder.java
  12. 6 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  13. 6 0
      fs-service/src/main/java/com/fs/his/mapper/FsCouponMapper.java
  14. 3 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserCouponMapper.java
  15. 6 1
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  16. 10 0
      fs-service/src/main/java/com/fs/his/param/FsCouponParam.java
  17. 45 0
      fs-service/src/main/java/com/fs/his/param/FsInquiryOrderManuallyParam.java
  18. 1 3
      fs-service/src/main/java/com/fs/his/param/FsIntegralOrderManuallyParam.java
  19. 28 0
      fs-service/src/main/java/com/fs/his/param/FsPackageOrderManuallyParam.java
  20. 17 0
      fs-service/src/main/java/com/fs/his/service/IFsCouponService.java
  21. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsInquiryOrderService.java
  22. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java
  23. 5 0
      fs-service/src/main/java/com/fs/his/service/IFsStoreProductService.java
  24. 5 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  25. 21 0
      fs-service/src/main/java/com/fs/his/service/impl/FsCouponServiceImpl.java
  26. 143 1
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  27. 160 136
      fs-service/src/main/java/com/fs/his/service/impl/FsIntegralOrderServiceImpl.java
  28. 136 0
      fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java
  29. 66 2
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  30. 177 32
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreProductServiceImpl.java
  31. 8 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  32. 5 0
      fs-service/src/main/java/com/fs/his/vo/FsDoctorListVO.java
  33. 5 0
      fs-service/src/main/java/com/fs/im/service/OpenIMService.java
  34. 102 1
      fs-service/src/main/java/com/fs/im/service/impl/OpenIMServiceImpl.java
  35. 13 1
      fs-service/src/main/resources/mapper/his/FsIntegralOrderMapper.xml
  36. 27 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml

+ 12 - 0
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -1848,4 +1848,16 @@ public class Task {
         fsConsecutiveWithdrawRecordService.checkConsecutiveWithdrawUsers();
     }
 
+    @Autowired
+    private IFsExternalOrderService fsExternalOrderService;
+
+    /**
+     * 外部订单批量推送聚水潭
+     */
+    public void pushExternalOrderToJst() throws Exception {
+        List<Long> orderIds = fsExternalOrderService.selectUnsyncedOrderIds();
+        log.info("外部订单推送聚水潭,待推送订单数: {}", orderIds.size());
+        fsExternalOrderService.pushToJstBatch(orderIds);
+    }
+
 }

+ 16 - 0
fs-admin/src/main/java/com/fs/hisStore/task/ErpTask.java

@@ -5,6 +5,7 @@ import com.fs.erp.domain.FsErpFinishPush;
 import com.fs.erp.dto.ErpOrderResponse;
 import com.fs.erp.mapper.FsErpFinishPushMapper;
 import com.fs.erp.service.IErpOrderService;
+import com.fs.his.service.IFsStoreProductService;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import lombok.extern.slf4j.Slf4j;
@@ -27,6 +28,9 @@ public class ErpTask {
     @Autowired
     private IFsStoreOrderScrmService fsStoreOrderService;
 
+    @Autowired
+    private IFsStoreProductService fsStoreProductService;
+
 
     /**
      * 推送完成订单到ERP
@@ -68,4 +72,16 @@ public class ErpTask {
 
     }
 
+    /**
+     * 根据ERP商品编码同步更新商品信息
+     */
+    public void syncProductFromErp() {
+        try {
+            int count = fsStoreProductService.updateStoreProductByErpProductCode();
+            log.info("ERP商品同步完成,更新商品数量: {}", count);
+        } catch (Exception e) {
+            log.error("ERP商品同步失败: {}", ExceptionUtils.getStackTrace(e), e);
+        }
+    }
+
 }

+ 13 - 0
fs-admin/src/main/java/com/fs/web/controller/tool/TestController.java

@@ -6,6 +6,7 @@ import java.util.*;
 import com.fs.common.core.domain.R;
 import com.fs.his.mapper.FsStoreOrderMapper;
 import com.fs.his.service.IFsStoreOrderService;
+import com.fs.his.service.IFsStoreProductService;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.task.Task;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,6 +53,9 @@ public class TestController extends BaseController {
     @Autowired
     IFsUserService  iFsUserService;
 
+    @Autowired
+    private IFsStoreProductService fsStoreProductService;
+
     @Autowired
     private Task task;
 
@@ -84,6 +88,15 @@ public class TestController extends BaseController {
         return R.ok();
     }
 
+    /**
+     * 测试从ERP更新商品信息
+     */
+    @GetMapping("/updateProductFromErp")
+    public R updateProductFromErp() {
+        int count = fsStoreProductService.updateStoreProductByErpProductCode();
+        return R.ok().put("updateCount", count);
+    }
+
     @ApiOperation("获取用户详细")
     @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path")
     @GetMapping("/{userId}")

+ 7 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java

@@ -897,4 +897,11 @@ public class CompanyUserController extends BaseController {
         List<CompanyUser> list = companyUserService.selectSubordinateList(userId);
         return R.ok().put("data", list);
     }
+
+    @Log(title = "删除IM好友", businessType = BusinessType.DELETE)
+    @PostMapping("/deleteAllImFriends")
+    public AjaxResult deleteAllImFriends() {
+        openIMService.deleteAllFriends();
+        return AjaxResult.success("删除任务已执行完成");
+    }
 }

+ 10 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsCouponController.java

@@ -79,6 +79,16 @@ public class FsCouponController extends BaseController
         return AjaxResult.success(fsCouponService.selectFsCouponByCouponId(couponId));
     }
 
+    /**
+     * 获取用户对应的优惠券
+     */
+    @PreAuthorize("@ss.hasPermi('store:coupon:query')")
+    @GetMapping("/getUserCoupon")
+    public TableDataInfo getUserCoupon(FsCouponParam fsCoupon){
+        startPage();
+        return getDataTable(fsCouponService.selectUserCouponByTypeWithGoods(fsCoupon.getUserId(), fsCoupon.getCouponType(), fsCoupon.getGoodsId()));
+    }
+
 //    /**
 //     * 新增优惠券
 //     */

+ 17 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsInquiryOrderController.java

@@ -2,6 +2,7 @@ package com.fs.company.controller.store;
 
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSON;
+import com.fs.common.annotation.DataScope;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.controller.BaseController;
@@ -19,6 +20,7 @@ import com.fs.his.domain.FsInquiryOrderMsg;
 import com.fs.his.domain.FsStoreOrderLogs;
 import com.fs.his.param.FsInquiryOrderCancelParam;
 import com.fs.his.param.FsInquiryOrderCreateParam;
+import com.fs.his.param.FsInquiryOrderManuallyParam;
 import com.fs.his.param.FsInquiryOrderParam;
 import com.fs.his.param.FsInquiryOrderRefundParam;
 import com.fs.his.service.IFsDoctorService;
@@ -66,6 +68,7 @@ public class FsInquiryOrderController extends BaseController
      */
 //    @PreAuthorize("@ss.hasPermi('store:inquiryOrder:list')")
     @GetMapping("/list")
+    @DataScope(deptAlias = "cu",userAlias = "cu")
    public TableDataInfo list(FsInquiryOrderParam fsInquiryOrder)
     {
         startPage();
@@ -272,6 +275,20 @@ public class FsInquiryOrderController extends BaseController
         return fsInquiryOrderService.createOrder(param);
     }
 
+    /**
+     * 手动代下问诊订单
+     */
+    @PreAuthorize("@ss.hasPermi('store:inquiryOrder:manually')")
+    @Log(title = "手动代下问诊订单", businessType = BusinessType.INSERT)
+    @PostMapping("/createManually")
+    public R createManually(@RequestBody @Validated FsInquiryOrderManuallyParam param)
+    {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        param.setCompanyUserId(loginUser.getUser().getUserId());
+        return fsInquiryOrderService.createOrderManually(param);
+    }
+
     /**
      * 修改问诊订单
      */

+ 16 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java

@@ -14,6 +14,7 @@ import com.fs.framework.security.SecurityUtils;
 import com.fs.his.domain.FsExportTask;
 import com.fs.his.domain.FsPackageOrder;
 import com.fs.his.param.FsPackageOrderAddParam;
+import com.fs.his.param.FsPackageOrderManuallyParam;
 import com.fs.his.param.FsPackageOrderParam;
 import com.fs.his.service.IFsExportTaskService;
 import com.fs.his.service.IFsPackageOrderService;
@@ -22,6 +23,7 @@ import com.fs.his.vo.FsPackageOrderListVO;
 import com.fs.his.vo.FsPackageOrderVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Base64;
@@ -197,6 +199,20 @@ public class FsPackageOrderController extends BaseController
         return fsPackageOrderService.addPackageOrder(fsPackageOrder);
     }
 
+    /**
+     * 手动代下套餐订单
+     */
+    @PreAuthorize("@ss.hasPermi('store:packageOrder:manually')")
+    @Log(title = "手动代下套餐订单", businessType = BusinessType.INSERT)
+    @PostMapping("/createManually")
+    public R createManually(@RequestBody @Validated FsPackageOrderManuallyParam param)
+    {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        param.setCompanyUserId(loginUser.getUser().getUserId());
+        return fsPackageOrderService.addPackageOrderManually(param);
+    }
+
     /**
      * 修改套餐订单
      */

+ 2 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsStoreOrderController.java

@@ -87,6 +87,7 @@ public class FsStoreOrderController extends BaseController
      * @return
      */
     @GetMapping("/auditList")
+    @DataScope(deptAlias = "cu",userAlias = "cu")
     public  TableDataInfo auditList(FsStoreOrderParam fsStoreOrder)
     {
         startPage();
@@ -101,6 +102,7 @@ public class FsStoreOrderController extends BaseController
 
     @GetMapping("/myList")
     @PreAuthorize("@ss.hasPermi('his:storeOrder:myList')")
+    @DataScope(deptAlias = "cu",userAlias = "cu")
     public TableDataInfo myList(FsStoreOrderParam fsStoreOrder)
     {
         startPage();

+ 30 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsUserController.java

@@ -101,6 +101,24 @@ public class FsUserController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 查询外部用户列表(isExternal = 0)
+     */
+    @PreAuthorize("@ss.hasPermi('his:user:externalList')")
+    @GetMapping("/externalList")
+    public TableDataInfo externalList(FsUserParam fsUser)
+    {
+        startPage();
+        fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        List<FsUserVO> list = fsUserService.selectExternalUserList(fsUser);
+        for (FsUserVO fsUserVO : list) {
+            fsUserVO.setPhone(decryptAutoPhoneMk(fsUserVO.getPhone()));
+        }
+        return getDataTable(list);
+    }
+
+
+
     @PreAuthorize("@ss.hasPermi('his:user:myList')")
     @GetMapping("/myList")
     public TableDataInfo myList(FsUserParam fsUser)
@@ -223,6 +241,18 @@ public class FsUserController extends BaseController
        return toAjax(fsUserService.insertFsUser(fsUser));
     }
 
+    /**
+     * 新增外部用户(isExternal = 0)
+     */
+    @PreAuthorize("@ss.hasPermi('his:user:addExternalUser')")
+    @Log(title = "新增外部用户", businessType = BusinessType.INSERT)
+    @PostMapping("/addExternalUser")
+    public AjaxResult addExternalUser(@RequestBody FsUser fsUser)
+    {
+        fsUser.setIsExternal(0);
+        return toAjax(fsUserService.insertFsUser(fsUser));
+    }
+
     /**
      * 修改用户
      */

+ 3 - 0
fs-company/src/main/java/com/fs/hisStore/controller/FsIntegralOrderController.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
+import com.fs.common.annotation.DataScope;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -65,6 +66,7 @@ public class FsIntegralOrderController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('his:integralOrder:list')")
     @GetMapping("/list")
+    @DataScope(deptAlias = "cu",userAlias = "cu")
     public TableDataInfo list(FsIntegralOrderParam fsIntegralOrder)
     {
         startPage();
@@ -188,6 +190,7 @@ public class FsIntegralOrderController extends BaseController
     }
 
     @PostMapping("/createByManually")
+    @PreAuthorize("@ss.hasPermi('his:integralOrder:createByManually')")
     @Log(title = "手动创建积分订单", businessType = BusinessType.INSERT)
     public R createByManually(@RequestBody FsIntegralOrderManuallyParam param)
     {

+ 15 - 0
fs-service/src/main/java/com/fs/his/domain/FsIntegralOrder.java

@@ -139,4 +139,19 @@ public class FsIntegralOrder
      */
     @TableField(exist = false)
     private List<Long> userIds;
+
+    /**
+     * 优惠券id
+     */
+    private Long couponId;
+
+    /**
+     * 订单总金额
+     */
+    private BigDecimal totalPrice;
+
+    /**
+     * 优惠金额
+     */
+    private BigDecimal discountPrice;
 }

+ 6 - 0
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -269,4 +269,10 @@ public class FsUser extends BaseEntity
     /** 是否下载APP (1=已下载, 0=未下载) */
     @TableField(exist = false)
     private Integer isDownloadApp;
+
+    /**
+     * 是否是外部订单用户(0:是 1:否)
+     */
+    private  Integer isExternal;
+
 }

+ 6 - 0
fs-service/src/main/java/com/fs/his/mapper/FsCouponMapper.java

@@ -98,4 +98,10 @@ public interface FsCouponMapper
     List<FsCouponListUVO> selectFsCouponListUVO(@Param("maps")FsCouponListUParam param);
     @Update("update fs_coupon set remain_number=number-(select ifnull(count(1),0) from fs_user_coupon uc where uc.coupon_id=#{couponId}) where coupon_id=#{couponId}")
     int updateRemainCount(Long couponId);
+
+    @Select("SELECT c.* FROM fs_coupon c " +
+            "INNER JOIN fs_user_coupon uc ON c.coupon_id = uc.coupon_id " +
+            "WHERE uc.user_id = #{userId} AND c.coupon_type = #{couponType} AND uc.status = 0 " +
+            "ORDER BY uc.create_time DESC")
+    List<FsCoupon> selectUserCouponByType(@Param("userId") Long userId, @Param("couponType") Integer couponType);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserCouponMapper.java

@@ -129,4 +129,7 @@ public interface FsUserCouponMapper
     List<FsUserCouponListUVO> getMyEnableCouponList(@Param("maps")FsUserCouponUParam param);
     @Select("select ifnull(count(1),0) from fs_user_coupon where coupon_id=#{couponId} and user_id=#{userId}")
     int checkReceive(@Param("userId")Long userId,@Param("couponId")Long couponId);
+
+    @Select("select * from fs_user_coupon where coupon_id=#{couponId} and user_id=#{userId} limit 1")
+    FsUserCoupon selectByCouponIdAndUserId(@Param("couponId") Long couponId, @Param("userId") Long userId);
 }

+ 6 - 1
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -243,7 +243,7 @@ public interface FsUserMapper
     List<Long> selectUserByStoreOrder();
     @Select({"<script> " +
             "select f1.*,f2.nick_name tui_name,f2.phone tui_phone FROM fs_user f1 LEFT JOIN fs_user f2 ON f1.tui_user_id =f2.user_id "+
-            " where f1.is_del=0 "+
+            " where f1.is_del=0 and f1.is_external=1 "+
             "  <if test=\"nickName != null  and nickName != ''\"> and f1.nick_name like concat(#{nickName}, '%')</if>\n" +
             "            <if test=\"avatar != null  and avatar != ''\"> and f1.avatar = #{avatar}</if>\n" +
             "            <if test=\"phone != null  and phone != ''\"> and f1.phone = #{phone}</if>\n" +
@@ -606,4 +606,9 @@ public interface FsUserMapper
     int addIntegral(@Param("userId") Long userId,@Param("integral") Long integral);
 
     int disabledUsers(@Param("param") FsUserDisabledUsersParam param);
+
+    /**
+     * 查询外部用户列表(isExternal = 0)
+     */
+    List<FsUserVO> selectExternalUserList(FsUserParam fsUser);
 }

+ 10 - 0
fs-service/src/main/java/com/fs/his/param/FsCouponParam.java

@@ -31,5 +31,15 @@ public class FsCouponParam implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 积分商品id
+     */
+    private Long goodsId;
+
 
 }

+ 45 - 0
fs-service/src/main/java/com/fs/his/param/FsInquiryOrderManuallyParam.java

@@ -0,0 +1,45 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class FsInquiryOrderManuallyParam implements Serializable {
+
+    @NotNull(message = "用户ID不能为空")
+    private Long userId;
+
+    @NotNull(message = "患者ID不能为空")
+    private Long patientId;
+
+    @NotEmpty(message = "病情描述不能为空")
+    private String title;
+
+    private Integer inquiryType;
+
+    @NotNull(message = "订单类型不能为空")
+    private Integer orderType;
+
+    private Integer inquirySubType;
+
+    private String companyUserRemark;
+
+    private String duration;
+
+    private String isVisit;
+
+    private Long companyId;
+
+    private Long companyUserId;
+
+    private Long doctorId;
+
+    /**
+     * 优惠券id
+     */
+    private Long  couponId;
+}

+ 1 - 3
fs-service/src/main/java/com/fs/his/param/FsIntegralOrderManuallyParam.java

@@ -3,7 +3,6 @@ package com.fs.his.param;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
-import java.math.BigDecimal;
 import java.util.List;
 
 @Data
@@ -12,9 +11,8 @@ public class FsIntegralOrderManuallyParam {
     private Long addressId;
     private Long companyId;
     private Long companyUserId;
-    private Integer payType;
-    private BigDecimal payMoney;
     private Long activityId;
+    private Long couponId;
 
     @NotNull(message = "商品ID列表不能为空")
     private List<Long> goodsIds;

+ 28 - 0
fs-service/src/main/java/com/fs/his/param/FsPackageOrderManuallyParam.java

@@ -0,0 +1,28 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class FsPackageOrderManuallyParam implements Serializable {
+
+    @NotNull(message = "用户ID不能为空")
+    private Long userId;
+
+    @NotNull(message = "患者ID不能为空")
+    private Long patientId;
+
+    @NotNull(message = "套餐ID不能为空")
+    private Long packageId;
+
+    @NotNull(message = "地址ID不能为空")
+    private Long addressId;
+
+    private Long companyId;
+
+    private Long companyUserId;
+
+    private Long couponId;
+}

+ 17 - 0
fs-service/src/main/java/com/fs/his/service/IFsCouponService.java

@@ -75,4 +75,21 @@ public interface IFsCouponService
     List<FsCouponListUVO> selectFsCouponListUVO(FsCouponListUParam param);
 
     R receive(FsCouponReceiveParam param);
+
+    /**
+     * 查询用户指定类型的优惠券列表
+     * @param userId 用户ID
+     * @param couponType 优惠券类型 3问诊优惠券 5套餐包优惠券 7积分商品免单券
+     * @return 优惠券列表
+     */
+    List<FsCoupon> selectUserCouponByType(Long userId, Integer couponType);
+
+    /**
+     * 查询用户指定类型的优惠券列表(带商品匹配)
+     * @param userId 用户ID
+     * @param couponType 优惠券类型 3问诊优惠券 5套餐包优惠券 7积分商品免单券
+     * @param goodsId 商品ID(用于积分优惠券匹配)
+     * @return 优惠券列表
+     */
+    List<FsCoupon> selectUserCouponByTypeWithGoods(Long userId, Integer couponType, Long goodsId);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/IFsInquiryOrderService.java

@@ -133,4 +133,6 @@ public interface IFsInquiryOrderService
     R getWxaCodeInquiryOrderUnLimitR(Long orderId);
 
     void closeOrder(Long orderId);
+
+    R createOrderManually(FsInquiryOrderManuallyParam param);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java

@@ -145,4 +145,6 @@ public interface IFsPackageOrderService
     R getPackageOrder(String createOrderKey);
 
     List<FsPackageOrder> selectOutTimeOrderList(Integer unPayTime);
+
+    R addPackageOrderManually(FsPackageOrderManuallyParam param);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/service/IFsStoreProductService.java

@@ -108,4 +108,9 @@ public interface IFsStoreProductService
     List<FsStoreProduct> getStoreProductInProductIds(List<Long> productIds);
 
     List<FsStoreProductListVO> liveList(LiveGoods liveId);
+
+    /**
+     * 根据商品编码 获取erp商品信息更新商品及属性等信息
+     */
+    int updateStoreProductByErpProductCode();
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -314,4 +314,9 @@ public interface IFsUserService
      * 批量禁用用户
      */
     int disabledUsers(FsUserDisabledUsersParam param);
+
+    /**
+     * 查询外部用户列表(isExternal = 0)
+     */
+    List<FsUserVO> selectExternalUserList(FsUserParam fsUser);
 }

+ 21 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsCouponServiceImpl.java

@@ -1,8 +1,10 @@
 package com.fs.his.service.impl;
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
@@ -156,6 +158,25 @@ public class FsCouponServiceImpl implements IFsCouponService
         redisCache.deleteObject(param.getCode());
         return R.ok();
     }
+
+    @Override
+    public List<FsCoupon> selectUserCouponByType(Long userId, Integer couponType) {
+        return fsCouponMapper.selectUserCouponByType(userId, couponType);
+    }
+
+    @Override
+    public List<FsCoupon> selectUserCouponByTypeWithGoods(Long userId, Integer couponType, Long goodsId) {
+        List<FsCoupon> coupons = fsCouponMapper.selectUserCouponByType(userId, couponType);
+        if (couponType == 7 && goodsId != null) {
+            // TODO: 积分商品免单券需要判断 fs_coupon 表的 free_goods_id 字段是否和商品ID对应
+            // 目前 FsCoupon 实体类暂无 freeGoodsId 字段,后续需要添加该字段后启用以下逻辑
+            // coupons = coupons.stream()
+            //     .filter(c -> c.getFreeGoodsId() != null && c.getFreeGoodsId().equals(goodsId))
+            //     .collect(Collectors.toList());
+        }
+        return coupons;
+    }
+
     @Synchronized
     public static String genCode() {
         String year = new SimpleDateFormat("yy").format(new Date());

+ 143 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java

@@ -159,6 +159,8 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
     @Autowired
     private FsUserCouponMapper userCouponMapper;
     @Autowired
+    private FsCouponMapper fsCouponMapper;
+    @Autowired
     RedisCache redisCache;
     @Autowired
     FsPackageOrderMapper fsPackageOrderMapper;
@@ -703,7 +705,7 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
                 report=new FsInquiryOrderReport();
                 report.setUserId(order.getUserId());
                 report.setPatientId(order.getPatientId());
-                report.setPatientJson(JSONUtil.toJsonStr(dto));
+                report.setPatientJson(JSONUtil.toJsonStr(   dto));
                 report.setReportSn(reportSn);
                 report.setStatus(1);
                 if (doctor != null) {
@@ -786,6 +788,146 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
         }
     }
 
+    @Override
+    @Transactional
+    public R createOrderManually(FsInquiryOrderManuallyParam param) {
+        FsUser user = userMapper.selectFsUserByUserId(param.getUserId());
+        if (user == null || user.getStatus() != 1) {
+            return R.error("用户不存在或已被禁用");
+        }
+        FsPatient patient = fsPatientMapper.selectFsPatientByPatientId(param.getPatientId());
+        if (patient == null) {
+            return R.error("患者不能为空");
+        }
+        FsInquiryOrderPatientDTO dto = new FsInquiryOrderPatientDTO();
+        BeanUtils.copyProperties(patient, dto);
+        dto.setAge(String.valueOf(DateUtil.ageOfNow(patient.getBirthday())));
+        dto.setBirthday(new SimpleDateFormat("yyyy-MM-dd").format(patient.getBirthday()));
+        dto.setDuration(param.getDuration());
+        dto.setTitle(param.getTitle());
+        dto.setIsVisit(param.getIsVisit());
+        if (patient.getMobile() != null && patient.getMobile().length() == 11 && patient.getMobile().matches("\\d+")) {
+            dto.setMobile(encryptPhone(patient.getMobile()));
+        } else {
+            dto.setMobile(patient.getMobile());
+        }
+
+        FsInquiryOrder order = new FsInquiryOrder();
+        String orderSn = OrderCodeUtils.getOrderSn();
+        if (StringUtils.isEmpty(orderSn)) {
+            return R.error("订单生成失败,请重试");
+        }
+        order.setOrderSn(orderSn);
+        order.setOrderType(param.getOrderType());
+        order.setInquiryType(param.getInquiryType());
+        order.setTitle(param.getTitle());
+        order.setUserId(param.getUserId());
+        order.setPatientId(patient.getPatientId());
+        order.setInquirySubType(param.getInquirySubType());
+        order.setCompanyUserRemark(param.getCompanyUserRemark());
+
+        String json = configService.selectConfigByKey("his.inquiryConfig");
+        InquiryConfigDTO configDTO = JSONUtil.toBean(json, InquiryConfigDTO.class);
+
+        if (param.getDoctorId() != null) {
+            FsDoctor doctor = doctorMapper.selectFsDoctorByDoctorId(param.getDoctorId());
+            if (doctor == null || doctor.getStatus() == 0) {
+                return R.error("医生不存在或已被禁用");
+            }
+            if (doctor.getWorkStatus() != 1) {
+                return R.error("医生已停诊");
+            }
+            order.setDoctorId(doctor.getDoctorId());
+            order.setDepartmentId(doctor.getDeptId());
+            if (doctor.getPriceJson() != null) {
+                List<FsPriceDTO> priceDTOList = JSONUtil.parseArray(doctor.getPriceJson()).toList(FsPriceDTO.class);
+                List<FsPriceDTO> doctorPrice = priceDTOList.stream().filter(x -> x.getType().equals(param.getOrderType())).collect(Collectors.toList());
+                if (doctorPrice != null && doctorPrice.size() == 1) {
+                    order.setMoney(doctorPrice.get(0).getPrice());
+                    order.setPayMoney(doctorPrice.get(0).getPrice());
+                }
+            }
+        } else {
+            List<FsPriceDTO> price = configDTO.getPrices().stream().filter(x -> x.getType().equals(param.getOrderType())).collect(Collectors.toList());
+            if (price != null && price.size() == 1) {
+                order.setMoney(price.get(0).getPrice());
+                order.setPayMoney(price.get(0).getPrice());
+            }
+        }
+
+        FsUserCoupon userCoupon = null;
+        FsCoupon coupon = null;
+        if (param.getCouponId() != null) {
+            coupon = fsCouponMapper.selectFsCouponByCouponId(param.getCouponId());
+            if (coupon == null) {
+                return R.error("优惠券配置不存在");
+            }
+            if (coupon.getCouponType() != 3) {
+                return R.error("优惠券类型不正确,仅支持问诊优惠券");
+            }
+            if (coupon.getLimitTime() != null && coupon.getLimitTime().before(new Date())) {
+                return R.error("优惠券已过期");
+            }
+            userCoupon = userCouponMapper.selectByCouponIdAndUserId(param.getCouponId(),param.getUserId());
+            if (userCoupon == null) {
+                return R.error("该用户的优惠券不存在");
+            }
+            if (userCoupon.getStatus() != 0) {
+                return R.error("优惠券已使用或已过期");
+            }
+
+            order.setUserCouponId(param.getCouponId());
+            BigDecimal couponPrice = coupon.getPrice();
+            BigDecimal orderMoney = order.getMoney() != null ? order.getMoney() : BigDecimal.ZERO;
+            if(couponPrice==null){
+                couponPrice=orderMoney;
+            }
+            BigDecimal payMoney = orderMoney.subtract(couponPrice);
+            if (payMoney.compareTo(BigDecimal.ZERO) < 0) {
+                payMoney = BigDecimal.ZERO;
+            }
+            order.setPayMoney(payMoney);
+        }
+
+        order.setIsReceive(0);
+        order.setIsAudit(1);
+
+        order.setStatus(2);
+        order.setIsPay(1);
+        order.setPayTime(new Date());
+        order.setCreateTime(new Date());
+        order.setIsPing(0);
+
+        if (param.getCompanyId() != null) {
+            Company company = companyService.selectCompanyById(param.getCompanyId());
+            if (company != null && company.getStatus().equals(1)) {
+                CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
+                if (companyUser != null && companyUser.getStatus().equals("0")) {
+                    order.setCompanyId(param.getCompanyId());
+                    order.setCompanyUserId(param.getCompanyUserId());
+                    if (companyUser.getDeptId() != null) {
+                        order.setDeptId(companyUser.getDeptId());
+                    }
+                }
+            }
+        }
+        order.setPatientJson(JSONUtil.toJsonStr(dto));
+        if (fsInquiryOrderMapper.insertFsInquiryOrder(order) > 0) {
+            if (userCoupon != null) {
+                FsUserCoupon updateUserCoupon = new FsUserCoupon();
+                updateUserCoupon.setId(userCoupon.getId());
+                updateUserCoupon.setStatus(1);
+                updateUserCoupon.setUseTime(new Date());
+                updateUserCoupon.setBusinessId(order.getOrderId());
+                updateUserCoupon.setBusinessType(1);
+                userCouponMapper.updateFsUserCoupon(updateUserCoupon);
+            }
+            return R.ok().put("order", order);
+        } else {
+            return R.error("创建失败");
+        }
+    }
+
     @Override
     @Transactional
     public R payConfirm(String orderSn,String payCode, String tradeNo,String payType,Integer type,String bankTransactionId,String bankSerialNo) {

+ 160 - 136
fs-service/src/main/java/com/fs/his/service/impl/FsIntegralOrderServiceImpl.java

@@ -94,8 +94,7 @@ import static com.fs.his.utils.PhoneUtil.decryptPhone;
  */
 @Slf4j
 @Service
-public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
-{
+public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService {
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
     @Autowired
     private FsIntegralOrderMapper fsIntegralOrderMapper;
@@ -125,7 +124,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     @Autowired
     private IFsStorePaymentService storePaymentService;
     @Autowired
-    private  FsStorePaymentMapper storePaymentMapper;
+    private FsStorePaymentMapper storePaymentMapper;
     @Autowired
     private IFsIntegralCartService cartService;
     @Autowired
@@ -182,6 +181,12 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     @Autowired
     private FsCourseCheckinReceiveMapper fsCourseCheckinReceiveMapper;
 
+    @Autowired
+    private FsUserCouponMapper fsUserCouponMapper;
+
+    @Autowired
+    private FsCouponMapper fsCouponMapper;
+
     @Autowired
     private RedisCacheUtil redisCacheUtil;
 
@@ -206,8 +211,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 积分商品订单
      */
     @Override
-    public FsIntegralOrder selectFsIntegralOrderByOrderId(Long orderId)
-    {
+    public FsIntegralOrder selectFsIntegralOrderByOrderId(Long orderId) {
         return fsIntegralOrderMapper.selectFsIntegralOrderByOrderId(orderId);
     }
 
@@ -218,8 +222,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 积分商品订单
      */
     @Override
-    public List<FsIntegralOrder> selectFsIntegralOrderList(FsIntegralOrder fsIntegralOrder)
-    {
+    public List<FsIntegralOrder> selectFsIntegralOrderList(FsIntegralOrder fsIntegralOrder) {
         return fsIntegralOrderMapper.selectFsIntegralOrderList(fsIntegralOrder);
     }
 
@@ -230,8 +233,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 结果
      */
     @Override
-    public int insertFsIntegralOrder(FsIntegralOrder fsIntegralOrder)
-    {
+    public int insertFsIntegralOrder(FsIntegralOrder fsIntegralOrder) {
         fsIntegralOrder.setCreateTime(DateUtils.getNowDate());
         return fsIntegralOrderMapper.insertFsIntegralOrder(fsIntegralOrder);
     }
@@ -243,8 +245,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 结果
      */
     @Override
-    public int updateFsIntegralOrder(FsIntegralOrder fsIntegralOrder)
-    {
+    public int updateFsIntegralOrder(FsIntegralOrder fsIntegralOrder) {
         return fsIntegralOrderMapper.updateFsIntegralOrder(fsIntegralOrder);
     }
 
@@ -255,8 +256,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 结果
      */
     @Override
-    public int deleteFsIntegralOrderByOrderIds(Long[] orderIds)
-    {
+    public int deleteFsIntegralOrderByOrderIds(Long[] orderIds) {
         return fsIntegralOrderMapper.deleteFsIntegralOrderByOrderIds(orderIds);
     }
 
@@ -267,8 +267,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      * @return 结果
      */
     @Override
-    public int deleteFsIntegralOrderByOrderId(Long orderId)
-    {
+    public int deleteFsIntegralOrderByOrderId(Long orderId) {
         return fsIntegralOrderMapper.deleteFsIntegralOrderByOrderId(orderId);
     }
 
@@ -282,10 +281,10 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
 
         FsIntegralOrder order = fsIntegralOrderMapper.selectFsIntegralOrderByOrderId(fsIntegralOrder.getOrderId());
 
-        if (order==null){
+        if (order == null) {
             throw new CustomException("订单不存在");
         }
-        if (order.getStatus()!=1L){
+        if (order.getStatus() != 1L) {
             throw new CustomException("非法更改");
         }
         FsIntegralOrder o1 = new FsIntegralOrder();
@@ -310,9 +309,9 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     @Transactional
     public R createOrder(FsIntegralOrderCreateParam param) {
 
-        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
-        FsUserAddress address=fsUserAddressMapper.selectFsUserAddressByAddressId(param.getAddressId());
-        FsIntegralGoods integralGoods=fsIntegralGoodsMapper.selectFsIntegralGoodsByGoodsId(param.getGoodsId());
+        FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
+        FsUserAddress address = fsUserAddressMapper.selectFsUserAddressByAddressId(param.getAddressId());
+        FsIntegralGoods integralGoods = fsIntegralGoodsMapper.selectFsIntegralGoodsByGoodsId(param.getGoodsId());
         if (Objects.isNull(user)) {
             return R.error("用户不存在");
         }
@@ -322,7 +321,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         if (Objects.isNull(integralGoods)) {
             return R.error("商品不存在");
         }
-        if(integralGoods.getStock()<=0L){
+        if (integralGoods.getStock() <= 0L) {
             return R.error("库存不足");
         }
 
@@ -330,19 +329,19 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         BigDecimal totalCash = integralGoods.getCash();
         Long activityId = param.getActivityId();
 
-        if(param.getIsAPP() != null && param.getIsAPP() == 1){
+        if (param.getIsAPP() != null && param.getIsAPP() == 1) {
             FsCourseCheckinPrize prizeQuery = new FsCourseCheckinPrize();
             prizeQuery.setGoodsId(param.getGoodsId());
             prizeQuery.setPrizeType(2);
             List<FsCourseCheckinPrize> prizeList = fsCourseCheckinPrizeMapper.selectFsCourseCheckinPrizeList(prizeQuery);
-            if(ObjectUtil.isNotEmpty(prizeList)){
+            if (ObjectUtil.isNotEmpty(prizeList)) {
                 FsCourseCheckinReceive receiveQuery = new FsCourseCheckinReceive();
                 receiveQuery.setUserId(param.getUserId());
                 receiveQuery.setActivityId(param.getActivityId());
                 receiveQuery.setGoodsId(param.getGoodsId());
                 receiveQuery.setReceiveStatus(0);
                 List<FsCourseCheckinReceive> receiveList = fsCourseCheckinReceiveMapper.selectFsCourseCheckinReceiveList(receiveQuery);
-                if(ObjectUtil.isNotEmpty(receiveList)){
+                if (ObjectUtil.isNotEmpty(receiveList)) {
                     totalIntegral = 0L;
                     totalCash = BigDecimal.ZERO;
                     activityId = param.getActivityId();
@@ -350,7 +349,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             }
         }
 
-        if(totalIntegral > 0 && user.getIntegral() < totalIntegral){
+        if (totalIntegral > 0 && user.getIntegral() < totalIntegral) {
             return R.error("积分不足");
         }
 
@@ -372,15 +371,15 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     /**
      * 创建订单
      */
-    private R createOrder(FsUser user, FsUserAddress address, Long totalIntegral, BigDecimal totalCash, List<FsIntegralGoods> goodsItem, Long companyUserId,Long goodsId,Long activityId) {
+    private R createOrder(FsUser user, FsUserAddress address, Long totalIntegral, BigDecimal totalCash, List<FsIntegralGoods> goodsItem, Long companyUserId, Long goodsId, Long activityId) {
         FsIntegralOrder order = new FsIntegralOrder();
         String orderSn = null;
-        try{
+        try {
             orderSn = OrderCodeUtils.getOrderSn();
-        }catch (Exception e){
+        } catch (Exception e) {
             orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
         }
-        if(StringUtils.isEmpty(orderSn)){
+        if (StringUtils.isEmpty(orderSn)) {
             throw new CustomException("订单生成失败,请重试");
         }
 
@@ -406,31 +405,31 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         order.setIntegral(totalIntegral.toString());
         order.setItemJson(JSONUtil.toJsonStr(goodsItem));
         order.setUserName(address.getRealName());
-        order.setUserAddress(address.getProvince()+address.getCity()+address.getDistrict()+address.getDetail());
+        order.setUserAddress(address.getProvince() + address.getCity() + address.getDistrict() + address.getDetail());
         order.setUserPhone(address.getPhone());
         order.setCreateTime(new Date());
         order.setCompanyUserId(companyUserId);
         CompanyUser companyUser = companyUserMapper.selectCompanyUserByCompanyUserId(companyUserId);
-        if (ObjectUtil.isNotEmpty(companyUser)){
+        if (ObjectUtil.isNotEmpty(companyUser)) {
             order.setCompanyId(companyUser.getCompanyId());
         }
 
         //判断当前用户是否有关联企微ID
-        if(ObjectUtil.isNotNull(user.getQwUserId())){
+        if (ObjectUtil.isNotNull(user.getQwUserId())) {
             //获取企微信息
-            QwUser qwUser=qwUserMapper.selectOne(new LambdaQueryWrapper<QwUser>().select(QwUser::getId,QwUser::getCompanyId,QwUser::getCompanyUserId).eq(QwUser::getId,user.getQwUserId()));
-            if(ObjectUtil.isNotNull(qwUser)){
+            QwUser qwUser = qwUserMapper.selectOne(new LambdaQueryWrapper<QwUser>().select(QwUser::getId, QwUser::getCompanyId, QwUser::getCompanyUserId).eq(QwUser::getId, user.getQwUserId()));
+            if (ObjectUtil.isNotNull(qwUser)) {
                 //写入企业微信ID、销售ID、公司id
                 order.setQwUserId(qwUser.getId());
-                order.setCompanyId(ObjectUtil.isNotNull(qwUser.getCompanyId())?qwUser.getCompanyId():null);
-                order.setCompanyUserId(ObjectUtil.isNotNull(qwUser.getCompanyUserId())?qwUser.getCompanyUserId():null);
+                order.setCompanyId(ObjectUtil.isNotNull(qwUser.getCompanyId()) ? qwUser.getCompanyId() : null);
+                order.setCompanyUserId(ObjectUtil.isNotNull(qwUser.getCompanyUserId()) ? qwUser.getCompanyUserId() : null);
             }
         }
 
-        if(fsIntegralOrderMapper.insertFsIntegralOrder(order)>0){
+        if (fsIntegralOrderMapper.insertFsIntegralOrder(order) > 0) {
             if (order.getPayType() != 2) {
                 //写入日志
-                FsUser userMap=new FsUser();
+                FsUser userMap = new FsUser();
                 userMap.setUserId(user.getUserId());
 
                 // 可消费积分
@@ -439,7 +438,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                     // 扣除完可消费积分后,剩余的积分
                     long extra = totalIntegral - consumer;
                     // 可提现积分扣除 剩余积分
-                    Long withdrawIntegral = user.getWithdrawIntegral()- extra;
+                    Long withdrawIntegral = user.getWithdrawIntegral() - extra;
                     userMap.setIntegral(withdrawIntegral);
                     userMap.setWithdrawIntegral(withdrawIntegral);
                 } else {
@@ -456,20 +455,20 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 fsUserIntegralLogsMapper.insertFsUserIntegralLogs(logs);
             }
             //如何是打卡活动的积分商品则修改领取状态
-            if(activityId!=null&&goodsId!=null){
+            if (activityId != null && goodsId != null) {
                 FsCourseCheckinReceive receiveQuery = new FsCourseCheckinReceive();
                 receiveQuery.setUserId(order.getUserId());
                 receiveQuery.setActivityId(activityId);
                 receiveQuery.setGoodsId(goodsId);
                 receiveQuery.setReceiveStatus(0);
                 List<FsCourseCheckinReceive> receiveList = fsCourseCheckinReceiveMapper.selectFsCourseCheckinReceiveList(receiveQuery);
-                if(ObjectUtil.isNotEmpty(receiveList)){
+                if (ObjectUtil.isNotEmpty(receiveList)) {
                     FsCourseCheckinReceive receive = receiveList.get(0);
                     receive.setReceiveStatus(1);
                     receive.setReceiveTime(new Date());
                     receive.setUpdateTime(new Date());
                     fsCourseCheckinReceiveMapper.updateFsCourseCheckinReceive(receive);
-                    if(receive.getGoodsId() != null){
+                    if (receive.getGoodsId() != null) {
                         redisCacheUtil.delRedisKey("getIntegralGoodsById::" + receive.getGoodsId());
                     }
                 }
@@ -483,30 +482,30 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 integralParam.setBusinessId(order.getOrderId().toString());
                 userIntegralLogsService.addIntegralTemplate(integralParam);
 
-                return R.ok("兑换成功").put("order",order).put("isPay", 1);
+                return R.ok("兑换成功").put("order", order).put("isPay", 1);
             }
             // 现金 或 积分+现金
             else {
                 String redisKey = String.valueOf(StrUtil.format("{}{}", FsConstants.REDIS_INTEGRAL_ORDER_UNPAY, order.getOrderId()));
-                redisCache.setCacheObject(redisKey,order.getOrderId(),30, TimeUnit.MINUTES);
-                return R.ok().put("order",order).put("isPay", 0);
+                redisCache.setCacheObject(redisKey, order.getOrderId(), 30, TimeUnit.MINUTES);
+                return R.ok().put("order", order).put("isPay", 0);
             }
-        }
-        else{
+        } else {
             throw new CustomException("订单创建失败");
         }
     }
 
     /**
      * 创建购物车订单
+     *
      * @param param 参数
-     * @return  R
+     * @return R
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
     public R createCartOrder(FsIntegralCartOrderCreateParam param) {
-        FsUser user=fsUserMapper.selectFsUserByUserId(param.getUserId());
-        FsUserAddress address=fsUserAddressMapper.selectFsUserAddressByAddressId(param.getAddressId());
+        FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
+        FsUserAddress address = fsUserAddressMapper.selectFsUserAddressByAddressId(param.getAddressId());
 
         if (Objects.isNull(user)) {
             throw new CustomException("用户不存在");
@@ -531,7 +530,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             if (Objects.isNull(integralGoods)) {
                 throw new CustomException("商品不存在");
             }
-            if(integralGoods.getStock() < cart.getCartNum()){
+            if (integralGoods.getStock() < cart.getCartNum()) {
                 throw new CustomException("库存不足");
             }
 
@@ -547,32 +546,29 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             goodsItem.add(integralGoods);
         }
 
-        if(user.getIntegral() < totalIntegral){
+        if (user.getIntegral() < totalIntegral) {
             return R.error("积分不足");
         }
 
-        return createOrder(user, address, totalIntegral, totalCash, goodsItem, null, null,null);
+        return createOrder(user, address, totalIntegral, totalCash, goodsItem, null, null, null);
     }
 
     @Override
     public String importProductDeliver(List<FsStoreProductDeliverExcelVO> list) {
-        if (StringUtils.isNull(list) || list.size() == 0)
-        {
+        if (StringUtils.isNull(list) || list.size() == 0) {
             throw new ServiceException("导入商品数据不能为空!");
         }
         int successNum = 0;
         int failureNum = 0;
         StringBuilder successMsg = new StringBuilder();
         StringBuilder failureMsg = new StringBuilder();
-        for (FsStoreProductDeliverExcelVO vo : list)
-        {
-            try
-            {
+        for (FsStoreProductDeliverExcelVO vo : list) {
+            try {
                 FsIntegralOrder o = fsIntegralOrderMapper.selectFsIntegralOrderByOrderCode(vo.getOrderCode());
-                if (o==null){
-                throw new CustomException("没有此订单");
+                if (o == null) {
+                    throw new CustomException("没有此订单");
                 }
-                if (o.getStatus()!=1){
+                if (o.getStatus() != 1) {
                     throw new CustomException("订单状态不为待发货");
                 }
                 // 判断每个字段是否为null或为空字符串
@@ -601,22 +597,17 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 successNum++;
                 successMsg.append("<br/>" + successNum + "、订单编号 " + vo.getOrderCode() + " 导入成功");
 
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
 
                 failureNum++;
-                String msg = "<br/>" + failureNum + "、订单编号 " + vo.getOrderCode()  + " 导入失败:";
+                String msg = "<br/>" + failureNum + "、订单编号 " + vo.getOrderCode() + " 导入失败:";
                 failureMsg.append(msg + e.getMessage());
             }
         }
-        if (failureNum > 0)
-        {
+        if (failureNum > 0) {
             failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
             throw new ServiceException(failureMsg.toString());
-        }
-        else
-        {
+        } else {
             successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
         }
         return successMsg.toString();
@@ -635,7 +626,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     public R cannelOrder(Long orderId) {
         // 取消订单
         FsIntegralOrder order = fsIntegralOrderMapper.selectFsIntegralOrderByOrderId(orderId);
-        if (!order.getStatus().equals(4)){
+        if (!order.getStatus().equals(4)) {
             return R.error("非法操作");
         }
 
@@ -643,8 +634,9 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         fsIntegralOrderMapper.updateFsIntegralOrder(order);
 
         // 还原库存
-        if (order.getItemJson().startsWith("[") && order.getItemJson().endsWith("]")){
-            List<FsIntegralGoods> goodsItem = JSONUtil.toBean(order.getItemJson(), new TypeReference<List<FsIntegralGoods>>(){}, true);
+        if (order.getItemJson().startsWith("[") && order.getItemJson().endsWith("]")) {
+            List<FsIntegralGoods> goodsItem = JSONUtil.toBean(order.getItemJson(), new TypeReference<List<FsIntegralGoods>>() {
+            }, true);
             goodsItem.forEach(goods -> fsIntegralGoodsMapper.addStock(goods.getGoodsId(), Objects.isNull(goods.getNum()) ? 1 : goods.getNum()));
         } else {
             FsIntegralGoods integralGoods = JSONUtil.toBean(order.getItemJson(), FsIntegralGoods.class);
@@ -652,8 +644,8 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         }
 
         // 还原积分
-        FsUser user=fsUserMapper.selectFsUserByUserId(order.getUserId());
-        FsUser userMap=new FsUser();
+        FsUser user = fsUserMapper.selectFsUserByUserId(order.getUserId());
+        FsUser userMap = new FsUser();
         userMap.setUserId(user.getUserId());
         userMap.setIntegral(user.getIntegral() + Long.parseLong(order.getIntegral()));
         fsUserMapper.updateFsUser(userMap);
@@ -676,7 +668,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     public R payment(FsIntegralOrderDoPayParam param, PaymentMethodEnum paymentMethod) {
         FsIntegralOrder order = fsIntegralOrderMapper.selectFsIntegralOrderByOrderId(param.getOrderId());
         if (Objects.isNull(order) || !order.getStatus().equals(4)
-                || order.getPayMoney().compareTo(BigDecimal.ZERO) <= 0){
+                || order.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
             return R.error("非法操作");
         }
 
@@ -706,7 +698,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public R payConfirm(String orderSn, String payCode, String tradeNo, String payType, int type,String bankTransactionId,String bankSerialNo){
+    public R payConfirm(String orderSn, String payCode, String tradeNo, String payType, int type, String bankTransactionId, String bankSerialNo) {
         log.info("进入积分商城订单支付回调 orderSn: {}, payCode: {}, tradeNo: {}, payType: {}, type: {}",
                 orderSn, payCode, tradeNo, payType, type);
         FsIntegralOrder order = null;
@@ -717,7 +709,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 return R.error("支付单号不存在");
             }
 
-            if(storePayment.getStatus() == 0){
+            if (storePayment.getStatus() == 0) {
                 FsStorePayment paymentMap = new FsStorePayment();
                 paymentMap.setPaymentId(storePayment.getPaymentId());
                 paymentMap.setStatus(1);
@@ -725,13 +717,12 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 paymentMap.setTradeNo(tradeNo);
                 paymentMap.setBankSerialNo(bankSerialNo);
                 paymentMap.setBankTransactionId(bankTransactionId);
-                if(payType.equals(PayType.WECHAT_MINI_PROGRAM_PAYMENT.getCode())){
+                if (payType.equals(PayType.WECHAT_MINI_PROGRAM_PAYMENT.getCode())) {
                     paymentMap.setPayTypeCode(PayType.WECHAT_MINI_PROGRAM_PAYMENT.name());
-                }
-                else if(payType.equals(PayType.ALIPAY_BARCODE_PAYMENT.getCode())){
+                } else if (payType.equals(PayType.ALIPAY_BARCODE_PAYMENT.getCode())) {
                     paymentMap.setPayTypeCode(PayType.ALIPAY_BARCODE_PAYMENT.name());
                 }
-                if (storePayment.getPayMode().equals("yb")){
+                if (storePayment.getPayMode().equals("yb")) {
                     OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
                     orderQueryDTO.setUpOrderId(tradeNo);
                     OrderResult orderResult = ybPayService.getOrder(orderQueryDTO);
@@ -742,8 +733,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 storePaymentService.updateFsStorePayment(paymentMap);
                 order = fsIntegralOrderMapper.selectFsIntegralOrderByOrderId(Long.parseLong(storePayment.getBusinessId()));
             }
-        }
-        else if (type == 2) {
+        } else if (type == 2) {
             order = fsIntegralOrderMapper.selectFsIntegralOrderByOrderCode(orderSn);
         }
 
@@ -770,9 +760,9 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 String mpOpenId = companyUserService.selectMpOpenIdByCompanyUserId(companyUserId);
                 if (StringUtils.isNotEmpty(mpOpenId)) {
                     FsUser user = userService.selectFsUserByUserId(order.getUserId());
-                    String userName = user.getUsername() != null?user.getUsername():user.getNickName();
+                    String userName = user.getUsername() != null ? user.getUsername() : user.getNickName();
                     Date payTime = Date.from(order.getPayTime().atZone(ZoneId.systemDefault()).toInstant());
-                    wechatApi.sendTemplateMessage(wechatApi.getAccessToken(), mpOpenId,payTime,userName,order.getPayMoney(),order.getOrderCode());
+                    wechatApi.sendTemplateMessage(wechatApi.getAccessToken(), mpOpenId, payTime, userName, order.getPayMoney(), order.getOrderCode());
                     log.info("支付成功模板消息已发送给销售: {}", companyUserId);
                 } else {
                     log.warn("未找到 companyUserId={} 的 openId,跳过模板消息发送", companyUserId);
@@ -808,19 +798,19 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     public int cancelOrder(String orderCode) {
         //查询订单是否存在且是否未发货
         FsIntegralOrder fsIntegralOrder = fsIntegralOrderMapper.selectFsIntegralOrderByOrderCode(orderCode);
-        if (null==fsIntegralOrder){
+        if (null == fsIntegralOrder) {
             throw new ServiceException("订单不存在");
         }
-        if (fsIntegralOrder.getStatus()!=1){
+        if (fsIntegralOrder.getStatus() != 1) {
             throw new ServiceException("订单已发货或已完成");
         }
         int i = 0;
         //修改订单状态
         i = fsIntegralOrderMapper.cancelOrder(fsIntegralOrder.getOrderId());
-        if (i>0){
+        if (i > 0) {
             //原路退回积分
             FsUser fsUser = fsUserMapper.selectFsUserByUserId(fsIntegralOrder.getUserId());
-            fsUser.setIntegral(fsUser.getIntegral()+Long.parseLong(fsIntegralOrder.getIntegral()));
+            fsUser.setIntegral(fsUser.getIntegral() + Long.parseLong(fsIntegralOrder.getIntegral()));
             i = fsUserMapper.updateFsUser(fsUser);
             //新增积分记录
             FsUserIntegralLogs fsUserIntegralLogs = new FsUserIntegralLogs();
@@ -833,28 +823,29 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             fsUserIntegralLogs.setStatus(0);
             i = fsUserIntegralLogsMapper.insertFsUserIntegralLogs(fsUserIntegralLogs);
             //还原库存
-            if (fsIntegralOrder.getItemJson().startsWith("[") && fsIntegralOrder.getItemJson().endsWith("]")){
-                List<FsIntegralGoods> goodsItem = JSONUtil.toBean(fsIntegralOrder.getItemJson(), new TypeReference<List<FsIntegralGoods>>(){}, true);
+            if (fsIntegralOrder.getItemJson().startsWith("[") && fsIntegralOrder.getItemJson().endsWith("]")) {
+                List<FsIntegralGoods> goodsItem = JSONUtil.toBean(fsIntegralOrder.getItemJson(), new TypeReference<List<FsIntegralGoods>>() {
+                }, true);
                 goodsItem.forEach(goods -> fsIntegralGoodsMapper.addStock(goods.getGoodsId(), Objects.isNull(goods.getNum()) ? 1 : goods.getNum()));
             } else {
                 FsIntegralGoods integralGoods = JSONUtil.toBean(fsIntegralOrder.getItemJson(), FsIntegralGoods.class);
                 fsIntegralGoodsMapper.addStock(integralGoods.getGoodsId(), Objects.isNull(integralGoods.getNum()) ? 1 : integralGoods.getNum());
             }
             //还原金额
-            List<FsStorePayment> payments = storePaymentMapper.selectFsStorePaymentByPay(6,fsIntegralOrder.getOrderId());
-            if(payments!=null&&payments.size()==1){
-                FsStorePayment payment=payments.get(0);
+            List<FsStorePayment> payments = storePaymentMapper.selectFsStorePaymentByPay(6, fsIntegralOrder.getOrderId());
+            if (payments != null && payments.size() == 1) {
+                FsStorePayment payment = payments.get(0);
                 V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                 request.setOrdAmt(payment.getPayMoney().toString());
                 request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setReqSeqId("refund-"+payment.getPayCode());
+                request.setReqSeqId("refund-" + payment.getPayCode());
                 Map<String, Object> extendInfoMap = new HashMap<>();
-                extendInfoMap.put("org_req_seq_id", "integral-"+payment.getPayCode());
+                extendInfoMap.put("org_req_seq_id", "integral-" + payment.getPayCode());
                 request.setExtendInfo(extendInfoMap);
                 HuiFuRefundResult refund = huiFuService.refund(request);
-                logger.info("积分退款返回结果:积分订单id:"+fsIntegralOrder.getOrderId()+refund);
-                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
-                    FsStorePayment paymentMap=new FsStorePayment();
+                logger.info("积分退款返回结果:积分订单id:" + fsIntegralOrder.getOrderId() + refund);
+                if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {
+                    FsStorePayment paymentMap = new FsStorePayment();
                     paymentMap.setPaymentId(payment.getPaymentId());
                     paymentMap.setStatus(-1);
                     paymentMap.setRefundTime(DateUtils.getNowDate());
@@ -880,7 +871,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     public int mandatoryRefunds(String orderCode) {
         //查询订单是否存在且是否未发货
         FsIntegralOrder fsIntegralOrder = fsIntegralOrderMapper.selectFsIntegralOrderByOrderCode(orderCode);
-        if (null==fsIntegralOrder){
+        if (null == fsIntegralOrder) {
             throw new ServiceException("订单不存在");
         }
         //用户说自己去对接物流,不必校验是否发货。
@@ -890,10 +881,10 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         int i = 0;
         //修改订单状态
         i = fsIntegralOrderMapper.cancelOrder(fsIntegralOrder.getOrderId());
-        if (i>0){
+        if (i > 0) {
             //原路退回积分
             FsUser fsUser = fsUserMapper.selectFsUserByUserId(fsIntegralOrder.getUserId());
-            fsUser.setIntegral(fsUser.getIntegral()+Long.parseLong(fsIntegralOrder.getIntegral()));
+            fsUser.setIntegral(fsUser.getIntegral() + Long.parseLong(fsIntegralOrder.getIntegral()));
             i = fsUserMapper.updateFsUser(fsUser);
             //新增积分记录
             FsUserIntegralLogs fsUserIntegralLogs = new FsUserIntegralLogs();
@@ -906,28 +897,29 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             fsUserIntegralLogs.setStatus(0);
             i = fsUserIntegralLogsMapper.insertFsUserIntegralLogs(fsUserIntegralLogs);
             //还原库存
-            if (fsIntegralOrder.getItemJson().startsWith("[") && fsIntegralOrder.getItemJson().endsWith("]")){
-                List<FsIntegralGoods> goodsItem = JSONUtil.toBean(fsIntegralOrder.getItemJson(), new TypeReference<List<FsIntegralGoods>>(){}, true);
+            if (fsIntegralOrder.getItemJson().startsWith("[") && fsIntegralOrder.getItemJson().endsWith("]")) {
+                List<FsIntegralGoods> goodsItem = JSONUtil.toBean(fsIntegralOrder.getItemJson(), new TypeReference<List<FsIntegralGoods>>() {
+                }, true);
                 goodsItem.forEach(goods -> fsIntegralGoodsMapper.addStock(goods.getGoodsId(), Objects.isNull(goods.getNum()) ? 1 : goods.getNum()));
             } else {
                 FsIntegralGoods integralGoods = JSONUtil.toBean(fsIntegralOrder.getItemJson(), FsIntegralGoods.class);
                 fsIntegralGoodsMapper.addStock(integralGoods.getGoodsId(), Objects.isNull(integralGoods.getNum()) ? 1 : integralGoods.getNum());
             }
             //还原金额
-            List<FsStorePayment> payments = storePaymentMapper.selectFsStorePaymentByPay(6,fsIntegralOrder.getOrderId());
-            if(payments!=null&&payments.size()==1){
-                FsStorePayment payment=payments.get(0);
+            List<FsStorePayment> payments = storePaymentMapper.selectFsStorePaymentByPay(6, fsIntegralOrder.getOrderId());
+            if (payments != null && payments.size() == 1) {
+                FsStorePayment payment = payments.get(0);
                 V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                 request.setOrdAmt(payment.getPayMoney().toString());
                 request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setReqSeqId("refund-"+payment.getPayCode());
+                request.setReqSeqId("refund-" + payment.getPayCode());
                 Map<String, Object> extendInfoMap = new HashMap<>();
-                extendInfoMap.put("org_req_seq_id", "integral-"+payment.getPayCode());
+                extendInfoMap.put("org_req_seq_id", "integral-" + payment.getPayCode());
                 request.setExtendInfo(extendInfoMap);
                 HuiFuRefundResult refund = huiFuService.refund(request);
-                logger.info("积分退款返回结果:积分订单id:"+fsIntegralOrder.getOrderId()+refund);
-                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
-                    FsStorePayment paymentMap=new FsStorePayment();
+                logger.info("积分退款返回结果:积分订单id:" + fsIntegralOrder.getOrderId() + refund);
+                if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {
+                    FsStorePayment paymentMap = new FsStorePayment();
                     paymentMap.setPaymentId(payment.getPaymentId());
                     paymentMap.setStatus(-1);
                     paymentMap.setRefundTime(DateUtils.getNowDate());
@@ -952,10 +944,10 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
     public int finishOrder(String orderCode) {
         //查询订单是否存在且是否未发货
         FsIntegralOrder fsIntegralOrder = fsIntegralOrderMapper.selectFsIntegralOrderByOrderCode(orderCode);
-        if (null==fsIntegralOrder){
+        if (null == fsIntegralOrder) {
             throw new ServiceException("订单不存在");
         }
-        if (fsIntegralOrder.getStatus()!=2){
+        if (fsIntegralOrder.getStatus() != 2) {
             throw new ServiceException("订单未发货或者未支付,无法完成订单");
         }
         return fsIntegralOrderMapper.finishOrder(fsIntegralOrder.getOrderId(), fsIntegralOrder.getStatus());
@@ -1012,7 +1004,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             payments.add(payment);
 
             FsExpress express = expressService.selectFsExpressByOmsCode("YUNDA");
-            if(express!=null){
+            if (express != null) {
                 erpOrder.setExpress_code(express.getOmsCode());
                 fsIntegralOrder.setDeliveryName(express.getName());
                 fsIntegralOrder.setDeliveryCode(express.getCode());
@@ -1045,7 +1037,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             } else {
                 erpOrder.setReceiver_mobile(fsIntegralOrder.getUserPhone());
             }
-            if (StringUtils.isNotEmpty(fsIntegralOrder.getUserAddress())){
+            if (StringUtils.isNotEmpty(fsIntegralOrder.getUserAddress())) {
                 erpOrder.setReceiver_address(fsIntegralOrder.getUserAddress());
             }
 //            String[] address = fsIntegralOrder.getUserAddress().split(" ");
@@ -1179,7 +1171,8 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             if (itemJson.startsWith("[") && itemJson.endsWith("]")) {
                 // 数组格式 - 多个商品
                 List<FsIntegralGoods> goodsList = JSONUtil.toBean(itemJson,
-                        new TypeReference<List<FsIntegralGoods>>(){}, true);
+                        new TypeReference<List<FsIntegralGoods>>() {
+                        }, true);
 
                 for (FsIntegralGoods goods : goodsList) {
                     if (ObjectUtil.isNotEmpty(goods)) {
@@ -1258,13 +1251,37 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             }
         }
 
-        if (param.getPayMoney() != null) {
-            totalCash = param.getPayMoney();
+        FsUserCoupon userCoupon = null;
+        FsCoupon coupon = null;
+        BigDecimal discountPrice = BigDecimal.ZERO;
+        BigDecimal totalPrice = totalCash;
+        if (param.getCouponId() != null) {
+            coupon = fsCouponMapper.selectFsCouponByCouponId(param.getCouponId());
+            if (coupon == null) {
+                return R.error("优惠券配置不存在");
+            }
+            if (coupon.getLimitTime() != null && coupon.getLimitTime().before(new Date())) {
+                return R.error("优惠券已过期");
+            }
+            userCoupon = fsUserCouponMapper.selectByCouponIdAndUserId(param.getCouponId(), param.getUserId());
+            if (userCoupon == null) {
+                return R.error("该用户的优惠券不存在");
+            }
+            if (userCoupon.getStatus() != 0) {
+                return R.error("优惠券已使用或已过期");
+            }
+            BigDecimal couponPrice = coupon.getPrice();
+            if (couponPrice == null || couponPrice.compareTo(BigDecimal.ZERO) == 0) {
+                discountPrice = totalPrice;
+            } else {
+                discountPrice = couponPrice;
+            }
+            totalCash = totalPrice.subtract(discountPrice);
+            if (totalCash.compareTo(BigDecimal.ZERO) < 0) {
+                totalCash = BigDecimal.ZERO;
+            }
         }
 
-        Long activityId = param.getActivityId();
-
-
         for (FsIntegralGoods goods : goodsList) {
             if (fsIntegralGoodsMapper.subStock(goods.getGoodsId(), 1) <= 0) {
                 throw new CustomException("商品库存不足: " + goods.getGoodsName());
@@ -1282,18 +1299,11 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             throw new CustomException("订单生成失败,请重试");
         }
 
-        if (totalCash.compareTo(BigDecimal.ZERO) > 0) {
-            order.setPayType(totalIntegral > 0 ? 3 : 2);
-            order.setStatus(4);
-            order.setIsPay(0);
-            order.setPayMoney(totalCash);
-        } else {
-            order.setPayType(1);
-            order.setStatus(1);
-            order.setIsPay(1);
-            order.setPayTime(LocalDateTime.now());
-        }
 
+        order.setPayType(totalIntegral > 0 ? 3 : 2);
+        order.setStatus(1);
+        order.setIsPay(1);
+        order.setPayMoney(totalCash);
         order.setOrderCode(orderSn);
         order.setUserId(user.getUserId());
         if (!goodsList.isEmpty()) {
@@ -1309,6 +1319,11 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         order.setCreateTime(new Date());
         order.setCompanyUserId(param.getCompanyUserId());
         order.setCompanyId(param.getCompanyId());
+        order.setTotalPrice(totalPrice);
+        order.setDiscountPrice(discountPrice);
+        if (coupon != null) {
+            order.setCouponId(coupon.getCouponId());
+        }
 
         if (fsIntegralOrderMapper.insertFsIntegralOrder(order) > 0) {
             if (order.getPayType() != 2 && totalIntegral > 0) {
@@ -1317,7 +1332,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 userMap.setIntegral(user.getIntegral() - totalIntegral);
                 fsUserMapper.updateFsUser(userMap);
                 FsUserIntegralLogs logs = new FsUserIntegralLogs();
-                logs.setIntegral(-totalIntegral);
+                logs.setIntegral(user.getIntegral()-totalIntegral);
                 logs.setUserId(order.getUserId());
                 logs.setBalance(userMap.getIntegral());
                 logs.setLogType(5);
@@ -1325,6 +1340,15 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
                 logs.setCreateTime(new Date());
                 fsUserIntegralLogsMapper.insertFsUserIntegralLogs(logs);
             }
+            if (userCoupon != null) {
+                FsUserCoupon updateUserCoupon = new FsUserCoupon();
+                updateUserCoupon.setId(userCoupon.getId());
+                updateUserCoupon.setStatus(1);
+                updateUserCoupon.setUseTime(new Date());
+                updateUserCoupon.setBusinessId(order.getOrderId());
+                updateUserCoupon.setBusinessType(4);
+                fsUserCouponMapper.updateFsUserCoupon(updateUserCoupon);
+            }
             return R.ok("订单创建成功").put("order", order);
         } else {
             throw new CustomException("订单创建失败");

+ 136 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -169,6 +169,9 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
     @Autowired
     private FsUserWxMapper fsUserWxMapper;
 
+    @Autowired
+    private FsUserCouponMapper fsUserCouponMapper;
+
     @Autowired
     private IFsUserWxService userWxService;
 
@@ -1962,4 +1965,137 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
     public List<FsPackageOrder> selectOutTimeOrderList(Integer unPayTime) {
         return fsPackageOrderMapper.selectOutTimeOrderList(unPayTime);
     }
+
+    @Override
+    @Transactional
+    public R addPackageOrderManually(FsPackageOrderManuallyParam param) {
+        FsPatient patient = fsPatientMapper.selectFsPatientByPatientId(param.getPatientId());
+        if (patient == null) {
+            return R.error("请提交患者信息");
+        }
+        FsPackage fsPackage = fsPackageMapper.selectFsPackageByPackageId(param.getPackageId());
+        if (fsPackage == null || fsPackage.getStatus().equals(0)) {
+            return R.error("套餐已下架");
+        }
+        Integer num = fsPackage.getNum();
+        if (num != 0) {
+            int i = fsPackageMapper.selectFsPackageListByUser(param.getUserId(), fsPackage.getPackageId());
+            if (i >= num) {
+                return R.error("超过限购次数");
+            }
+        }
+
+        FsPackageOrder order = new FsPackageOrder();
+        String orderSn = OrderCodeUtils.getOrderSn();
+        if (StringUtils.isEmpty(orderSn)) {
+            return R.error("订单生成失败,请重试");
+        }
+        order.setOrderSn(orderSn);
+        order.setStoreId(fsPackage.getStoreId());
+        order.setUserId(param.getUserId());
+        order.setPackageId(param.getPackageId());
+        order.setPackageName(fsPackage.getPackageName());
+        order.setTotalPrice(fsPackage.getTotalPrice());
+        order.setIcdCode(fsPackage.getIcdCode());
+        order.setPayMoney(fsPackage.getTotalPrice());
+        order.setIsPay(1);
+        order.setPayTime(new Date());
+        order.setPackageSecondName(fsPackage.getSecondName());
+        order.setDoctorRemark(fsPackage.getDoctorRemark());
+        order.setFollowTempId(fsPackage.getFollowTempId());
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.package");
+        Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
+        Integer followRate = (Integer) config.get("followRate");
+        calendar.add(Calendar.DAY_OF_MONTH, followRate);
+        order.setFollowTime(calendar.getTime());
+        order.setFollowRate(followRate);
+        order.setPackageSubType(fsPackage.getPackageSubType());
+        order.setDays(fsPackage.getCycle());
+        order.setStatus(2);
+        order.setStartTime(new Date());
+        order.setCompanyUserId(param.getCompanyUserId());
+        if (param.getCompanyUserId() != null) {
+            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
+            if (companyUser != null) {
+                order.setDeptId(companyUser.getDeptId());
+            }
+        }
+        order.setCompanyId(param.getCompanyId());
+        Calendar c = Calendar.getInstance();
+        c.setTime(order.getStartTime());
+        c.add(Calendar.DAY_OF_MONTH, fsPackage.getCycle());
+        order.setFinishTime(c.getTime());
+        order.setFormJson("[{\"title\":\"您是否已在线下就诊,且对所购买的药品无过敏或不良反应?\",\"options\":[{\"name\":\"是,我线下就诊过\",\"value\":1,\"color\":\"green\"},{\"name\":\"无,从未就诊\",\"value\":0,\"color\":\"red\"}],\"option\":\"是,我线下就诊过\"},{\"title\":\"您是否已详细阅读药物说明,确认自己符合药物适用人群,并了解用药方法、用药禁忌等信息?\",\"options\":[{\"name\":\"是,我已充分了解\",\"value\":1,\"color\":\"green\"},{\"name\":\"否,未阅读\",\"value\":0,\"color\":\"red\"}],\"option\":\"是,我已充分了解\"}]");
+        order.setPackageJson(JSONUtil.toJsonStr(fsPackage));
+        order.setCreateTime(new Date());
+        order.setPatientJson(JSONUtil.toJsonStr(patient));
+        order.setInquiryCostPrice(fsPackage.getInquiryCostPrice());
+        order.setProductCostPrice(fsPackage.getProductCostPrice());
+        order.setTotalCostPrice(fsPackage.getTotalCostPrice());
+        order.setCycle(fsPackage.getCycle());
+        order.setCostDiscountMoney(fsPackage.getTotalCostPrice().subtract(fsPackage.getTotalPrice()));
+
+        FsUserAddress address = userAddressService.selectFsUserAddressByAddressId(param.getAddressId());
+        if (address != null) {
+            Map<String, String> myMap = new HashMap<>();
+            myMap.put("userName", address.getRealName().trim());
+            myMap.put("userPhone", address.getPhone().trim());
+            myMap.put("userAddress", address.getProvince() + " " + address.getCity() + " " + address.getDistrict() + " " + address.getDetail());
+            String addressString = JSON.toJSONString(myMap);
+            order.setAddressJson(addressString);
+        } else {
+            return R.error("地址错误");
+        }
+
+        FsUserCoupon userCoupon = null;
+        FsCoupon coupon = null;
+        if (param.getCouponId() != null) {
+            coupon = couponService.selectFsCouponByCouponId(param.getCouponId());
+            if (coupon == null) {
+                return R.error("优惠券配置不存在");
+            }
+            if (coupon.getCouponType() != 5) {
+                return R.error("优惠券类型不正确,仅支持套餐优惠券");
+            }
+            if (coupon.getLimitTime() != null && coupon.getLimitTime().before(new Date())) {
+                return R.error("优惠券已过期");
+            }
+            userCoupon = fsUserCouponMapper.selectByCouponIdAndUserId(param.getCouponId(), param.getUserId());
+            if (userCoupon == null) {
+                return R.error("该用户的优惠券不存在");
+            }
+            if (userCoupon.getStatus() != 0) {
+                return R.error("优惠券已使用或已过期");
+            }
+
+            order.setUserCouponId(param.getCouponId());
+            BigDecimal couponPrice = coupon.getPrice();
+            BigDecimal orderMoney = order.getPayMoney() != null ? order.getPayMoney() : BigDecimal.ZERO;
+            BigDecimal payMoney = orderMoney.subtract(couponPrice);
+            if (payMoney.compareTo(BigDecimal.ZERO) < 0) {
+                payMoney = BigDecimal.ZERO;
+            }
+            order.setPayMoney(orderMoney);
+            order.setPayPrice(payMoney);
+        }
+
+        if (fsPackageOrderMapper.insertFsPackageOrder(order) > 0) {
+            if (userCoupon != null) {
+                FsUserCoupon updateUserCoupon = new FsUserCoupon();
+                updateUserCoupon.setId(userCoupon.getId());
+                updateUserCoupon.setStatus(1);
+                updateUserCoupon.setUseTime(new Date());
+                updateUserCoupon.setBusinessId(order.getOrderId());
+                updateUserCoupon.setBusinessType(3);
+                userCouponService.updateFsUserCoupon(updateUserCoupon);
+            }
+            //创建普通订单
+            fsStoreOrderService.createOrderByPackageOrder(order);
+            return R.ok().put("order", order);
+        } else {
+            return R.error("创建失败");
+        }
+    }
 }

+ 66 - 2
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -619,12 +619,24 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         return fsStoreOrderMapper.selectFsFsStoreOrderLogsList(orderId);
     }
 
-
     @Override
     public int sendGoods(FsStoreOrder fsStoreOrder, String opeName) {
         FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(fsStoreOrder.getOrderId());
         if (order == null) throw new CustomException("订单不存在");
         if (order.getStatus() != 2) throw new CustomException("非法更改");
+        
+//        FsStore store = fsStoreMapper.selectFsStoreByStoreId(order.getStoreId());
+//        if (store == null) throw new CustomException("店铺不存在");
+//
+//        FsStoreOrderItem queryItem = new FsStoreOrderItem();
+//        queryItem.setOrderId(fsStoreOrder.getOrderId());
+//        List<FsStoreOrderItem> orderItems = fsStoreOrderItemMapper.selectFsStoreOrderItemList(queryItem);
+//
+//        String deliveryCheckResult = checkDeliveryPermission(store, orderItems);
+//        if (deliveryCheckResult != null) {
+//            throw new CustomException(deliveryCheckResult);
+//        }
+        
         FsStoreOrder o1 = new FsStoreOrder();
         o1.setOrderId(fsStoreOrder.getOrderId());
         o1.setStatus(3);
@@ -655,6 +667,49 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         expressService.subscribeEspress(order.getOrderCode(), fsStoreOrder.getDeliveryCode(), fsStoreOrder.getDeliverySn(), lastFourNumber);
         return i;
     }
+    
+//    private String checkDeliveryPermission(FsStore store, List<FsStoreOrderItem> orderItems) {
+//        if (orderItems == null || orderItems.isEmpty()) {
+//            return null;
+//        }
+//
+//        String storeChainBrands = store.getChainBrands();
+//        Set<String> storeAllowedBrands = new HashSet<>();
+//        if (storeChainBrands != null && !storeChainBrands.trim().isEmpty()) {
+//            String[] brands = storeChainBrands.split(",");
+//            for (String brand : brands) {
+//                storeAllowedBrands.add(brand.trim());
+//            }
+//        }
+//
+//        for (FsStoreOrderItem item : orderItems) {
+//            FsStoreProduct product = fsStoreProductMapper.selectFsStoreProductByProductId(item.getProductId());
+//            if (product == null) {
+//                continue;
+//            }
+//
+//            Integer productSourceType = product.getProductSourceType();
+//            if (productSourceType == null) {
+//                productSourceType = ProductSourceTypeEnum.SELF_STORE.getCode();
+//            }
+//
+//            if (ProductSourceTypeEnum.BIG_PACKAGE.getCode().equals(productSourceType)) {
+//                String productChainBrand = product.getChainBrand();
+//                if (productChainBrand == null || productChainBrand.trim().isEmpty()) {
+//                    return "商品【" + product.getProductName() + "】为大包品但未配置连锁品牌";
+//                }
+//                if (!storeAllowedBrands.contains(productChainBrand)) {
+//                    return "店铺无权发货大包品【" + product.getProductName() + "】,连锁品牌:" + productChainBrand;
+//                }
+//            } else if (ProductSourceTypeEnum.SELF_STORE.getCode().equals(productSourceType)) {
+//                if (!store.getStoreId().equals(product.getStoreId())) {
+//                    return "商品【" + product.getProductName() + "】为自库品,不属于当前店铺";
+//                }
+//            }
+//        }
+//
+//        return null;
+//    }
 
     @Override
     public int getGoods(Long orderId, String opeName) {
@@ -987,6 +1042,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R createOrderByPackageOrder(FsPackageOrder packageOrder) {
         if (packageOrder.getDoctorId() == null) {
             Long doctorID = iFsDoctorService.selectFsDoctorDoctorByPackage();
@@ -1140,6 +1196,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
         Integer followRate = (Integer) config.get("followRate");
         Integer FollowTempId = (Integer) config.get("oneFollowTempId");
+        if (followRate == null) {
+            followRate = 0;
+        }
+        if(FollowTempId == null){
+            FollowTempId=0;
+        }
         Long followDoctorId = fsPackageOrderMapper.selectFsPackageOrderByUserId(order.getUserId());
         if (followDoctorId != null && followDoctorId > 0) {
             order.setFollowDoctorId(followDoctorId);
@@ -1210,7 +1272,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 fsFollow.setPushStatus(1);
                 fsFollow.setWriteStatus(0);
                 FsFollowTemp fsFollowTemp = fsFollowTempMapper.selectFsFollowTempByTempId(FollowTempId + 0L);
-                fsFollow.setFormJson(fsFollowTemp.getFormJson());
+                if(fsFollowTemp!=null){
+                    fsFollow.setFormJson(fsFollowTemp.getFormJson());
+                }
                 fsFollow.setCreateTime(DateUtils.getNowDate());
                 int i = fsFollowMapper.insertFsFollow(fsFollow);
                 TemplateBean templateBean = TemplateBean.builder()

+ 177 - 32
fs-service/src/main/java/com/fs/his/service/impl/FsStoreProductServiceImpl.java

@@ -18,11 +18,15 @@ import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.DateUtils;
 import com.fs.erp.domain.ErpGoods;
+import com.fs.erp.dto.ProductQueryRequestDTO;
+import com.fs.erp.dto.ProductResponseDTO;
+import com.fs.erp.http.JstErpHttpService;
 import com.fs.erp.service.IErpGoodsService;
 import com.fs.erp.service.IErpOrderService;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.dto.FsPackagePruductDTO;
+import com.fs.his.mapper.FsPackageMapper;
 import com.fs.his.mapper.FsPackageOrderMapper;
 import com.fs.his.param.FsProductAttrValueParam;
 import com.fs.his.param.FsStoreProductAddEditParam;
@@ -65,6 +69,9 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
     @Autowired
     private FsPackageOrderMapper fsPackageOrderMapper;
 
+    @Autowired
+    private FsPackageMapper fsPackageMapper;
+
     @Autowired
     IFsPackageService fsPackageService;
     @Autowired
@@ -78,6 +85,9 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
     @Qualifier("JSTErpGoodsServiceImpl")
     private IErpGoodsService jSTErpGoodsService;
 
+    @Autowired
+    private JstErpHttpService jstErpHttpService;
+
 
 
     /**
@@ -519,20 +529,20 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
 
             //todo 添加商品HzOMSerp调用
             //判断是否开启erp
-            if (erpOpen == null || erpOpen == 0) {
-                //不作操作
-            } else {
-                //判断erp类型
-                Integer erpType = sysConfig.getErpType();
-                if (erpType == null) {
-                    //不作操作
-                } else if (erpType == 5){
-                    //聚水潭商品同步
-                    params.setProductIdList(Arrays.asList(product.getProductId()));
-                    
-                    jSTErpGoodsService.addGoods(params);
-                }
-            }
+//            if (erpOpen == null || erpOpen == 0) {
+//                //不作操作
+//            } else {
+//                //判断erp类型
+//                Integer erpType = sysConfig.getErpType();
+//                if (erpType == null) {
+//                    //不作操作
+//                } else if (erpType == 5){
+//                    //聚水潭商品同步
+//                    params.setProductIdList(Arrays.asList(product.getProductId()));
+//
+//                    jSTErpGoodsService.addGoods(params);
+//                }
+//            }
         } else {
             FsStoreProduct product = new FsStoreProduct();
             BeanUtils.copyProperties(param, product);
@@ -557,24 +567,24 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
             }
 
             //todo 添加商品HzOMSerp调用
-            //判断是否开启erp
-            if (erpOpen == null || erpOpen == 0) {
-                //不作操作
-            } else {
-                //判断erp类型
-                Integer erpType = sysConfig.getErpType();
-                if (erpType == null) {
-                    //不作操作
-                } else if (erpType == 3) {
-                    params.setStoreProductId(product.getProductId());
-                    //瀚智OMS 维护添加商品
-                    hzOMSErpGoodsService.addGoods(params);
-                }else if (erpType == 5){
-                    //聚水潭商品同步
-                    params.setProductIdList(Arrays.asList(product.getProductId()));
-                    jSTErpGoodsService.addGoods(params);
-                }
-            }
+//            //判断是否开启erp
+//            if (erpOpen == null || erpOpen == 0) {
+//                //不作操作
+//            } else {
+//                //判断erp类型
+//                Integer erpType = sysConfig.getErpType();
+//                if (erpType == null) {
+//                    //不作操作
+//                } else if (erpType == 3) {
+//                    params.setStoreProductId(product.getProductId());
+//                    //瀚智OMS 维护添加商品
+//                    hzOMSErpGoodsService.addGoods(params);
+//                }else if (erpType == 5){
+//                    //聚水潭商品同步
+//                    params.setProductIdList(Arrays.asList(product.getProductId()));
+//                    jSTErpGoodsService.addGoods(params);
+//                }
+//            }
         }
         return R.ok();
     }
@@ -878,4 +888,139 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService {
     public List<FsStoreProductListVO> liveList(LiveGoods liveId) {
         return fsStoreProductMapper.liveList(liveId);
     }
+
+    /**
+     * 批量获取商品编码 获取erp商品信息更新商品及属性等信息
+     * @return
+     */
+    @Override
+    public int updateStoreProductByErpProductCode() {
+        List<FsStoreProduct> productList = fsStoreProductMapper.selectFsStoreProductList(new FsStoreProduct());
+        if (productList == null || productList.isEmpty()) {
+            return 0;
+        }
+        
+        List<String> barCodes = productList.stream()
+                .filter(p -> StringUtils.isNotBlank(p.getBarCode()))
+                .map(FsStoreProduct::getBarCode)
+                .distinct()
+                .collect(Collectors.toList());
+        
+        if (barCodes.isEmpty()) {
+            return 0;
+        }
+        
+        Map<String, FsStoreProduct> productMap = productList.stream()
+                .filter(p -> StringUtils.isNotBlank(p.getBarCode()))
+                .collect(Collectors.toMap(FsStoreProduct::getBarCode, p -> p, (a, b) -> a));
+        
+        int updateCount = 0;
+        int batchSize = 20;
+        
+        for (int i = 0; i < barCodes.size(); i += batchSize) {
+            int endIndex = Math.min(i + batchSize, barCodes.size());
+            List<String> batchBarCodes = barCodes.subList(i, endIndex);
+            
+            ProductQueryRequestDTO queryDTO = new ProductQueryRequestDTO();
+            queryDTO.setSkuIds(String.join(",", batchBarCodes));
+            queryDTO.setPageIndex(1);
+            queryDTO.setPageSize(batchSize);
+            
+            try {
+                ProductResponseDTO response = jstErpHttpService.queryGoods(queryDTO);
+                if (response == null || response.getDatas() == null || response.getDatas().isEmpty()) {
+                    continue;
+                }
+                
+                for (ProductResponseDTO.ProductInfo erpProduct : response.getDatas()) {
+                    String skuId = erpProduct.getSkuId();
+                    FsStoreProduct product = productMap.get(skuId);
+                    if (product == null) {
+                        continue;
+                    }
+                    
+                    FsStoreProduct updateProduct = new FsStoreProduct();
+                    updateProduct.setProductId(product.getProductId());
+                    updateProduct.setProductName(erpProduct.getName());
+                    updateProduct.setPrice(erpProduct.getSalePrice());
+                    updateProduct.setCostPrice(erpProduct.getCostPrice());
+                    updateProduct.setOtPrice(erpProduct.getMarketPrice());
+                    updateProduct.setImgUrl(erpProduct.getPic());
+                    updateProduct.setUnitName(erpProduct.getUnit());
+                    updateProduct.setBrand(erpProduct.getBrand());
+                    updateProduct.setPrescribeSpec(erpProduct.getPropertiesValue());
+                    updateProduct.setPrescribeFactory(erpProduct.getSupplierName());
+                    
+                    fsStoreProductMapper.updateFsStoreProduct(updateProduct);
+                    updateCount++;
+                    
+                    FsStoreProductAttrValue attrQuery = new FsStoreProductAttrValue();
+                    attrQuery.setProductId(product.getProductId());
+                    attrQuery.setBarCode(skuId);
+                    List<FsStoreProductAttrValue> attrList = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueList(attrQuery);
+                    
+                    if (attrList != null && !attrList.isEmpty()) {
+                        for (FsStoreProductAttrValue attr : attrList) {
+                            FsStoreProductAttrValue updateAttr = new FsStoreProductAttrValue();
+                            updateAttr.setId(attr.getId());
+                            updateAttr.setPrice(erpProduct.getSalePrice());
+                            updateAttr.setCost(erpProduct.getCostPrice());
+                            updateAttr.setOtPrice(erpProduct.getMarketPrice());
+                            updateAttr.setImage(erpProduct.getPic());
+                            updateAttr.setWeight(erpProduct.getWeight());
+                            
+                            fsStoreProductAttrValueMapper.updateFsStoreProductAttrValue(updateAttr);
+                        }
+                    }
+                    
+                    updatePackageProductJson(product.getProductId(), erpProduct);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        
+        return updateCount;
+    }
+    
+    private void updatePackageProductJson(Long productId, ProductResponseDTO.ProductInfo erpProduct) {
+        List<FsPackage> packageList = fsPackageOrderMapper.selectFsPackageOrderListByProd(String.valueOf(productId));
+        if (packageList == null || packageList.isEmpty()) {
+            return;
+        }
+        
+        for (FsPackage fsPackage : packageList) {
+            String productJson = fsPackage.getProductJson();
+            if (StringUtils.isBlank(productJson)) {
+                continue;
+            }
+            
+            try {
+                JSONArray jsonArray = JSONUtil.parseArray(productJson);
+                List<FsPackagePruductDTO> productList = JSONUtil.toList(jsonArray, FsPackagePruductDTO.class);
+                boolean updated = false;
+                
+                for (FsPackagePruductDTO dto : productList) {
+                    if (productId.equals(dto.getProductId())) {
+                        dto.setProductName(erpProduct.getName());
+                        dto.setPrice(erpProduct.getSalePrice());
+                        dto.setOtPrice(erpProduct.getMarketPrice());
+                        dto.setCostPrice(erpProduct.getCostPrice());
+                        dto.setPrescribeSpec(erpProduct.getPropertiesValue());
+                        dto.setImage(erpProduct.getPic());
+                        updated = true;
+                    }
+                }
+                
+                if (updated) {
+                    FsPackage updatePackage = new FsPackage();
+                    updatePackage.setPackageId(fsPackage.getPackageId());
+                    updatePackage.setProductJson(JSONUtil.toJsonStr(productList));
+                    fsPackageMapper.updateFsPackage(updatePackage);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -2424,4 +2424,12 @@ public class FsUserServiceImpl implements IFsUserService {
         }
     }
 
+    /**
+     * 查询外部用户列表(isExternal = 0)
+     */
+    @Override
+    public List<FsUserVO> selectExternalUserList(FsUserParam fsUser) {
+        return fsUserMapper.selectExternalUserList(fsUser);
+    }
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/his/vo/FsDoctorListVO.java

@@ -124,6 +124,11 @@ public class FsDoctorListVO {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
+    /**
+     * 价格配置
+     */
+    private String priceJson;
+
     private Integer isPrescribeDoctor;
 
     private Long   prescribeDoctorId;

+ 5 - 0
fs-service/src/main/java/com/fs/im/service/OpenIMService.java

@@ -97,4 +97,9 @@ public interface OpenIMService {
 
     OpenImResponseDTO doctorSendMsgToUser(Long userId,Long doctorId);
 
+    /**
+     * 获取指定用户的好友列表循环删除好友
+     */
+    void deleteAllFriends();
+
 }

+ 102 - 1
fs-service/src/main/java/com/fs/im/service/impl/OpenIMServiceImpl.java

@@ -61,7 +61,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 @Service
@@ -1707,4 +1708,104 @@ public class OpenIMServiceImpl implements OpenIMService {
         openImMsgDTO.setContent(content);
         return openIMSendMsg(openImMsgDTO);
     }
+
+    /**
+     * 获取指定用户的好友列表循环删除好友
+     */
+    @Override
+    public void deleteAllFriends() {
+        String userId = "C10418";
+        String adminToken = getAdminToken();
+        
+        int pageNumber = 1;
+        int showNumber = 100;
+        AtomicInteger totalDeleted = new AtomicInteger(0);
+        AtomicInteger totalFailed = new AtomicInteger(0);
+        
+        ExecutorService executorService = Executors.newFixedThreadPool(10);
+        List<Future<?>> futures = new ArrayList<>();
+        
+        while (true) {
+            JSONObject requestJson = new JSONObject();
+            requestJson.put("userID", userId);
+            JSONObject pagination = new JSONObject();
+            pagination.put("pageNumber", pageNumber);
+            pagination.put("showNumber", showNumber);
+            requestJson.put("pagination", pagination);
+            
+            String body = HttpRequest.post(IMConfig.URL + "/friend/get_friend_list")
+                    .header("operationID", String.valueOf(System.currentTimeMillis()))
+                    .header("token", adminToken)
+                    .body(requestJson.toString())
+                    .execute()
+                    .body();
+            
+            OpenImResponseDTO response = JSONUtil.toBean(body, OpenImResponseDTO.class);
+            if (response.getErrCode() != 0 || response.getData() == null) {
+                log.error("获取好友列表失败: {}", response.getErrMsg());
+                break;
+            }
+            
+            cn.hutool.json.JSONObject dataObj = JSONUtil.parseObj(response.getData());
+            cn.hutool.json.JSONArray friendsInfo = dataObj.getJSONArray("friendsInfo");
+            
+            if (friendsInfo == null || friendsInfo.isEmpty()) {
+                log.info("没有更多好友了,删除完成");
+                break;
+            }
+            
+            for (int i = 0; i < friendsInfo.size(); i++) {
+                cn.hutool.json.JSONObject friendObj = friendsInfo.getJSONObject(i);
+                cn.hutool.json.JSONObject friendUser = friendObj.getJSONObject("friendUser");
+                String friendUserId = friendUser.getStr("userID");
+                
+                Future<?> future = executorService.submit(() -> {
+                    try {
+                        JSONObject deleteJson = new JSONObject();
+                        deleteJson.put("ownerUserID", userId);
+                        deleteJson.put("friendUserID", friendUserId);
+                        
+                        String deleteBody = HttpRequest.post(IMConfig.URL + "/friend/delete_friend")
+                                .header("operationID", String.valueOf(System.currentTimeMillis()))
+                                .header("token", adminToken)
+                                .body(deleteJson.toString())
+                                .execute()
+                                .body();
+                        
+                        OpenImResponseDTO deleteResponse = JSONUtil.toBean(deleteBody, OpenImResponseDTO.class);
+                        if (deleteResponse.getErrCode() == 0) {
+                            totalDeleted.incrementAndGet();
+                            log.info("删除好友成功: {}", friendUserId);
+                        } else {
+                            totalFailed.incrementAndGet();
+                            log.error("删除好友失败: {}, 错误: {}", friendUserId, deleteResponse.getErrMsg());
+                        }
+                    } catch (Exception e) {
+                        totalFailed.incrementAndGet();
+                        log.error("删除好友异常: {}", friendUserId, e);
+                    }
+                });
+                futures.add(future);
+            }
+            
+            if (friendsInfo.size() < showNumber) {
+                log.info("已处理完所有好友,删除完成");
+                break;
+            }
+            
+            pageNumber++;
+        }
+        
+        for (Future<?> future : futures) {
+            try {
+                future.get();
+            } catch (Exception e) {
+                log.error("等待删除任务完成异常", e);
+            }
+        }
+        
+        executorService.shutdown();
+        
+        log.info("删除完成 - 成功: {}, 失败: {}", totalDeleted.get(), totalFailed.get());
+    }
 }

+ 13 - 1
fs-service/src/main/resources/mapper/his/FsIntegralOrderMapper.xml

@@ -26,10 +26,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="remark"    column="remark"    />
         <result property="barCode"    column="bar_code"    />
         <result property="loginAccount"    column="login_account"    />
+        <result property="couponId"    column="coupon_id"    />
+        <result property="totalPrice"    column="total_price"    />
+        <result property="discountPrice"    column="discount_price"    />
     </resultMap>
 
     <sql id="selectFsIntegralOrderVo">
-        select order_id, order_code, user_id,bar_code, user_name, user_phone, user_address, item_json, integral,pay_money,is_pay,pay_time,pay_type, status, delivery_code, delivery_name, delivery_sn, delivery_time, create_time,qw_user_id,company_user_id,company_id,remark,login_account from fs_integral_order
+        select order_id, order_code, user_id,bar_code, user_name, user_phone, user_address, item_json, integral,pay_money,is_pay,pay_time,pay_type, status, delivery_code, delivery_name, delivery_sn, delivery_time, create_time,qw_user_id,company_user_id,company_id,remark,login_account,coupon_id,total_price,discount_price from fs_integral_order
     </sql>
 
     <select id="selectFsIntegralOrderList" parameterType="FsIntegralOrder" resultMap="FsIntegralOrderResult">
@@ -87,6 +90,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="qwUserId != null">qw_user_id,</if>
             <if test="companyUserId != null">company_user_id,</if>
             <if test="companyId != null">company_id,</if>
+            <if test="couponId != null">coupon_id,</if>
+            <if test="totalPrice != null">total_price,</if>
+            <if test="discountPrice != null">discount_price,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="orderId != null">#{orderId},</if>
@@ -112,6 +118,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="qwUserId != null">#{qwUserId},</if>
             <if test="companyUserId != null">#{companyUserId},</if>
             <if test="companyId != null">#{companyId},</if>
+            <if test="couponId != null">#{couponId},</if>
+            <if test="totalPrice != null">#{totalPrice},</if>
+            <if test="discountPrice != null">#{discountPrice},</if>
          </trim>
     </insert>
 
@@ -138,6 +147,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remark != null">remark = #{remark},</if>
             <if test="barCode != null">bar_code = #{barCode},</if>
             <if test="loginAccount != '' and loginAccount != null">login_account = #{loginAccount},</if>
+            <if test="couponId != null">coupon_id = #{couponId},</if>
+            <if test="totalPrice != null">total_price = #{totalPrice},</if>
+            <if test="discountPrice != null">discount_price = #{discountPrice},</if>
         </trim>
         where order_id = #{orderId}
     </update>

+ 27 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -55,6 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="totalCommission"    column="total_commission"    />
         <result property="mayWithdraw"    column="may_withdraw"    />
         <result property="appCreateTime"    column="app_create_time"    />
+        <result property="isExternal"    column="is_external"    />
     </resultMap>
 
     <sql id="selectFsUserVo">
@@ -654,6 +655,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="spreadCount != null">spread_count,</if>
             <if test="appId != null">app_id,</if>
             <if test="appCreateTime != null">app_create_time,</if>
+            <if test="isExternal != null">is_external,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="nickName != null">#{nickName},</if>
@@ -705,6 +707,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="spreadCount != null">#{spreadCount},</if>
             <if test="appId != null">#{appId},</if>
             <if test="appCreateTime != null">#{appCreateTime},</if>
+            <if test="isExternal != null">#{isExternal},</if>
          </trim>
     </insert>
 
@@ -771,6 +774,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="withdrawFinish != null">withdraw_finish = #{withdrawFinish},</if>
             <if test="totalCommission != null">total_commission = #{totalCommission},</if>
             <if test="mayWithdraw != null">may_withdraw = #{mayWithdraw},</if>
+            <if test="isExternal != null">is_external = #{isExternal},</if>
         </trim>
         where user_id = #{userId}
     </update>
@@ -2654,4 +2658,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT user_id,integral, withdraw_integral, total_commission, withdraw_finish,may_withdraw FROM fs_user WHERE user_id = #{userId}
     </select>
 
+    <select id="selectExternalUserList" parameterType="com.fs.his.param.FsUserParam" resultType="com.fs.his.vo.FsUserVO">
+        SELECT
+            fu.user_id,
+            fu.nick_name,
+            fu.avatar,
+            fu.phone,
+            fu.status,
+            fu.source,
+            fu.login_device as loginDevice,
+            fu.app_create_time as appCreateTime,
+            fu.create_time as createTime
+        FROM fs_user fu
+        WHERE fu.is_external = 0
+          AND fu.is_del = 0
+        <if test="nickName != null and nickName != ''">
+            AND fu.nick_name LIKE CONCAT('%', #{nickName}, '%')
+        </if>
+        <if test="phone != null and phone != ''">
+            AND fu.phone LIKE CONCAT('%', #{phone}, '%')
+        </if>
+        ORDER BY fu.user_id DESC
+    </select>
+
 </mapper>