浏览代码

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

15376779826 6 天之前
父节点
当前提交
3163559565
共有 46 个文件被更改,包括 1015 次插入105 次删除
  1. 2 1
      fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java
  2. 40 2
      fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java
  3. 28 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  4. 2 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  5. 6 1
      fs-company/src/main/java/com/fs/company/controller/crm/CrmMsgController.java
  6. 6 5
      fs-company/src/main/java/com/fs/company/controller/store/FsInquiryOrderController.java
  7. 14 1
      fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java
  8. 1 1
      fs-company/src/main/java/com/fs/company/controller/store/FsStoreOrderController.java
  9. 5 2
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  10. 1 1
      fs-service/src/main/java/com/fs/aiTongueApi/config/AiTongueConfig.java
  11. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseFinishTempServiceImpl.java
  12. 1 0
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  13. 5 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  14. 1 2
      fs-service/src/main/java/com/fs/course/service/impl/FsUserWatchStatisticsServiceImpl.java
  15. 1 1
      fs-service/src/main/java/com/fs/erp/http/JstErpHttpServiceImpl.java
  16. 9 7
      fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java
  17. 19 0
      fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  18. 4 0
      fs-service/src/main/java/com/fs/his/config/StoreConfig.java
  19. 4 3
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  20. 6 1
      fs-service/src/main/java/com/fs/his/enums/FsStoreOrderLogEnum.java
  21. 10 1
      fs-service/src/main/java/com/fs/his/mapper/FsPackageOrderMapper.java
  22. 5 0
      fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java
  23. 1 0
      fs-service/src/main/java/com/fs/his/param/FsStoreOrderSetErpPhoneParam.java
  24. 2 0
      fs-service/src/main/java/com/fs/his/service/IFsInquiryOrderService.java
  25. 2 1
      fs-service/src/main/java/com/fs/his/service/IFsPackageOrderService.java
  26. 5 0
      fs-service/src/main/java/com/fs/his/service/IFsStoreOrderService.java
  27. 47 0
      fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java
  28. 46 2
      fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java
  29. 2 0
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java
  30. 18 1
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  31. 143 0
      fs-service/src/main/java/com/fs/his/utils/IdCardUtil.java
  32. 14 0
      fs-service/src/main/java/com/fs/his/vo/FsStoreOrderListAndStatisticsVo.java
  33. 1 1
      fs-service/src/main/java/com/fs/qw/domain/QwUserVoiceLog.java
  34. 2 2
      fs-service/src/main/java/com/fs/qw/mapper/QwCourseFinishRemarkRtyMapper.java
  35. 1 1
      fs-service/src/main/java/com/fs/qw/service/IQwUserVoiceLogService.java
  36. 68 44
      fs-service/src/main/java/com/fs/qw/service/impl/QwUserVoiceLogServiceImpl.java
  37. 1 1
      fs-service/src/main/java/com/fs/qw/vo/QwUserVoiceLogVo.java
  38. 2 2
      fs-service/src/main/resources/application-config-druid-syysy.yml
  39. 1 1
      fs-service/src/main/resources/application-druid-jnmy-test.yml
  40. 9 6
      fs-service/src/main/resources/application-druid-jnmy.yml
  41. 1 1
      fs-service/src/main/resources/mapper/course/FsCourseLinkMapper.xml
  42. 392 0
      fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml
  43. 1 1
      fs-service/src/main/resources/mapper/store/FsUserCourseCountMapper.xml
  44. 1 0
      fs-store/src/main/java/com/fs/store/controller/store/FsStoreOrderController.java
  45. 82 9
      fs-user-app/src/main/java/com/fs/app/controller/PatientController.java
  46. 2 2
      fs-user-app/src/main/resources/application.yml

+ 2 - 1
fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java

@@ -193,7 +193,8 @@ public class FsPackageOrderController extends BaseController
     @GetMapping("storeRefund/{orderId}")
     public AjaxResult storeRefund(@PathVariable("orderId") Long orderId)
     {
-        return AjaxResult.success(fsPackageOrderService.PackageStoreOrderRefund(orderId));
+        String nickName = getLoginUser().getUser().getNickName();
+        return AjaxResult.success(fsPackageOrderService.PackageStoreOrderRefund(orderId,nickName));
     }
 
     /**

+ 40 - 2
fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java

@@ -1,9 +1,11 @@
 package com.fs.his.controller;
 
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import cn.hutool.core.util.StrUtil;
@@ -35,6 +37,7 @@ import com.fs.his.domain.*;
 import com.fs.his.dto.ExpressInfoDTO;
 import com.fs.his.dto.StoreOrderExpressExportDTO;
 import com.fs.his.dto.TracesDTO;
+import com.fs.his.enums.FsStoreOrderLogEnum;
 import com.fs.his.enums.ShipperCodeEnum;
 import com.fs.his.param.FsFollowMsgParam;
 import com.fs.his.param.FsStoreOrderParam;
@@ -48,6 +51,7 @@ import com.fs.system.mapper.SysConfigMapper;
 import com.fs.system.service.ISysRoleService;
 import com.github.pagehelper.PageHelper;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -120,11 +124,14 @@ public class FsStoreOrderController extends BaseController
 
     @Autowired
     private CloudHostProper cloudHostProper;
+
+    @Autowired
+    private IFsStoreOrderLogsService fsStoreOrderLogsService;
     /**
      * 查询订单列表
      */
     @PostMapping("/list")
-    public TableDataInfo list(@RequestBody FsStoreOrderParam fsStoreOrder)
+    public FsStoreOrderListAndStatisticsVo list(@RequestBody FsStoreOrderParam fsStoreOrder)
     {
         PageHelper.startPage(fsStoreOrder);
         if (fsStoreOrder.getUserPhoneMk()!=null&& !fsStoreOrder.getUserPhoneMk().isEmpty()){
@@ -151,7 +158,29 @@ public class FsStoreOrderController extends BaseController
             }
             dataTable.setMsg("jnmy");
         }
-        return dataTable;
+        FsStoreOrderListAndStatisticsVo vo = new FsStoreOrderListAndStatisticsVo();
+        BeanUtils.copyProperties(dataTable, vo);
+        if (dataTable.getTotal()>0){
+            Map<String,BigDecimal> statistics= fsStoreOrderService.selectFsStoreOrderStatistics(fsStoreOrder);
+            if (statistics != null && statistics.size() >= 3){
+                vo.setPayPriceTotal(statistics.get("pay_price").toString());
+                vo.setPayMoneyTotal(statistics.get("pay_money").toString());
+                vo.setPayRemainTotal(statistics.get("pay_remain").toString());
+            }else {
+                vo.setPayPriceTotal("0");
+                vo.setPayMoneyTotal("0");
+                vo.setPayRemainTotal("0");
+            }
+            //商品数量合计
+            String productStatistics= fsStoreOrderService.selectFsStoreOrderProductStatistics(fsStoreOrder);
+            if (StringUtils.isNotBlank(productStatistics)){
+                vo.setProductInfo(productStatistics);
+            } else {
+                vo.setProductInfo("");
+            }
+
+        }
+        return vo;
     }
 
     /**
@@ -598,6 +627,7 @@ public class FsStoreOrderController extends BaseController
     @PostMapping(value = "/batchCreateErpOrder")
     public R batchCreateErpOrder(@RequestBody FsStoreOrderSetErpPhoneParam param)
     {
+        String nickName = getLoginUser().getUser().getNickName();
         String loginAccount = param.getLoginAccount();
         if (StringUtils.isBlank(loginAccount)){
             return R.error("未选择推送erp账户");
@@ -629,8 +659,12 @@ public class FsStoreOrderController extends BaseController
                 FsStoreOrderDf temp = fsStoreOrderDfService.selectFsStoreOrderDfByOrderId(df.getOrderId());
                 if (temp == null){
                     fsStoreOrderDfService.insertFsStoreOrderDf(df);
+                    fsStoreOrderLogsService.create(orderId, FsStoreOrderLogEnum.SET_PUSH_ACCOUNT.getValue(),
+                            nickName + " " +FsStoreOrderLogEnum.SET_PUSH_ACCOUNT.getDesc() + ":" + df.getLoginAccount());
                 }
                 fsStoreOrderService.createOmsOrder(orderId);
+                fsStoreOrderLogsService.create(orderId, FsStoreOrderLogEnum.PUSH_ORDER_ERP.getValue(),
+                        nickName + " " +FsStoreOrderLogEnum.PUSH_ORDER_ERP.getDesc() + ":" + df.getLoginAccount());
             } catch (ParseException e) {
                 throw new RuntimeException(e);
             }
@@ -645,6 +679,7 @@ public class FsStoreOrderController extends BaseController
     @PostMapping(value = "/batchSetErpOrder")
     public R batchSetErpOrder(@RequestBody FsStoreOrderSetErpPhoneParam param)
     {
+        String nickName = getLoginUser().getUser().getNickName();
         String loginAccount = param.getLoginAccount();
         if (StringUtils.isBlank(loginAccount)){
             return R.error("未选择erp账户");
@@ -673,6 +708,8 @@ public class FsStoreOrderController extends BaseController
             } else {
                 fsStoreOrderDfService.insertFsStoreOrderDf(df);
             }
+            fsStoreOrderLogsService.create(orderId, FsStoreOrderLogEnum.SET_PUSH_ACCOUNT.getValue(),
+                    nickName + " " +FsStoreOrderLogEnum.SET_PUSH_ACCOUNT.getDesc() + ":" + df.getLoginAccount());
         });
         return R.ok();
     }
@@ -855,6 +892,7 @@ public class FsStoreOrderController extends BaseController
     @PostMapping("/editErpPhone")
     public AjaxResult editErpPhone(@RequestBody FsStoreOrderSetErpPhoneParam param)
     {
+        param.setOpeName(getLoginUser().getUser().getNickName());
         List<String> erpPhone = param.getErpPhone();
         if (erpPhone == null || erpPhone.isEmpty()) {
             return AjaxResult.error("请选择手机号");

+ 28 - 0
fs-admin/src/main/java/com/fs/his/controller/FsUserController.java

@@ -162,6 +162,34 @@ public class FsUserController extends BaseController
         return getDataTable(list);
     }
 
+    @PreAuthorize("@ss.hasPermi('his:user:export')")
+    @GetMapping("/exportListProject")
+    public AjaxResult exportListProject(FsUser fsUser)
+    {
+        if(StringUtils.isNotEmpty(fsUser.getPhone())){
+            fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        }
+        List<FsUserVO> list = fsUserService.selectFsUserVOListByProject(fsUser);
+        boolean checkPhone = isCheckPhone();
+        for (FsUserVO fsUserVO : list) {
+            if(fsUserVO.getPhone() != null&&fsUserVO.getPhone()!=""){
+                if (!checkPhone){
+                    if (fsUserVO.getPhone().length()>11){
+                        fsUserVO.setPhone(decryptPhoneMk(fsUserVO.getPhone()));
+                    }else {
+                        fsUserVO.setPhone(fsUserVO.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                    }
+                } else {
+                    if (fsUserVO.getPhone().length()>11) {
+                        fsUserVO.setPhone(decryptPhone(fsUserVO.getPhone()));
+                    }
+                }
+            }
+        }
+        ExcelUtil<FsUserVO> util = new ExcelUtil<FsUserVO>(FsUserVO.class);
+        return util.exportExcel(list, "项目会员数据");
+    }
+
     /**
      * 导出用户列表
      */

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

@@ -565,10 +565,12 @@ public class Task {
     public void CreateOmsAndHis()
     {
         List<Long> omsList = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
+        logger.info("推送订单id====>{}",omsList);
         for (Long l : omsList) {
             try {
                 fsStoreOrderService.createOmsOrder(l);
             } catch (Exception e) {
+                logger.error("推送订单异常:",e);
             }
         }
 //        List<Long> tuiOrderList = fsStoreOrderMapper.selectFsStoreOrderNoTuiOrder();

+ 6 - 1
fs-company/src/main/java/com/fs/company/controller/crm/CrmMsgController.java

@@ -64,7 +64,12 @@ public class CrmMsgController extends BaseController
     }
 
 
-
+    /**
+     * 获取站内销售消息列表
+     * @param request
+     * @param type
+     * @return
+     */
     @GetMapping("/getMsgList")
     public R getMsgList(
             HttpServletRequest request,

+ 6 - 5
fs-company/src/main/java/com/fs/company/controller/store/FsInquiryOrderController.java

@@ -364,16 +364,17 @@ public class FsInquiryOrderController extends BaseController
 
 
     /**
-    * 生成订单二维码
+    * 生成问诊付款二维码
     */
     @PreAuthorize("@ss.hasPermi('store:inquiryOrder:wxaCodeInquiryOrder')")
     @GetMapping("/getWxaCodeInquiryOrderUnLimit/{orderId}")
-    public AjaxResult getWxaCodeInquiryOrderUnLimit(@PathVariable("orderId") Long orderId)
+    public R getWxaCodeInquiryOrderUnLimit(@PathVariable("orderId") Long orderId)
     {
 
-        byte[] bytes = fsInquiryOrderService.getWxaCodeInquiryOrderUnLimit(orderId);
-        String base64 = Base64.getEncoder().encodeToString(bytes);
-        return AjaxResult.success("成功",base64);
+        //        byte[] bytes = fsInquiryOrderService.getWxaCodeInquiryOrderUnLimit(orderId);
+//        String base64 = Base64.getEncoder().encodeToString(bytes);
+        return fsInquiryOrderService.getWxaCodeInquiryOrderUnLimitR(orderId);
 
     }
+
 }

+ 14 - 1
fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java

@@ -235,7 +235,8 @@ public class FsPackageOrderController extends BaseController
     @GetMapping("storeRefund/{orderId}")
     public AjaxResult storeRefund(@PathVariable("orderId") Long orderId)
     {
-        return AjaxResult.success(fsPackageOrderService.PackageStoreOrderRefund(orderId));
+        String nickName = getLoginUser().getUser().getNickName();
+        return AjaxResult.success(fsPackageOrderService.PackageStoreOrderRefund(orderId,nickName));
     }
 
 
@@ -247,4 +248,16 @@ public class FsPackageOrderController extends BaseController
         String base64 = Base64.getEncoder().encodeToString(bytes);
         return AjaxResult.success("成功",base64);
     }
+
+    /**
+     * 生成套餐包付款二维码
+     */
+    @PreAuthorize("@ss.hasPermi('store:packageOrder:wxaCodePackageOrder')")
+    @GetMapping("/getWxaCodePackageOrderUnLimit/{orderId}")
+    public R getWxaCodePackageOrderUnLimit(@PathVariable("orderId") Long orderId)
+    {
+
+        return fsPackageOrderService.getWxaCodePackageOrderUnLimit(orderId);
+
+    }
 }

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

@@ -390,7 +390,7 @@ public class FsStoreOrderController extends BaseController
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
         fsStoreOrder.setCompanyId(loginUser.getCompany().getCompanyId());
-        fsStoreOrder.setOperator(loginUser.getUser().getNickName());
+        fsStoreOrder.setOperator("销售端:" + loginUser.getUser().getNickName());
         return toAjax(fsStoreOrderService.afterSales(fsStoreOrder));
     }
 

+ 5 - 2
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -330,6 +330,9 @@ public class QwMsgController {
                         WxwSpeechToTextEntityRespDTO data = dto.getData();
                         content = data.getText();
                         System.out.println("语音消息"+content);
+                        if(content == null || content.isEmpty()){
+                            content = "==语音转换失败==";
+                        }
                     }
                     else if (wxWorkMessageDTO.getMsgtype() == 101){
                         content = processImageMessage(serverId, wxWorkMessageDTO, wxWorkMsgResp);
@@ -357,7 +360,7 @@ public class QwMsgController {
                     }
                     Long receiver = wxWorkMessageDTO.getReceiver();
                     Long extId=null;
-                    Integer totalSeconds=0;
+                    Long totalSeconds=null;
                     if (2000000000000000L-receiver>0){
                          extId = wxWorkMessageDTO.getSender();
                         System.out.println("客户发起");
@@ -388,7 +391,7 @@ public class QwMsgController {
                                     minutes = Integer.parseInt(matcher.group(1));
                                     seconds = Integer.parseInt(matcher.group(2));
                                 }
-                                totalSeconds = hours * 3600 + minutes * 60 + seconds;
+                                totalSeconds = hours * 3600L + minutes * 60L + seconds;
                                 System.out.println("总通话秒数: " + totalSeconds);
                             }
                         }

+ 1 - 1
fs-service/src/main/java/com/fs/aiTongueApi/config/AiTongueConfig.java

@@ -4,7 +4,7 @@ public interface AiTongueConfig {
     String getFaceHistoryByIDUrl="https://api.aikanshe.com/agency/getHistoryByID";
     String quanxiUrl="https://api.aikanshe.com/agency/quanxi";
     String checkTongue="https://api.aikanshe.com/agency/checkTongue";
-    String appKey="";
+    String appKey="i5h5u6g59dw9x0o6yymd3tf5ea6gcdqi";
 
     String newCheckTongue="http://132.232.234.246:5056/api/detect";
 }

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

@@ -349,7 +349,7 @@ public class FsCourseFinishTempServiceImpl implements IFsCourseFinishTempService
 
                         break;
                     } else {
-                        if (attempt==2 && (qwResult.getErrcode() == 45033 || qwResult.getErrcode()== -1)) {
+                        if (attempt==2 && (qwResult.getErrcode() == 45033 || qwResult.getErrcode()== -1 || qwResult.getErrcode()== 60020)) {
                             QwCourseFinishRemarkRty remarkRty=new QwCourseFinishRemarkRty();
                             remarkRty.setQwUserId(externalContact.getUserId());
                             remarkRty.setCorpId(externalContact.getCorpId());

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

@@ -389,6 +389,7 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
         }else {
             link.setLink(randomString);
         }
+        link.setProjectCode(cloudHostProper.getProjectCode());
 
         link.setCreateTime(sendTime);
 

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

@@ -792,6 +792,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             BigDecimal longAsBigDecimal = BigDecimal.valueOf(video.getFileSize());
             long roundedResult = result.multiply(longAsBigDecimal).setScale(0, RoundingMode.HALF_UP).longValue();
             trafficLog.setInternetTraffic(roundedResult);
+            // 获取课程所属项目id
+            FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
+            if(fsUserCourse != null){
+                trafficLog.setProject(fsUserCourse.getProject());
+            }
 
             // 处理 UUID 为空的情况
             if (StringUtils.isNotEmpty(trafficLog.getUuId())) {

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

@@ -141,9 +141,8 @@ public class FsUserWatchStatisticsServiceImpl extends ServiceImpl<FsUserWatchSta
         //获取公司的会员数量和今日新增会员数量
         List<FsUserWatchStatistics> userTotal = fsUserMapper.selectFsUserTotal();
         Map<String, FsUserWatchStatistics> userTotalMap;
-        if (userTotal != null && userTotal.size() > 0) {
+        if (userTotal != null && !userTotal.isEmpty()) {
             userTotalMap = userTotal.stream().collect(Collectors.toMap(FsUserWatchStatistics::getCompanyId, Function.identity()));
-
         } else {
             userTotalMap = null;
         }

+ 1 - 1
fs-service/src/main/java/com/fs/erp/http/JstErpHttpServiceImpl.java

@@ -110,7 +110,7 @@ public class JstErpHttpServiceImpl implements JstErpHttpService {
 
     @Override
     public OrderQueryResponseDTO query(OrderQueryRequestDTO dto) {
-        String url = BASE_URL + "/open/orders/single/query";
+        String url = BASE_URL + "open/orders/single/query";
         log.info("查询订单信息 - URL: {}, 请求体: {}", url, JSON.toJSONString(dto));
 
         HttpResponse response = executeJsonPost(url, dto);

+ 9 - 7
fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java

@@ -77,7 +77,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
     @Override
     public ErpOrderResponse addOrder(ErpOrder order) {
         FsStoreOrder fsStoreOrder = fsStoreOrderService.selectFsStoreOrderByOrderCode(order.getPlatform_code());
-
+        log.info("ERP订单号: {}, 订单信息: {}",order.getPlatform_code(), JSON.toJSONString(fsStoreOrder));
         ErpOrderPayment erpOrderPayment = order.getPayments().get(0);
 
         ShopOrderDTO shopOrderDTO = new ShopOrderDTO();
@@ -182,16 +182,17 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
 
 
         // 如果是货到付款
-        if("2".equals(fsStoreOrder.getPayType()) || "3".equals(fsStoreOrder.getPayType())){
+        log.info("订单支付方式: {},\"2\".equals(fsStoreOrder.getPayType()) || \"3\".equals(fsStoreOrder.getPayType()):{}",fsStoreOrder.getPayType(),fsStoreOrder.getPayType() == 2 || fsStoreOrder.getPayType() == 3);
+        if(fsStoreOrder.getPayType() == 2 || fsStoreOrder.getPayType() == 3){
             shopOrderDTO.setIsCod(true);
             // 货到付款金额 = 物流代收金额-优惠金额
             shopOrderDTO.setBuyerPaidAmount(fsStoreOrder.getPayDelivery());
-            shopOrderDTO.setPayAmount(fsStoreOrder.getPayPrice().doubleValue());
+            shopOrderDTO.setPayAmount(fsStoreOrder.getPayRemain().doubleValue());
 
             // 货到付款要推两次
             PaymentDTO paymentDTO2 = new PaymentDTO();
             // 物流代收金额
-            paymentDTO2.setAmount(fsStoreOrder.getPayDelivery().doubleValue());
+            paymentDTO2.setAmount(fsStoreOrder.getPayRemain().doubleValue());
             paymentDTO2.setOuterPayId(String.format("%s%d",order.getPlatform_code(),1));
             paymentDTO2.setPayDate(order.getDeal_datetime());
             paymentDTO2.setPayment("货到付款");
@@ -207,7 +208,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
             fsJstCodPush.setTaskStatus(TaskStatusEnum.PENDING.getCode());
             fsJstCodPushMapper.insert(fsJstCodPush);
 
-            shopOrderDTO.setPay(paymentDTO);
+            //shopOrderDTO.setPay(paymentDTO);
         }
 
         ErpOrderResponseDTO upload = jstErpHttpService.upload(shopOrderDTO);
@@ -227,6 +228,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
     @Override
     public ErpOrderResponse addOrderScrm(ErpOrder order) {
         FsStoreOrderScrm fsStoreOrder = fsStoreOrderScrmService.selectFsStoreOrderByOrderCode(order.getPlatform_code());
+        log.info("ERP订单号: {}, 订单信息: {}",order.getPlatform_code(), JSON.toJSONString(fsStoreOrder));
 
         ErpOrderPayment erpOrderPayment = order.getPayments().get(0);
 
@@ -294,6 +296,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
 //        }
 
         List<FsStoreOrderItemVO> fsStoreOrderItemVOS = fsStoreOrderItemScrmService.selectFsStoreOrderItemListByOrderId(fsStoreOrder.getId());
+        log.info("fsStoreOrderItemVOS==========>{}",fsStoreOrderItemVOS);
         for (FsStoreOrderItemVO item : fsStoreOrderItemVOS) {
             OrderItemDTO orderItemDTO = new OrderItemDTO();
             JSONObject jsonObject = JSON.parseObject(item.getJsonInfo());
@@ -328,7 +331,6 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
         paymentDTO.setSellerAccount("平台销售");
         shopOrderDTO.setPay(paymentDTO);
 
-
         // 如果是货到付款
         if("2".equals(fsStoreOrder.getPayType()) || "3".equals(fsStoreOrder.getPayType())){
             shopOrderDTO.setIsCod(true);
@@ -355,7 +357,7 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
             fsJstCodPush.setTaskStatus(TaskStatusEnum.PENDING.getCode());
             fsJstCodPushMapper.insert(fsJstCodPush);
 
-            shopOrderDTO.setPay(paymentDTO);
+            //shopOrderDTO.setPay(paymentDTO);
         }
 
         ErpOrderResponseDTO upload = jstErpHttpService.upload(shopOrderDTO);

+ 19 - 0
fs-service/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -17,6 +17,8 @@ import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.param.FsCourseLinkCreateParam;
 import com.fs.course.service.IFsCourseLinkService;
 import com.fs.course.vo.FsCourseWatchLogVO;
+import com.fs.crm.domain.CrmMsg;
+import com.fs.crm.service.ICrmMsgService;
 import com.fs.fastGpt.config.ModeConfig;
 import com.fs.fastGpt.domain.*;
 import com.fs.fastGpt.mapper.FastGptChatReplaceWordsMapper;
@@ -161,6 +163,8 @@ public class AiHookServiceImpl implements AiHookService {
     private CompanyConfigMapper companyConfigMapper;
     @Autowired
     private IFastGptChatReplaceTextService fastGptChatReplaceTextService;
+    @Autowired
+    private ICrmMsgService crmMsgService;
 
     private static final String AI_REPLY = "AI_REPLY:";
     private static final String AI_REPLY_TAG = "AI_REPLY_TAG:";
@@ -449,6 +453,12 @@ public class AiHookServiceImpl implements AiHookService {
                 log.info("不是图片"+type);
             }
 
+            if("==语音转换失败==".equals(qwContent)){
+                log.error("语音转换失败转人工:"+role.getRoleId()+":"+qwExternalContacts.getName() + ",uid" + uid);
+                notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 语音转换失败转人工",qwExternalContacts.getId(),sender);
+                return R.ok();
+            }
+
             //对用户处理的内容做处理
             String maskedContent = processContent(qwContent);
             String contentEmj = replaceWxEmo(maskedContent);
@@ -1123,6 +1133,15 @@ public class AiHookServiceImpl implements AiHookService {
         sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),"您的客户:"+name+"因"+reason+"  需要转人工,请及时回复");
         sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),name);
         qwWorkTaskService.addQwWorkByAiNotifyArtificial(user,extId,"Ai转人工");
+        FastGptChatSession chatSession = fastGptChatSessionMapper.selectFastGptChatSessionBySessionId(sessionId);
+        CrmMsg crmMsg = new CrmMsg();
+        crmMsg.setMsgType(3);
+        crmMsg.setTitle("Ai转人工");
+        crmMsg.setContent("你的客户:" + chatSession.getNickName() + ", 因  \"" + reason + "\"  需要转人工,请及时回复");
+        crmMsg.setCompanyId(user.getCompanyId());
+        crmMsg.setCompanyUserId(user.getCompanyUserId());
+        crmMsgService.insertCrmMsg(crmMsg);
+
     }
 
     void sendQwAppMsg(String corpId, Integer agentId,String qwUserId,String content){

+ 4 - 0
fs-service/src/main/java/com/fs/his/config/StoreConfig.java

@@ -18,5 +18,9 @@ public class StoreConfig implements Serializable {
     private String refundPhoneNumber;
     private String refundAddress;
     private Integer storeCall;
+    private Integer isIdVerification; //1开启三方身份认证 0不开启
+    private String API_URL;
+    private String HASHCODE;
+    private String SECRET_KEY;
 
 }

+ 4 - 3
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -22,6 +22,7 @@ public class FsUser extends BaseEntity
     private static final long serialVersionUID = 1L;
 
     /** 用户id */
+    @Excel(name = "ID", sort = 0)
     private Long userId;
     private String username;
     private String password;
@@ -35,7 +36,7 @@ public class FsUser extends BaseEntity
     private String nickName;
 
     /** 用户头像 */
-    @Excel(name = "用户头像")
+//    @Excel(name = "用户头像")
     private String avatar;
     private String remark;
 
@@ -73,11 +74,11 @@ public class FsUser extends BaseEntity
     private Long tuiUserCount;
 
     /** 微信小程序OPENID */
-    @Excel(name = "微信小程序OPENID")
+//    @Excel(name = "微信小程序OPENID")
     private String maOpenId;
 
     /** 微信公众号OPENID */
-    @Excel(name = "微信公众号OPENID")
+//    @Excel(name = "微信公众号OPENID")
     private String mpOpenId;
 
     /** 关联ID */

+ 6 - 1
fs-service/src/main/java/com/fs/his/enums/FsStoreOrderLogEnum.java

@@ -13,6 +13,7 @@ public enum FsStoreOrderLogEnum {
     REMOVE_ORDER("remove_order","删除订单"),
     EVAL_ORDER("order_eval","用户评价"),
     REFUND_ORDER_APPLY("apply_refund","用户申请退款"),
+    REFUND_ORDER_PLATFORM("REFUND_ORDER_PLATFORM","平台申请退款"),
     REFUND_ORDER_DF("refund_order_df","代服取消订单,申请退款"),
     TAKE_ORDER_DELIVERY("user_take_delivery","用户已收货"),
     PAY_ORDER_SUCCESS("pay_success","用户付款成功"),
@@ -30,7 +31,11 @@ public enum FsStoreOrderLogEnum {
     PLATFORM_REVIEW_SALES("PLATFORM_REVIEW_SALES","平台已审核"),
     WAREHOUSE_REVIEW_SALES("WAREHOUSE_REVIEW_SALES","仓库已审核"),
     FINANCE_REVIEW_SALES("FINANCE_REVIEW_SALES","财务已审核"),
-    PLATFORM_REVIEW_CANCEL("PLATFORM_REVIEW_CANCEL","平台已取消售后");
+    PLATFORM_REVIEW_CANCEL("PLATFORM_REVIEW_CANCEL","平台已取消售后"),
+
+    SET_PUSH_MOBILE("SET_PUSH_MOBILE","设置推送手机号"),
+    SET_PUSH_ACCOUNT("SET_PUSH_ACCOUNT","数据分拣"),
+    PUSH_ORDER_ERP("PUSH_ORDER_ERP","创建ERP");
     private String value;
     private String desc;
 

+ 10 - 1
fs-service/src/main/java/com/fs/his/mapper/FsPackageOrderMapper.java

@@ -76,7 +76,16 @@ public interface FsPackageOrderMapper
     public int deleteFsPackageOrderByOrderIds(Long[] orderIds);
 
     @Select({"<script> " +
-            "select o.order_id,o.package_second_name,o.source,o.order_sn,o.package_name,o.pay_time, o.days,o.pay_price,o.pay_money,o.pay_type,o.`status`,o.package_sub_type,o.create_time,o.start_time,o.finish_time      ,d.doctor_name,u.nick_name,u.phone,c.company_name,cu.nick_name company_user_name,patient_json->>'$.patientName' as patientName,fso.delivery_status,fso.delivery_pay_status  from fs_package_order o LEFT JOIN fs_doctor d ON d.doctor_id=o.doctor_id LEFT JOIN fs_user u ON u.user_id=o.user_id LEFT JOIN company c on c.company_id =o.company_id LEFT JOIN company_user cu on cu.user_id=o.company_user_id LEFT JOIN fs_store_order fso ON fso.order_id= o.store_order_id"+
+            "select o.order_id,o.package_second_name,o.source,o.order_sn,o.package_name,o.pay_time,o.is_pay, o.days,o.pay_price, " +
+            "o.pay_money,o.pay_type,o.`status`,o.package_sub_type,o.create_time,o.start_time,o.finish_time      " +
+            ",d.doctor_name,u.nick_name,u.phone,c.company_name,cu.nick_name company_user_name, " +
+            "patient_json->>'$.patientName' as patientName,fso.delivery_status,fso.delivery_pay_status  " +
+            "from fs_package_order o " +
+            "LEFT JOIN fs_doctor d ON d.doctor_id=o.doctor_id " +
+            "LEFT JOIN fs_user u ON u.user_id=o.user_id " +
+            "LEFT JOIN company c on c.company_id =o.company_id " +
+            "LEFT JOIN company_user cu on cu.user_id=o.company_user_id " +
+            "LEFT JOIN fs_store_order fso ON fso.order_id= o.store_order_id "+
             " where 1 = 1 \n" +
             "            <if test=\"maps.orderSn != null  and maps.orderSn != ''\"> and o.order_sn = #{maps.orderSn}</if>\n" +
             "            <if test=\"maps.phone != null and maps.phone != '' \">and u.phone = #{maps.phone} </if>\n" +

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

@@ -1,5 +1,6 @@
 package com.fs.his.mapper;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -1166,6 +1167,10 @@ public interface FsStoreOrderMapper
 
     List<FsStoreOrderErpExportVO> selectFsStoreOrderListErpVOByExport(@Param("maps")FsStoreOrderParam fsStoreOrder);
 
+    Map<String,BigDecimal> selectFsStoreOrderStatistics(@Param("maps") FsStoreOrderParam fsStoreOrder);
+
+    String selectFsStoreOrderProductStatistics(@Param("maps")FsStoreOrderParam fsStoreOrder);
+
 
     List<Report> selectOrderByCustomerIds(@Param("map") ReportParam param);
 }

+ 1 - 0
fs-service/src/main/java/com/fs/his/param/FsStoreOrderSetErpPhoneParam.java

@@ -9,4 +9,5 @@ public class FsStoreOrderSetErpPhoneParam extends FsStoreOrderParam{
     private List<String> erpPhone;
     private List<Long> orderIds;
     private String loginAccount;
+    private String opeName; //操作人
 }

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

@@ -129,4 +129,6 @@ public interface IFsInquiryOrderService
 
     byte[] getWxaCodeInquiryOrderUnLimit(Long orderId);
 
+    R getWxaCodeInquiryOrderUnLimitR(Long orderId);
+
 }

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

@@ -94,7 +94,7 @@ public interface IFsPackageOrderService
 
     Integer PackageInquiryOrderRefund(Long orderId);
 
-    Integer PackageStoreOrderRefund(Long orderId);
+    Integer PackageStoreOrderRefund(Long orderId,String opeName);
 
     R payment(FsPackageOrderDoPayParam param);
 
@@ -122,5 +122,6 @@ public interface IFsPackageOrderService
 
     List<PackageOrderDTO> getNewOrder();
 
+    R getWxaCodePackageOrderUnLimit(Long orderId);
 
 }

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

@@ -1,5 +1,6 @@
 package com.fs.his.service;
 
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
@@ -260,4 +261,8 @@ public interface IFsStoreOrderService
     String importOrderStatusData(List<FsStoreOrderStatusExcelVO> list);
 
     Long selectFsStoreOrderListVOByErpAccountByExportCount(FsStoreOrderParam param);
+
+    Map<String,BigDecimal> selectFsStoreOrderStatistics(FsStoreOrderParam fsStoreOrder);
+
+    String selectFsStoreOrderProductStatistics(FsStoreOrderParam fsStoreOrder);
 }

+ 47 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.his.service.impl;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
@@ -23,6 +24,7 @@ import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
+import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.event.TemplateBean;
@@ -48,6 +50,8 @@ import com.fs.jpush.service.JpushService;
 import com.fs.repeat.vo.RepeatUploadVo;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
 import com.fs.tzBankPay.doman.*;
 import com.fs.ybPay.domain.OrderResult;
 import com.fs.ybPay.domain.RefundResult;
@@ -67,6 +71,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
 import lombok.Synchronized;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1807,4 +1812,46 @@ public class FsInquiryOrderServiceImpl implements IFsInquiryOrderService
         byte[] bytes = HttpUtil.getWechatQrcodeByHttpURL(codeUrl, jsonMap);
         return bytes;
     }
+
+    @Override
+    public R getWxaCodeInquiryOrderUnLimitR(Long orderId) {
+
+        FsSysConfig sysConfig = configUtil.getSysConfig();
+
+        final WxMaService wxMaService = WxMaConfiguration.getMaService(sysConfig.getAppid());
+        String scene="orderId="+ orderId ;
+        byte[] file;
+        try {
+            file = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
+                    scene,
+                    "pages_order/inquiryPay",
+                    true,
+                    "release",
+                    430,
+                    true,
+                    null,
+                    false);
+
+            // 上传图片到存储桶
+            String suffix = ".png";
+            CloudStorageService storage = OSSFactory.build();
+            String url;
+            try {
+                url = storage.uploadSuffix(file, suffix);
+            }  catch (Exception e) {
+                // 记录错误日志
+                logger.error("生成图片失败:{}",e.getMessage(),e);
+                return R.error("生成图片失败");
+            }
+            // 返回成功信息
+            return R.ok().put("url",url);
+
+        } catch (WxErrorException e) {
+            logger.error(e.getMessage(), e);
+            return R.error("微信接口调用失败: " + e.getMessage());
+        }
+
+    }
+
+
 }

+ 46 - 2
fs-service/src/main/java/com/fs/his/service/impl/FsPackageOrderServiceImpl.java

@@ -10,6 +10,7 @@ import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
@@ -27,6 +28,7 @@ import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyUserMapper;
+import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.his.config.FsSysConfig;
@@ -50,6 +52,8 @@ import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.service.HuiFuService;
 import com.fs.system.domain.SysConfig;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
 import com.fs.ybPay.domain.CreateWxOrderResult;
 import com.fs.ybPay.domain.OrderResult;
 import com.fs.ybPay.dto.OrderQueryDTO;
@@ -70,6 +74,7 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -846,7 +851,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
     }
 
     @Override
-    public Integer PackageStoreOrderRefund(Long orderId) {
+    public Integer PackageStoreOrderRefund(Long orderId,String opeName) {
         FsPackageOrder fsPackageOrder = fsPackageOrderMapper.selectFsPackageOrderByOrderId(orderId);
         if (fsPackageOrder.getStatus()!=2&&fsPackageOrder.getStatus()!=3){
             throw  new CustomException("非法操作");
@@ -857,6 +862,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
         }
         FsStoreOrderSalesParam fsStoreOrderSalesParam = new FsStoreOrderSalesParam();
         fsStoreOrderSalesParam.setOrderId(fsPackageOrder.getStoreOrderId());
+        fsStoreOrderSalesParam.setOperator(opeName);
         return fsStoreOrderService.afterSales(fsStoreOrderSalesParam);
     }
 
@@ -1029,7 +1035,7 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             }
         }
         else{
-            return R.error("用户OPENID不存在");
+            return R.error(401,"用户OPENID不存在"); //触发前端重新登录
         }
         return R.error();
     }
@@ -1535,4 +1541,42 @@ public class FsPackageOrderServiceImpl implements IFsPackageOrderService
             return R.error("创建失败");
         }
     }
+
+    @Override
+    public R getWxaCodePackageOrderUnLimit(Long orderId) {
+        FsSysConfig sysConfig = configUtil.getSysConfig();
+
+        final WxMaService wxMaService = WxMaConfiguration.getMaService(sysConfig.getAppid());
+        String scene="orderId="+ orderId ;
+        byte[] file;
+        try {
+            file = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
+                    scene,
+                    "pages_order/packagePayment",
+                    true,
+                    "release",
+                    430,
+                    true,
+                    null,
+                    false);
+
+            // 上传图片到存储桶
+            String suffix = ".png";
+            CloudStorageService storage = OSSFactory.build();
+            String url;
+            try {
+                url = storage.uploadSuffix(file, suffix);
+            }  catch (Exception e) {
+                // 记录错误日志
+                logger.error("生成图片失败:{}",e.getMessage(),e);
+                return R.error("生成图片失败");
+            }
+            // 返回成功信息
+            return R.ok().put("url",url);
+
+        } catch (WxErrorException e) {
+            logger.error(e.getMessage(), e);
+            return R.error("微信接口调用失败: " + e.getMessage());
+        }
+    }
 }

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

@@ -719,6 +719,8 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
         logs.setStoreAfterSalesId(storeAfterSales.getId());
         logs.setChangeMessage(FsStoreAfterSalesStatusEnum.STATUS_0.getDesc());
         fsStoreAfterSalesLogsMapper.insertFsStoreAfterSalesLogs(logs);
+        fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_APPLY.getValue(),
+                FsStoreOrderLogEnum.REFUND_ORDER_APPLY.getDesc());
         if (order.getExtendOrderId() != null) {
             ErpRefundUpdateRequest request = new ErpRefundUpdateRequest();
             request.setTid(order.getOrderCode());

+ 18 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -1606,6 +1606,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         logs.setCompanyId(fsStoreOrderSalesParam.getCompanyId());
         logs.setChangeMessage("平台提交售后");
         fsStoreAfterSalesLogsMapper.insertFsStoreAfterSalesLogs(logs);
+        //添加订单日志
+        fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getValue(),
+                fsStoreOrderSalesParam.getOperator() + " " +FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getDesc());
         //判断是否开启erp
         FsSysConfig sysConfig = configUtil.getSysConfig();
         Integer erpOpen = sysConfig.getErpOpen();
@@ -2311,7 +2314,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             order.setStatus(4);
             fsStoreOrderMapper.updateFsStoreOrder(order);
             fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
-                    FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
+                    "用户"+FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
             return R.ok("操作成功");
         } else {
             return R.error("非法操作");
@@ -3290,6 +3293,8 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 map.put("orderId", orderIds.get(i).toString());
                 map.put("erpPhone", erpPhones.get(i));
                 maps.add(map);
+                fsStoreOrderLogsService.create(orderIds.get(i), FsStoreOrderLogEnum.SET_PUSH_MOBILE.getValue(),
+                        param.getOpeName() + " " +FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhones.get(i));
             }
         } else {
             //2.手机号小于orderIds长度
@@ -3309,6 +3314,8 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     map.put("erpPhone", erpPhone);
                     maps.add(map);
                     orderIndex++;
+                    fsStoreOrderLogsService.create(orderIds.get(i), FsStoreOrderLogEnum.SET_PUSH_MOBILE.getValue(),
+                            param.getOpeName() + " " +FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhone);
                 }
             }
         }
@@ -3688,4 +3695,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         return fsStoreOrderMapper.selectFsStoreOrderListVOByErpAccountByExportCount(param);
     }
 
+    @Override
+    public Map<String,BigDecimal> selectFsStoreOrderStatistics(FsStoreOrderParam fsStoreOrder) {
+        return fsStoreOrderMapper.selectFsStoreOrderStatistics(fsStoreOrder);
+    }
+
+    @Override
+    public String selectFsStoreOrderProductStatistics(FsStoreOrderParam fsStoreOrder) {
+        return fsStoreOrderMapper.selectFsStoreOrderProductStatistics(fsStoreOrder);
+    }
+
 }

+ 143 - 0
fs-service/src/main/java/com/fs/his/utils/IdCardUtil.java

@@ -0,0 +1,143 @@
+package com.fs.his.utils;
+
+import cn.hutool.crypto.digest.DigestUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.config.StoreConfig;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 三方身份验证
+ */
+@Service
+public class IdCardUtil {
+    @Autowired
+    private static ISysConfigService configService;
+
+    /**
+     * 身份证信息隐藏 中间
+     * @param idCard   身份证信息
+     * @return  隐藏后信息
+     */
+    public static String hiddenIdCard(String idCard) {
+        if (StringUtils.isBlank(idCard)) {
+            return idCard;
+        }
+
+        return idCard.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1**********$2");
+    }
+
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+
+    private static String generateSign(String hashcode, String passname, String pid, String mobile,String secretKey) {
+        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
+        String raw = null;
+        if (StringUtils.isNotBlank(mobile)){
+            raw = hashcode + mobile + passname + secretKey + date;
+        } else {
+            raw = hashcode + passname + pid + secretKey + date;
+        }
+        return DigestUtil.md5Hex(raw.getBytes(StandardCharsets.UTF_8));
+    }
+
+    /**
+     * 检查身份证与姓名是否匹配
+     *
+     * @param passname 姓名
+     * @param pid      身份证号
+     * @return true 表示一致,false 表示不一致
+     */
+    public static boolean isMatchById(StoreConfig storeConfig,String passname, String pid) {
+        if (storeConfig == null) {
+            return false;
+        }
+        String API_URL = storeConfig.getAPI_URL() + "/HrmApi/Idverify";
+        String HASHCODE = storeConfig.getHASHCODE();
+        String SECRET_KEY = storeConfig.getSECRET_KEY();
+        try {
+            String sign = generateSign(HASHCODE, passname, pid,null, SECRET_KEY);
+            String bodyJson = String.format(
+                    "{\"passname\":\"%s\",\"pid\":\"%s\",\"hashcode\":\"%s\",\"sign\":\"%s\"}",
+                    passname, pid, HASHCODE, sign
+            );
+
+            HttpResponse response = HttpRequest.post(API_URL)
+                    .body(bodyJson)
+                    .header("Content-Type", "application/json;charset=UTF-8")
+                    .timeout(5000)
+                    .execute();
+
+            if (response.getStatus() != 200) {
+                throw new RuntimeException("HTTP请求失败,状态码:" + response.getStatus());
+            }
+
+            JsonNode root = OBJECT_MAPPER.readTree(response.body());
+            JsonNode errorRes = root.get("errorRes");
+            String errTransCode = root.get("err_TransCode").asText();
+            System.out.println(DateUtils.getNowDate());
+            System.out.println("流水号"+errTransCode);
+            if (errorRes != null && "200".equals(errorRes.get("err_code").asText())) {
+                return true; // 一致
+            }
+            return false; // 不一致或接口异常
+        } catch (Exception e) {
+            throw new RuntimeException("匹配请求异常", e);
+        }
+    }
+
+    /**
+     * 检查身份证与姓名是否匹配
+     *
+     * @param passname 姓名
+     * @param mobile      身份证号
+     * @return true 表示一致,false 表示不一致
+     */
+    public static boolean isMatchByMobile(StoreConfig storeConfig,String passname, String mobile) {
+        if (storeConfig == null) {
+            return false;
+        }
+        String API_URL = storeConfig.getAPI_URL() + "/HrmApi/mobile2everify";
+        String HASHCODE = storeConfig.getHASHCODE();
+        String SECRET_KEY = storeConfig.getSECRET_KEY();
+        try {
+            String sign = generateSign(HASHCODE, passname, null,mobile, SECRET_KEY);
+            String bodyJson = String.format(
+                    "{\"passname\":\"%s\",\"mobile\":\"%s\",\"hashcode\":\"%s\",\"sign\":\"%s\"}",
+                    passname, mobile, HASHCODE, sign
+            );
+
+            HttpResponse response = HttpRequest.post(API_URL)
+                    .body(bodyJson)
+                    .header("Content-Type", "application/json;charset=UTF-8")
+                    .timeout(5000)
+                    .execute();
+
+            if (response.getStatus() != 200) {
+                throw new RuntimeException("HTTP请求失败,状态码:" + response.getStatus());
+            }
+
+            JsonNode root = OBJECT_MAPPER.readTree(response.body());
+            JsonNode errorRes = root.get("errorRes");
+            String errTransCode = root.get("err_TransCode").asText();
+            System.out.println(DateUtils.getNowDate());
+            System.out.println("流水号"+errTransCode);
+            if (errorRes != null && "200".equals(errorRes.get("err_code").asText())) {
+                return true; // 一致
+            }
+            return false; // 不一致或接口异常
+        } catch (Exception e) {
+            throw new RuntimeException("匹配请求异常", e);
+        }
+    }
+}

+ 14 - 0
fs-service/src/main/java/com/fs/his/vo/FsStoreOrderListAndStatisticsVo.java

@@ -0,0 +1,14 @@
+package com.fs.his.vo;
+
+import com.fs.common.core.page.TableDataInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class FsStoreOrderListAndStatisticsVo extends TableDataInfo{
+    private String payPriceTotal;
+    private String payMoneyTotal;
+    private String payRemainTotal;
+    private String productInfo;
+}

+ 1 - 1
fs-service/src/main/java/com/fs/qw/domain/QwUserVoiceLog.java

@@ -36,7 +36,7 @@ public class QwUserVoiceLog extends BaseEntity{
 
     /** 1接听 2未接 */
     @Excel(name = "1接听 2未接")
-    private Long status;
+    private Integer status;
 
     /** 企微id */
     @Excel(name = "企微id")

+ 2 - 2
fs-service/src/main/java/com/fs/qw/mapper/QwCourseFinishRemarkRtyMapper.java

@@ -32,10 +32,10 @@ public interface QwCourseFinishRemarkRtyMapper extends BaseMapper<QwCourseFinish
      */
     List<QwCourseFinishRemarkRty> selectQwCourseFinishRemarkRtyList(QwCourseFinishRemarkRty qwCourseFinishRemarkRty);
 
-    @DataSource(DataSourceType.SLAVE)
+
     List<QwCourseFinishRemarkRty> selectQwCourseFinishRemarkRtyListByTime(@Param("time") LocalDateTime tenMinutesBefore,@Param("num") Integer num);
 
-    @DataSource(DataSourceType.SLAVE)
+
     List<Long> selectQwCourseFinishRemarkRtyListByOutTime();
 
     /**

+ 1 - 1
fs-service/src/main/java/com/fs/qw/service/IQwUserVoiceLogService.java

@@ -64,5 +64,5 @@ public interface IQwUserVoiceLogService extends IService<QwUserVoiceLog>{
 
     List<QwUserVoiceLogTotalVo> selectQwUserVoiceLogTotalList(QwUserVoiceLogTotalVo qwUserVoiceLog);
 
-    void addQuUserVoiceByIpadCallback(Long id, Long extUserId, Integer recordType, Integer totalSeconds, String uuid);
+    void addQuUserVoiceByIpadCallback(Long id, Long extUserId, Integer recordType, Long totalSeconds, String uuid);
 }

+ 68 - 44
fs-service/src/main/java/com/fs/qw/service/impl/QwUserVoiceLogServiceImpl.java

@@ -155,57 +155,81 @@ public class QwUserVoiceLogServiceImpl extends ServiceImpl<QwUserVoiceLogMapper,
     }
 
     @Override
-    public void addQuUserVoiceByIpadCallback(Long id, Long extUserId, Integer recordType, Integer totalSeconds, String uuid) {
-        QwUser sendUser = qwUserMapper.selectQwUserById(id);
-        if (sendUser!=null){
-            String extId = getExtId(extUserId, uuid, sendUser.getServerId());
-            QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(extId, sendUser.getCorpId(),sendUser.getQwUserId());
-            if (qwExternalContacts==null){
-                log.error("未找到外部联系人,qwUserId:" + id);
-                return ;
-            }
+    public void addQuUserVoiceByIpadCallback(Long id, Long extUserId, Integer recordType, Long totalSeconds, String uuid) {
+        // 参数校验
+        if (id == null || (extUserId == null && uuid == null)) {
+            log.error("参数校验失败: id={}, extUserId={}, uuid={}", id, extUserId, uuid);
+            return;
+        }
 
-            QwUserVoiceLog qwUserVoiceLog = new QwUserVoiceLog();
-            qwUserVoiceLog.setCorpId(sendUser.getCorpId());
-            qwUserVoiceLog.setExtId(qwExternalContacts.getId());
-            qwUserVoiceLog.setQwUserId(sendUser.getId());
-            qwUserVoiceLog.setCompanyId(qwExternalContacts.getCompanyId());
-            if(qwExternalContacts.getCompanyUserId() != null){
-                qwUserVoiceLog.setCompanyUserId(qwExternalContacts.getCompanyUserId());
-            }
+        try {
+            QwUser sendUser = qwUserMapper.selectQwUserById(id);
+            if (sendUser != null) {
+                String extId = getExtId(extUserId, uuid, sendUser.getServerId());
+                // 检查extId是否有效
+                if (extId == null || extId.isEmpty()) {
+                    log.error("获取外部联系人ID失败,qwUserId:" + id + ",extUserId:" + extUserId + ",uuid:" + uuid);
+                    return;
+                }
 
-            if(recordType == 2){//2是未接通的处理
-                qwUserVoiceLog.setStatus(Long.valueOf(recordType));
-                qwUserVoiceLog.setTitle("通话拒接");
-            }else{
-                qwUserVoiceLog.setStatus(1L);
-                if(totalSeconds != null){
-                    qwUserVoiceLog.setDuration(Long.valueOf(totalSeconds));
-                }else{
-                    qwUserVoiceLog.setDuration(0L);
+                QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(extId, sendUser.getCorpId(), sendUser.getQwUserId());
+                if (qwExternalContacts == null) {
+                    log.error("未找到外部联系人,qwUserId:" + id + ",extId:" + extId);
+                    return;
                 }
-                qwUserVoiceLog.setTitle("通话已接听");
-            }
-            qwUserVoiceLog.setCreateTime(new Date());
-
-            int insert = baseMapper.insertQwUserVoiceLog(qwUserVoiceLog);
-            //插入成功的情况下就处理定时任务
-            if(insert == 1){
-                List<QwWorkTask> qwWorkTaskList = qwWorkTaskMapper.selectQwWorkTaskByExtIdAndQwUserId(qwUserVoiceLog);
-                if(qwWorkTaskList != null && !qwWorkTaskList.isEmpty()){
-                    for (QwWorkTask qwWorkTask : qwWorkTaskList) {
-                        if(qwUserVoiceLog.getStatus() == 1L){//接通电话
-                            qwWorkTask.setTrackType(3);//1正常处理 2 未接听 3 已接听
-                            qwWorkTask.setDuration(qwUserVoiceLog.getDuration());
-                        }else{
-                            qwWorkTask.setTrackType(2);//1正常处理 2 未接听 3 已接听
+
+                QwUserVoiceLog qwUserVoiceLog = new QwUserVoiceLog();
+                qwUserVoiceLog.setCorpId(sendUser.getCorpId());
+                qwUserVoiceLog.setExtId(qwExternalContacts.getId());
+                qwUserVoiceLog.setQwUserId(sendUser.getId());
+                qwUserVoiceLog.setCompanyId(qwExternalContacts.getCompanyId());
+                if (qwExternalContacts.getCompanyUserId() != null) {
+                    qwUserVoiceLog.setCompanyUserId(qwExternalContacts.getCompanyUserId());
+                }
+
+                if (recordType == 2) {//2是未接通的处理
+                    qwUserVoiceLog.setStatus(recordType);
+                    qwUserVoiceLog.setTitle("通话拒接");
+                } else {
+                    qwUserVoiceLog.setStatus(1);
+                    if (totalSeconds != null) {
+                        qwUserVoiceLog.setDuration(totalSeconds);
+                    } else {
+                        qwUserVoiceLog.setDuration(0L);
+                    }
+                    qwUserVoiceLog.setTitle("通话已接听");
+                }
+                qwUserVoiceLog.setCreateTime(new Date());
+
+                int insert = baseMapper.insertQwUserVoiceLog(qwUserVoiceLog);
+                // 插入成功的情况下就处理定时任务
+                if (insert == 1) {
+                    List<QwWorkTask> qwWorkTaskList = qwWorkTaskMapper.selectQwWorkTaskByExtIdAndQwUserId(qwUserVoiceLog);
+                    if (qwWorkTaskList != null && !qwWorkTaskList.isEmpty()) {
+                        for (QwWorkTask qwWorkTask : qwWorkTaskList) {
+                            try {
+                                if (qwUserVoiceLog.getStatus() == 1L) {//接通电话
+                                    qwWorkTask.setTrackType(3);//1正常处理 2 未接听 3 已接听
+                                    qwWorkTask.setDuration(qwUserVoiceLog.getDuration());
+                                } else {
+                                    qwWorkTask.setTrackType(2);//1正常处理 2 未接听 3 已接听
+                                }
+                                qwWorkTask.setStatus(1);//0 待处理 1 已处理 3 过期
+                                qwWorkTask.setUpdateTime(new Date());
+                                qwWorkTaskMapper.updateQwWorkTask(qwWorkTask);
+                            } catch (Exception e) {
+                                log.error("更新任务状态失败, taskId: " + qwWorkTask.getId(), e);
+                            }
                         }
-                        qwWorkTask.setStatus(1);//0 待处理 1 已处理 3 过期
-                        qwWorkTask.setUpdateTime(new Date());
-                        qwWorkTaskMapper.updateQwWorkTask(qwWorkTask);
                     }
+                } else {
+                    log.error("插入失败,qwUserId:" + id + ",extId:" + extUserId + ",uuid:" + uuid + ",totalSeconds" + totalSeconds);
                 }
+            } else {
+                log.error("未找到企微用户,id:" + id + ",extId:" + extUserId + ",uuid:" + uuid + ",totalSeconds" + totalSeconds);
             }
+        } catch (Exception e) {
+            log.error("处理通话回调异常, id:" + id + ",extUserId:" + extUserId + ",recordType:" + recordType + ",totalSeconds:" + totalSeconds + ",uuid:" + uuid, e);
         }
     }
 

+ 1 - 1
fs-service/src/main/java/com/fs/qw/vo/QwUserVoiceLogVo.java

@@ -42,7 +42,7 @@ public class QwUserVoiceLogVo extends BaseEntity {
 
     /** 1接听 2未接 */
     @Excel(name = "接听状态,1接听 2未接")
-    private Long status;
+    private Integer status;
 
     /** 企微id */
     @Excel(name = "企微id")

+ 2 - 2
fs-service/src/main/resources/application-config-druid-syysy.yml

@@ -42,8 +42,8 @@ wx:
       port: 6379
       timeout: 2000
     configs:
-      - appId: wx # 第一个公众号的appid  //公众号名称
-        secret: 5da9ae # 公众号的appsecret
+      - appId: wx17f36a56c701bdea # 第一个公众号的appid   //公众号名称
+        secret: 185030bbe7f8d7a0c16b94dd9d4ea542 # 公众号的appsecret
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
 aifabu:  #爱链接

+ 1 - 1
fs-service/src/main/resources/application-druid-jnmy-test.yml

@@ -41,7 +41,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://120.46.174.121:2345/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    url: jdbc:mysql://120.46.174.121:2345/fs_his_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: root
                     password: Ylrztek250218!3@.
                 # 从库数据源

+ 9 - 6
fs-service/src/main/resources/application-druid-jnmy.yml

@@ -139,15 +139,18 @@ spring:
                         config:
                             multi-statement-allow: true
 rocketmq:
-    name-server: rmq-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    name-server: 192.168.0.176:8100 # RocketMQ NameServer 地址
     producer:
         group: my-producer-group
-        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
-        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+        access-key: jnmyunl # 替换为实际的 accessKey
+        secret-key: 73a!ul~xQl@-6u1 # 替换为实际的 secretKey
+        tls-enable: false
     consumer:
-        group: test-group
-        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
-        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+        topic: course-finish-notes
+        group: course-finish-group
+        access-key: jnmyunl # 替换为实际的 accessKey
+        secret-key: 73a!ul~xQl@-6u1 # 替换为实际的 secretKey
+        tls-enable: false
 openIM:
     secret: openIM123
     userID: imAdmin

+ 1 - 1
fs-service/src/main/resources/mapper/course/FsCourseLinkMapper.xml

@@ -152,7 +152,7 @@
             #{item.courseId,jdbcType=BIGINT},
             #{item.qwExternalId,jdbcType=BIGINT},
             #{item.linkType,jdbcType=BIGINT},
-            #{item.isRoom,jdbcType=VARCHAR},
+            #{item.isRoom,jdbcType=VARCHAR}
             )
         </foreach>
     </insert>

+ 392 - 0
fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml

@@ -1598,6 +1598,398 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LIMIT 30000
 
 
+    </select>
+    <select id="selectFsStoreOrderStatistics" resultType="java.util.Map">
+        select sum(so.pay_price) pay_price,sum(so.pay_money) pay_money,sum(so.pay_remain) pay_remain
+        FROM fs_store_order so LEFT JOIN fs_store st ON so.store_id =st.store_id
+        LEFT JOIN fs_user us ON us.user_id=so.user_id
+        LEFT JOIN fs_prescribe p ON p.prescribe_id =so.prescribe_id
+        LEFT JOIN fs_doctor d ON so.doctor_id= d.doctor_id
+        LEFT JOIN company_user cu on cu.user_id=so.company_user_id
+        LEFT JOIN fs_store_order_df df on df.order_id=so.order_id
+        <where>
+            <if test="maps.packageSecondName != null and maps.packageSecondName != ''">
+                and so.package_second_name like concat('%', #{maps.packageSecondName}, '%')
+            </if>
+            <if test="maps.storeId != null">
+                and so.store_id = #{maps.storeId}
+            </if>
+            <if test="maps.orderCodes != null  and maps.orderCodes.size > 0">
+                and so.order_code in
+                <foreach collection="maps.orderCodes" item="orderCode" open="(" close=")" separator=",">
+                    #{orderCode}
+                </foreach>
+            </if>
+            <if test="maps.orderCode != null  and maps.orderCode != ''">
+                and so.order_code = #{maps.orderCode}
+            </if>
+            <if test="maps.prescribeCode != null  and maps.prescribeCode != ''">
+                and p.prescribe_code = #{maps.prescribeCode}
+            </if>
+            <if test="maps.userName != null  and maps.userName != ''">
+                and so.user_name like concat('%', #{maps.userName}, '%')
+            </if>
+            <if test="maps.userPhone != null  and maps.userPhone != ''">
+                and so.user_phone = #{maps.userPhone}
+            </if>
+            <if test="maps.userId != null ">
+                and so.user_id = #{maps.userId}
+            </if>
+            <if test="maps.isFirst != null">
+                and so.is_first = #{maps.isFirst}
+            </if>
+            <if test="maps.status != null and maps.status != 6">
+                and so.status = #{maps.status}
+            </if>
+            <if test="maps.status == 6">
+                and so.`status`= 2
+                and (
+                so.store_id in (select store_id from fs_store where delivery_type=2 or delivery_type=1)
+                )
+                and  (so.extend_order_id is null or  so.extend_order_id like '')
+            </if>
+            <if test="maps.source != null">
+                and so.source = #{maps.source}
+            </if>
+            <if test="maps.deliverySn != null  and maps.deliverySn != ''">
+                and so.delivery_sn = #{maps.deliverySn}
+            </if>
+            <if test="maps.prescribeId != null">
+                and so.prescribe_id = #{maps.prescribeId}
+            </if>
+            <if test="maps.companyUserId != null">
+                and so.company_user_id = #{maps.companyUserId}
+            </if>
+            <if test="maps.sTime != null">
+                and DATE(so.create_time) &gt;= DATE(#{maps.sTime})
+            </if>
+            <if test="maps.eTime != null">
+                and DATE(so.create_time) &lt;= DATE(#{maps.eTime})
+            </if>
+            <if test="maps.paysTime != null">
+                and DATE(so.pay_time) &gt;= DATE(#{maps.paysTime})
+            </if>
+            <if test="maps.payeTime != null">
+                and DATE(so.pay_time) &lt;= DATE(#{maps.payeTime})
+            </if>
+            <if test="maps.orderCreateType != null">
+                and so.order_create_type = #{maps.orderCreateType}
+            </if>
+            <if test="maps.patientName != null">
+                and p.patient_name like concat('%', #{maps.patientName}, '%')
+            </if>
+            <if test="maps.doctorName != null">
+                and d.doctor_name like concat('%', #{maps.doctorName}, '%')
+            </if>
+            <if test="maps.orderType != null">
+                and so.order_type = #{maps.orderType}
+            </if>
+            <if test="maps.deliverySendsTime != null">
+                and DATE(so.delivery_send_time) &gt;= DATE(#{maps.deliverySendsTime})
+            </if>
+            <if test="maps.deliverySendeTime != null">
+                and DATE(so.delivery_send_time) &lt;= DATE(#{maps.deliverySendeTime})
+            </if>
+            <if test="maps.deliveryImportsTime != null">
+                and DATE(so.delivery_import_time) &gt;= DATE(#{maps.deliveryImportsTime})
+            </if>
+            <if test="maps.deliveryImporteTime != null">
+                and DATE(so.delivery_import_time) &lt;= DATE(#{maps.deliveryImporteTime})
+            </if>
+            <if test="maps.tuisTime != null">
+                and DATE(so.tui_money_time) &gt;= DATE(#{maps.tuisTime})
+            </if>
+            <if test="maps.tuieTime != null">
+                and DATE(so.tui_money_time) &lt;= DATE(#{maps.tuieTime})
+            </if>
+            <if test="maps.companyUserNickName != null and  maps.companyUserNickName !=''">
+                and cu.nick_name like concat( #{maps.companyUserNickName}, '%')
+            </if>
+            <if test="maps.companyIds != null and  maps.companyIds.size >0">
+                and so.company_id in
+                <foreach collection="maps.companyIds" item="companyId" open="(" close=")" separator=",">
+                    #{companyId}
+                </foreach>
+            </if>
+            <if test="maps.companyId != null and  maps.companyId != -1">
+                and so.company_id =#{maps.companyId}
+            </if>
+            <if test="maps.companyId == -1">
+                and so.company_id is null
+            </if>
+            <if test="maps.deliveryStatus != null">
+                and so.delivery_status =#{maps.deliveryStatus}
+            </if>
+            <if test="maps.customerId != null">
+                and so.customer_id =#{maps.customerId}
+            </if>
+            <if test="maps.deliveryPayStatus != null">
+                and so.delivery_pay_status =#{maps.deliveryPayStatus}
+            </if>
+            <if test="maps.tuiMoneyStatus != null">
+                and so.tui_money_status =#{maps.tuiMoneyStatus}
+            </if>
+            <if test="maps.deptId != null">
+                AND (so.dept_id = #{maps.deptId} OR so.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{maps.deptId}, ancestors) ))
+            </if>
+            <if test="maps.packageName != null and maps.packageName != ''">
+                and so.package_name like concat('%', #{maps.packageName}, '%')
+            </if>
+            <if test="maps.payType != null">
+                and so.pay_type IN
+                <foreach collection="maps.payType.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.scheduleId != null  and  maps.scheduleId != -1">
+                and so.schedule_id IN
+                <foreach collection="maps.scheduleId.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.scheduleId == -1">
+                and so.schedule_id is null
+            </if>
+            <if test="maps.orderBuyType != null and maps.orderBuyType != -1">
+                and so.order_buy_type IN
+                <foreach collection="maps.orderBuyType.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.orderBuyType == -1">
+                and so.order_buy_type is null
+            </if>
+            <if test="maps.orderChannel == -1">
+                and so.order_channel is null
+            </if>
+            <if test="maps.orderChannel != null and maps.orderChannel != -1">
+                and so.order_channel IN
+                <foreach collection="maps.orderChannel.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.qwSubject == -1">
+                and so.qw_subject is null
+            </if>
+            <if test="maps.qwSubject != null and maps.qwSubject != -1">
+                and so.qw_subject IN
+                <foreach collection="maps.qwSubject.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.erpPhoneNumber != null and maps.erpPhoneNumber != ''">
+                and so.erp_phone like concat(#{maps.erpPhoneNumber},'%')
+            </if>
+            <if test="maps.erpAccount != null and maps.erpAccount != '未分拣' and maps.erpAccount != ''">
+                and df.login_account like #{maps.erpAccount}
+            </if>
+            <if test="maps.erpAccount == '未分拣'">
+                and ( df.login_account is null or df.login_account like '')
+            </if>
+
+        </where>
+        ${maps.params.dataScope}
+    </select>
+    <select id="selectFsStoreOrderProductStatistics" resultType="java.lang.String">
+        SELECT GROUP_CONCAT(
+        CONCAT(product_name, ':', product_num)
+        ORDER BY product_name
+        SEPARATOR '   '
+        ) AS product_num_list
+        FROM (
+        SELECT sp.product_name,SUM(IF(soi.num IS NULL,0,soi.num)) product_num FROM fs_store_product sp
+        INNER JOIN fs_store_order_item soi ON soi.product_id = sp.product_id
+        INNER JOIN fs_store_order so ON soi.order_id = so.order_id
+        LEFT JOIN fs_user us ON us.user_id=so.user_id
+        LEFT JOIN fs_prescribe p ON p.prescribe_id =so.prescribe_id
+        LEFT JOIN fs_doctor d ON so.doctor_id= d.doctor_id
+        LEFT JOIN company_user cu on cu.user_id=so.company_user_id
+        LEFT JOIN fs_store_order_df df on df.order_id=so.order_id
+        <where>
+            <if test="maps.packageSecondName != null and maps.packageSecondName != ''">
+                and so.package_second_name like concat('%', #{maps.packageSecondName}, '%')
+            </if>
+            <if test="maps.storeId != null">
+                and so.store_id = #{maps.storeId}
+            </if>
+            <if test="maps.orderCodes != null  and maps.orderCodes.size > 0">
+                and so.order_code in
+                <foreach collection="maps.orderCodes" item="orderCode" open="(" close=")" separator=",">
+                    #{orderCode}
+                </foreach>
+            </if>
+            <if test="maps.orderCode != null  and maps.orderCode != ''">
+                and so.order_code = #{maps.orderCode}
+            </if>
+            <if test="maps.prescribeCode != null  and maps.prescribeCode != ''">
+                and p.prescribe_code = #{maps.prescribeCode}
+            </if>
+            <if test="maps.userName != null  and maps.userName != ''">
+                and so.user_name like concat('%', #{maps.userName}, '%')
+            </if>
+            <if test="maps.userPhone != null  and maps.userPhone != ''">
+                and so.user_phone = #{maps.userPhone}
+            </if>
+            <if test="maps.userId != null ">
+                and so.user_id = #{maps.userId}
+            </if>
+            <if test="maps.isFirst != null">
+                and so.is_first = #{maps.isFirst}
+            </if>
+            <if test="maps.status != null and maps.status != 6">
+                and so.status = #{maps.status}
+            </if>
+            <if test="maps.status == 6">
+                and so.`status`= 2
+                and (
+                so.store_id in (select store_id from fs_store where delivery_type=2 or delivery_type=1)
+                )
+                and  (so.extend_order_id is null or  so.extend_order_id like '')
+            </if>
+            <if test="maps.source != null">
+                and so.source = #{maps.source}
+            </if>
+            <if test="maps.deliverySn != null  and maps.deliverySn != ''">
+                and so.delivery_sn = #{maps.deliverySn}
+            </if>
+            <if test="maps.prescribeId != null">
+                and so.prescribe_id = #{maps.prescribeId}
+            </if>
+            <if test="maps.companyUserId != null">
+                and so.company_user_id = #{maps.companyUserId}
+            </if>
+            <if test="maps.sTime != null">
+                and DATE(so.create_time) &gt;= DATE(#{maps.sTime})
+            </if>
+            <if test="maps.eTime != null">
+                and DATE(so.create_time) &lt;= DATE(#{maps.eTime})
+            </if>
+            <if test="maps.paysTime != null">
+                and DATE(so.pay_time) &gt;= DATE(#{maps.paysTime})
+            </if>
+            <if test="maps.payeTime != null">
+                and DATE(so.pay_time) &lt;= DATE(#{maps.payeTime})
+            </if>
+            <if test="maps.orderCreateType != null">
+                and so.order_create_type = #{maps.orderCreateType}
+            </if>
+            <if test="maps.patientName != null">
+                and p.patient_name like concat('%', #{maps.patientName}, '%')
+            </if>
+            <if test="maps.doctorName != null">
+                and d.doctor_name like concat('%', #{maps.doctorName}, '%')
+            </if>
+            <if test="maps.orderType != null">
+                and so.order_type = #{maps.orderType}
+            </if>
+            <if test="maps.deliverySendsTime != null">
+                and DATE(so.delivery_send_time) &gt;= DATE(#{maps.deliverySendsTime})
+            </if>
+            <if test="maps.deliverySendeTime != null">
+                and DATE(so.delivery_send_time) &lt;= DATE(#{maps.deliverySendeTime})
+            </if>
+            <if test="maps.deliveryImportsTime != null">
+                and DATE(so.delivery_import_time) &gt;= DATE(#{maps.deliveryImportsTime})
+            </if>
+            <if test="maps.deliveryImporteTime != null">
+                and DATE(so.delivery_import_time) &lt;= DATE(#{maps.deliveryImporteTime})
+            </if>
+            <if test="maps.tuisTime != null">
+                and DATE(so.tui_money_time) &gt;= DATE(#{maps.tuisTime})
+            </if>
+            <if test="maps.tuieTime != null">
+                and DATE(so.tui_money_time) &lt;= DATE(#{maps.tuieTime})
+            </if>
+            <if test="maps.companyUserNickName != null and  maps.companyUserNickName !=''">
+                and cu.nick_name like concat( #{maps.companyUserNickName}, '%')
+            </if>
+            <if test="maps.companyIds != null and  maps.companyIds.size >0">
+                and so.company_id in
+                <foreach collection="maps.companyIds" item="companyId" open="(" close=")" separator=",">
+                    #{companyId}
+                </foreach>
+            </if>
+            <if test="maps.companyId != null and  maps.companyId != -1">
+                and so.company_id =#{maps.companyId}
+            </if>
+            <if test="maps.companyId == -1">
+                and so.company_id is null
+            </if>
+            <if test="maps.deliveryStatus != null">
+                and so.delivery_status =#{maps.deliveryStatus}
+            </if>
+            <if test="maps.customerId != null">
+                and so.customer_id =#{maps.customerId}
+            </if>
+            <if test="maps.deliveryPayStatus != null">
+                and so.delivery_pay_status =#{maps.deliveryPayStatus}
+            </if>
+            <if test="maps.tuiMoneyStatus != null">
+                and so.tui_money_status =#{maps.tuiMoneyStatus}
+            </if>
+            <if test="maps.deptId != null">
+                AND (so.dept_id = #{maps.deptId} OR so.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{maps.deptId}, ancestors) ))
+            </if>
+            <if test="maps.packageName != null and maps.packageName != ''">
+                and so.package_name like concat('%', #{maps.packageName}, '%')
+            </if>
+            <if test="maps.payType != null">
+                and so.pay_type IN
+                <foreach collection="maps.payType.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.scheduleId != null  and  maps.scheduleId != -1">
+                and so.schedule_id IN
+                <foreach collection="maps.scheduleId.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.scheduleId == -1">
+                and so.schedule_id is null
+            </if>
+            <if test="maps.orderBuyType != null and maps.orderBuyType != -1">
+                and so.order_buy_type IN
+                <foreach collection="maps.orderBuyType.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.orderBuyType == -1">
+                and so.order_buy_type is null
+            </if>
+            <if test="maps.orderChannel == -1">
+                and so.order_channel is null
+            </if>
+            <if test="maps.orderChannel != null and maps.orderChannel != -1">
+                and so.order_channel IN
+                <foreach collection="maps.orderChannel.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.qwSubject == -1">
+                and so.qw_subject is null
+            </if>
+            <if test="maps.qwSubject != null and maps.qwSubject != -1">
+                and so.qw_subject IN
+                <foreach collection="maps.qwSubject.split(',')" item="item" index="index" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="maps.erpPhoneNumber != null and maps.erpPhoneNumber != ''">
+                and so.erp_phone like concat(#{maps.erpPhoneNumber},'%')
+            </if>
+            <if test="maps.erpAccount != null and maps.erpAccount != '未分拣' and maps.erpAccount != ''">
+                and df.login_account like #{maps.erpAccount}
+            </if>
+            <if test="maps.erpAccount == '未分拣'">
+                and ( df.login_account is null or df.login_account like '')
+            </if>
+
+        </where>
+        ${maps.params.dataScope} GROUP BY sp.product_id
+        ) AS t
+
+
     </select>
 
 

+ 1 - 1
fs-service/src/main/resources/mapper/store/FsUserCourseCountMapper.xml

@@ -167,7 +167,7 @@
             DATE (fwl.create_time ) AS lastDate
         FROM fs_course_watch_log fwl
         left join fs_user_company_user ucu on ucu.user_id = fwl.user_id
-        where fwl.send_type = 1 and fwl.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL 7 DAY) and fwl.project = ucu.project_id
+        where fwl.send_type = 1 and fwl.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL 15 DAY) and fwl.project = ucu.project_id
         GROUP BY
             fwl.user_id, date(fwl.create_time),ucu.project_id
     </select>

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

@@ -281,6 +281,7 @@ public class FsStoreOrderController extends BaseController
     @PutMapping("/afterSales")
     public AjaxResult afterSales(@RequestBody FsStoreOrderSalesParam fsStoreOrder)
     {
+        fsStoreOrder.setOperator("店铺");
         return toAjax(fsStoreOrderService.afterSales(fsStoreOrder));
     }
 

+ 82 - 9
fs-user-app/src/main/java/com/fs/app/controller/PatientController.java

@@ -2,16 +2,21 @@ package com.fs.app.controller;
 
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.app.annotation.Login;
 import com.fs.app.param.FsPatientAddEditParam;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.config.StoreConfig;
 import com.fs.his.domain.FsPatient;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.service.IFsPatientService;
 import com.fs.his.service.IFsUserIntegralLogsService;
+import com.fs.his.utils.IdCardUtil;
+import com.fs.system.service.ISysConfigService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -38,6 +43,8 @@ public class PatientController extends  AppBaseController {
     private IFsPatientService patientService;
     @Autowired
     private IFsUserIntegralLogsService userIntegralLogsService;
+    @Autowired
+    private ISysConfigService configService;
 
     @Login
     @ApiOperation("获取病人列表")
@@ -77,15 +84,34 @@ public class PatientController extends  AppBaseController {
     @ApiOperation("添加病人")
     @PostMapping("/addPatient")
     public R addPatient(@Valid @RequestBody FsPatientAddEditParam param, HttpServletRequest request){
+        String json = configService.selectConfigByKey("his.store");
+        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+        Integer isIdVerification = storeConfig.getIsIdVerification();
 
         String idCardNumber = param.getIdCard(); // 替换为要验证的身份证号码
-        if (idCardNumber == null || idCardNumber.length() != 18) {
+        String mobile = param.getMobile();
+        if (idCardNumber == null || idCardNumber.trim().isEmpty()) {
             return R.error("身份证号码不合法");
         }
-        String regex = "\\d{17}[0-9Xx]";
-        if (!Pattern.matches(regex, idCardNumber)) {
-            return   R.error("身份证号码不合法");
+        if (idCardNumber.length() != 18) {
+//            //大陆身份证是18位
+//            if (isIdVerification != 1) {
+//                return R.error("身份证号码不合法");
+//            } else {
+//                //非大陆身份校验需要手机号 手机号只支持大陆的办理的手机号
+//                if (StringUtils.isBlank(mobile)){
+//                    R.error("手机号不能为空");
+//                }
+//            }
+            //暂时仅支持大陆身份证
+            return  R.error("身份证号码不合法");
+        } else {
+            String regex = "\\d{17}[0-9Xx]";
+            if (!Pattern.matches(regex, idCardNumber)) {
+                return   R.error("身份证号码不合法");
+            }
         }
+
         if (param.getPatientName().length()<2||param.getPatientName().length()>30||!param.getPatientName().matches("^[\u4e00-\u9fa5]+$")) {
             return   R.error("就诊人名称不合法");
         }
@@ -127,6 +153,19 @@ public class PatientController extends  AppBaseController {
             return   R.error("身份证校验错误");
         }
 
+        //三方校验
+        if (isIdVerification == 1){
+            boolean match = true;
+            if (idCardNumber.length() != 18) {
+                match = IdCardUtil.isMatchByMobile(storeConfig,param.getPatientName(), mobile);
+            } else {
+                match = IdCardUtil.isMatchById(storeConfig,param.getPatientName(), param.getIdCard());
+            }
+            if (!match){
+                return R.error("身份证校验错误");
+            }
+        }
+
         FsPatient patient=new FsPatient();
         BeanUtil.copyProperties(param, patient);
         patient.setUserId(Long.parseLong(getUserId()));
@@ -148,14 +187,34 @@ public class PatientController extends  AppBaseController {
     @ApiOperation("编辑病人")
     @PostMapping("/editPatient")
     public R editPatient(@Valid @RequestBody FsPatientAddEditParam param, HttpServletRequest request){
+        String json = configService.selectConfigByKey("his.store");
+        StoreConfig storeConfig = JSONUtil.toBean(json, StoreConfig.class);
+        Integer isIdVerification = storeConfig.getIsIdVerification();
+        String mobile = param.getMobile();
+
         String idCardNumber = param.getIdCard(); // 替换为要验证的身份证号码
-        if (idCardNumber == null || idCardNumber.length() != 18) {
-            throw new CustomException("身份证号码不合法");
+        if (idCardNumber == null || idCardNumber.trim().isEmpty()) {
+            return R.error("身份证号码不合法");
         }
-        String regex = "\\d{17}[0-9Xx]";
-        if (!Pattern.matches(regex, idCardNumber)) {
-            throw new CustomException("身份证号码不合法");
+        if (idCardNumber.length() != 18) {
+//            //大陆身份证是18位
+//            if (isIdVerification != 1) {
+//                return R.error("身份证号码不合法");
+//            } else {
+//                //非大陆身份校验需要手机号 手机号只支持大陆的办理的手机号
+//                if (StringUtils.isBlank(mobile)){
+//                    R.error("手机号不能为空");
+//                }
+//            }
+            //暂时仅支持大陆身份证
+            return  R.error("身份证号码不合法");
+        } else {
+            String regex = "\\d{17}[0-9Xx]";
+            if (!Pattern.matches(regex, idCardNumber)) {
+                return   R.error("身份证号码不合法");
+            }
         }
+
         if (param.getPatientName().length()<2||param.getPatientName().length()>30||!param.getPatientName().matches("^[\u4e00-\u9fa5]+$")) {
             return   R.error("就诊人名称不合法");
         }
@@ -191,6 +250,20 @@ public class PatientController extends  AppBaseController {
 //        if (age2 > 200) {
 //            throw new CustomException("年龄超过200岁");
 //        }
+
+        //三方校验
+        if (isIdVerification == 1){
+            boolean match = true;
+            if (idCardNumber.length() != 18) {
+                match = IdCardUtil.isMatchByMobile(storeConfig,param.getPatientName(), mobile);
+            } else {
+                match = IdCardUtil.isMatchById(storeConfig,param.getPatientName(), param.getIdCard());
+            }
+            if (!match){
+                return R.error("身份证校验错误");
+            }
+        }
+
         FsPatient patient=new FsPatient();
         BeanUtil.copyProperties(param, patient);
         patientService.updateFsPatient(patient);

+ 2 - 2
fs-user-app/src/main/resources/application.yml

@@ -6,10 +6,10 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: dev
+#    active: dev
 #    active: druid-jzzx
 #    active: druid-yzt
 #    active: druid-hdt
 #    active: druid-sxjz
 #    active: druid-yzt
-#    active: druid-fcky-test
+    active: druid-jnmy-test