瀏覽代碼

需求表需求调整

wangxy 1 周之前
父節點
當前提交
8e7f3a17de
共有 24 個文件被更改,包括 952 次插入178 次删除
  1. 42 0
      fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java
  2. 15 0
      fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java
  3. 11 0
      fs-admin/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java
  4. 19 0
      fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java
  5. 14 0
      fs-company/src/main/java/com/fs/company/controller/course/FsCourseWatchLogController.java
  6. 13 0
      fs-company/src/main/java/com/fs/company/controller/course/qw/FsQwCourseWatchLogController.java
  7. 10 4
      fs-company/src/main/java/com/fs/company/controller/store/FsStoreOrderController.java
  8. 115 2
      fs-company/src/main/java/com/fs/hisStore/controller/FsStoreStatisticsScrmController.java
  9. 31 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  10. 2 0
      fs-service/src/main/java/com/fs/course/param/FsCourseWatchLogStatisticsListParam.java
  11. 70 34
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  12. 2 2
      fs-service/src/main/java/com/fs/his/mapper/FsPackageOrderMapper.java
  13. 9 0
      fs-service/src/main/java/com/fs/his/param/FsPackageOrderAddParam.java
  14. 7 0
      fs-service/src/main/java/com/fs/his/service/IFsStoreOrderService.java
  15. 232 99
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  16. 15 1
      fs-service/src/main/java/com/fs/his/vo/FsCourseReportVO.java
  17. 9 0
      fs-service/src/main/java/com/fs/his/vo/FsOrderReportVO.java
  18. 18 0
      fs-service/src/main/java/com/fs/his/vo/FsPackageOrderExcelVO.java
  19. 12 4
      fs-service/src/main/java/com/fs/his/vo/FsPackageOrderReportVO.java
  20. 17 1
      fs-service/src/main/java/com/fs/his/vo/FsUserReportVO.java
  21. 26 0
      fs-service/src/main/java/com/fs/his/vo/WatchLogReportVO.java
  22. 38 0
      fs-service/src/main/java/com/fs/qw/vo/QwWatchLogAllStatisticsListVO.java
  23. 224 30
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  24. 1 1
      fs-service/src/main/resources/mapper/his/FsPackageOrderMapper.xml

+ 42 - 0
fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java

@@ -1,6 +1,7 @@
 package com.fs.company.controller;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fs.common.annotation.Excel;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -38,6 +39,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -752,6 +754,23 @@ public class CompanyStatisticsController extends BaseController {
         return getDataTable(list);
     }
 
+    @GetMapping("/exportFsOrderReportVO")
+    public  AjaxResult exportOrderReport(FsPackageOrderParam param) {
+        startPage();
+        List<FsOrderReportVO> list = fsPackageOrderService.selectFsOrderReportVO(param);
+        List<String> allFields = Arrays.stream(FsOrderReportVO.class.getDeclaredFields())
+                .filter(field -> field.isAnnotationPresent(Excel.class))
+                .map(Field::getName)
+                .collect(Collectors.toList());
+        if("company".equals(param.getDimension())){
+            allFields.removeIf(field -> field.contains("dept"));
+        }else {
+            allFields.removeIf(field -> field.contains("company"));
+        }
+        ExcelUtil<FsOrderReportVO> util = new ExcelUtil<FsOrderReportVO>(FsOrderReportVO.class);
+        return util.exportExcelSelectedColumns(list, "收款统计报表", allFields);
+    }
+
     /**
      * 课程统计报表
      *
@@ -822,6 +841,21 @@ public class CompanyStatisticsController extends BaseController {
         return getDataTable(fsCourseReportVOS);
     }
 
+    @GetMapping("/exportFsCourseReportVO")
+    public AjaxResult exportFsCourseReportVO(FsCourseWatchLogStatisticsListParam param) {
+        List<FsCourseReportVO> list = fsCourseWatchLogService.selectFsCourseReportVO(param);
+        List<String> allFields = Arrays.stream(FsCourseReportVO.class.getDeclaredFields())
+                .filter(field -> field.isAnnotationPresent(Excel.class))
+                .map(Field::getName)
+                .collect(Collectors.toList());
+        // 如果是公司类型,过滤训练营字段
+        if ("company".equals(param.getDimension())) {
+            allFields.removeIf(field -> field.contains("camp") || field.contains("period"));
+        }
+        ExcelUtil<FsCourseReportVO> util = new ExcelUtil<FsCourseReportVO>(FsCourseReportVO.class);
+        return util.exportExcelSelectedColumns(list, "会员看课统计报表", allFields);
+    }
+
     /**
      * 用户统计报表
      *
@@ -873,4 +907,12 @@ public class CompanyStatisticsController extends BaseController {
 //        result.put("total", totalVo);
         return getDataTable(list);
     }
+
+    @GetMapping("/exportUserReport")
+    public  AjaxResult exportFsUserReportVO(FsCourseWatchLogStatisticsListParam param) {
+        startPage();
+        List<FsUserReportVO> list = fsCourseWatchLogService.selectFsUserReportVO(param);
+        ExcelUtil<FsUserReportVO> util = new ExcelUtil<FsUserReportVO>(FsUserReportVO.class);
+        return util.exportExcel(list, "会员积分报表");
+    }
 }

+ 15 - 0
fs-admin/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java

@@ -14,6 +14,7 @@ import com.fs.course.vo.FsCourseWatchLogListVO;
 import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
 import com.fs.qw.param.QwWatchLogStatisticsListParam;
 import com.fs.qw.service.IQwWatchLogService;
+import com.fs.qw.vo.QwWatchLogAllStatisticsListVO;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -73,6 +74,20 @@ public class FsCourseWatchLogController extends BaseController
         }
         return qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
     }
+
+    @GetMapping("/qwWatchLogAllStatisticsExport")
+    public AjaxResult qwWatchLogAllStatisticsExport(QwWatchLogStatisticsListParam param){
+        if(param.getCompanyId() == null){
+            throw new CustomException("必须选择公司!");
+        }
+        if (param.getSTime()==null||param.getETime()==null){
+            AjaxResult.error("必须选择时间");
+        }
+        TableDataInfo tableDataInfo = qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
+        List<QwWatchLogAllStatisticsListVO> rows = (List<QwWatchLogAllStatisticsListVO>) tableDataInfo.getRows();
+        ExcelUtil<QwWatchLogAllStatisticsListVO> util = new ExcelUtil<QwWatchLogAllStatisticsListVO>(QwWatchLogAllStatisticsListVO.class);
+        return util.exportExcel(rows, "会员课程数据汇总");
+    }
     @GetMapping("/qwWatchLogStatisticsList")
     public TableDataInfo qwWatchLogStatisticsList(QwWatchLogStatisticsListParam param)
     {

+ 11 - 0
fs-admin/src/main/java/com/fs/course/controller/qw/QwFsCourseWatchLogController.java

@@ -68,6 +68,17 @@ public class QwFsCourseWatchLogController extends BaseController
         return getDataTable(list);
     }
 
+    @GetMapping("/qwWatchLogAllStatisticsExport")
+    public AjaxResult qwWatchLogAllStatisticsExport(QwWatchLogStatisticsListParam param){
+        startPage();
+        if (param.getSTime()==null||param.getETime()==null){
+            return AjaxResult.error("必须选择时间");
+        }
+        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVO(param);
+        ExcelUtil<QwWatchLogAllStatisticsListVO> util = new ExcelUtil<QwWatchLogAllStatisticsListVO>(QwWatchLogAllStatisticsListVO.class);
+        return util.exportExcel(list, "企微课程数据汇总");
+    }
+
     @PreAuthorize("@ss.hasPermi('course:courseWatchLog:statisticsList')")
     @GetMapping("/statisticsList")
     public TableDataInfo statisticsList(FsCourseWatchLogStatisticsListParam param)

+ 19 - 0
fs-admin/src/main/java/com/fs/his/controller/FsPackageOrderController.java

@@ -1,8 +1,11 @@
 package com.fs.his.controller;
 
+import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
+import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.SecurityUtils;
@@ -107,6 +110,22 @@ public class FsPackageOrderController extends BaseController
         return getDataTable(list);
     }
 
+    @GetMapping("/exportPackageReport")
+    public  AjaxResult exportPackageReport(FsPackageOrderParam param) {
+        startPage();
+        List<FsPackageOrderReportVO> list = fsPackageOrderService.selectFsPackageOrderReportVO(param);
+        List<String> allFields = Arrays.stream(FsPackageOrderReportVO.class.getDeclaredFields())
+                .filter(field -> field.isAnnotationPresent(Excel.class))
+                .map(Field::getName)
+                .collect(Collectors.toList());
+        if("company".equals(param.getDimension())){
+            allFields.removeIf(field -> field.contains("dept"));
+        }else {
+            allFields.removeIf(field -> field.contains("company"));
+        }
+        ExcelUtil<FsPackageOrderReportVO> util = new ExcelUtil<FsPackageOrderReportVO>(FsPackageOrderReportVO.class);
+        return util.exportExcelSelectedColumns(list, "订单类报表", allFields);
+    }
 
     /**
      * 导出套餐订单列表

+ 14 - 0
fs-company/src/main/java/com/fs/company/controller/course/FsCourseWatchLogController.java

@@ -279,6 +279,20 @@ public class FsCourseWatchLogController extends BaseController
         }
         return qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
     }
+
+    @GetMapping("/qwWatchLogAllStatisticsExport")
+    public  AjaxResult qwWatchLogAllStatisticsExport(QwWatchLogStatisticsListParam param)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId( loginUser.getCompany().getCompanyId());
+        if (param.getSTime()==null||param.getETime()==null){
+            return AjaxResult.error("请选择时间");
+        }
+        TableDataInfo tableDataInfo = qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
+        List<QwWatchLogAllStatisticsListVO> rows = (List<QwWatchLogAllStatisticsListVO>) tableDataInfo.getRows();
+        ExcelUtil<QwWatchLogAllStatisticsListVO> util = new ExcelUtil<QwWatchLogAllStatisticsListVO>(QwWatchLogAllStatisticsListVO.class);
+        return util.exportExcel(rows, "会员课程数据汇总导出");
+    }
     @GetMapping("/myQwWatchLogAllStatisticsList")
     public TableDataInfo myQwWatchLogAllStatisticsList(QwWatchLogStatisticsListParam param)
     {

+ 13 - 0
fs-company/src/main/java/com/fs/company/controller/course/qw/FsQwCourseWatchLogController.java

@@ -146,6 +146,19 @@ public class FsQwCourseWatchLogController extends BaseController
         List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVO(param);
         return getDataTable(list);
     }
+
+
+    @GetMapping("/qwWatchLogAllStatisticsExport")
+    public  AjaxResult qwWatchLogAllStatisticsExport(QwWatchLogStatisticsListParam param){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId( loginUser.getCompany().getCompanyId());
+        if (param.getSTime()==null||param.getETime()==null){
+          AjaxResult.error("请选择日期");
+        }
+        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVO(param);
+        ExcelUtil<QwWatchLogAllStatisticsListVO> util = new ExcelUtil<QwWatchLogAllStatisticsListVO>(QwWatchLogAllStatisticsListVO.class);
+        return util.exportExcel(list, "企微课程汇总数据导出");
+    }
     @GetMapping("/myQwWatchLogAllStatisticsList")
     public TableDataInfo myQwWatchLogAllStatisticsList(QwWatchLogStatisticsListParam param)
     {

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

@@ -21,10 +21,7 @@ import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.*;
 import com.fs.his.dto.ExpressInfoDTO;
 import com.fs.his.enums.ShipperCodeEnum;
-import com.fs.his.param.FsFollowMsgParam;
-import com.fs.his.param.FsStoreOrderBindCustomerParam;
-import com.fs.his.param.FsStoreOrderParam;
-import com.fs.his.param.FsStoreOrderSalesParam;
+import com.fs.his.param.*;
 import com.fs.his.service.IFsExportTaskService;
 import com.fs.his.service.IFsExpressService;
 import com.fs.his.service.IFsStoreOrderService;
@@ -368,6 +365,15 @@ public class FsStoreOrderController extends BaseController
         return R.ok();
     }
 
+    @Log(title = "手动创建订单", businessType = BusinessType.INSERT)
+    @PostMapping("/createOrderByManually")
+    @PreAuthorize("@ss.hasPermi('his:storeOrder:addManually')")
+    public  R createOrderByManually( @RequestBody FsPackageOrderAddParam param){
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        param.setCompanyUserId(loginUser.getUser().getUserId());
+        return fsStoreOrderService.createOrderByManually(param);
+    }
 
     /**
      * 推送到智慧药房

+ 115 - 2
fs-company/src/main/java/com/fs/hisStore/controller/FsStoreStatisticsScrmController.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.controller;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fs.common.annotation.Excel;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -15,6 +16,8 @@ import com.fs.course.param.FsCourseWatchLogStatisticsListParam;
 import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
+import com.fs.his.vo.FsUserReportVO;
+import com.fs.his.vo.WatchLogReportVO;
 import com.fs.hisStore.param.FsStoreStatisticsParam;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.service.IFsStorePaymentScrmService;
@@ -26,8 +29,8 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.lang.reflect.Field;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -195,6 +198,16 @@ public class FsStoreStatisticsScrmController extends BaseController {
         return getDataTable(courseWatchLogService.selectFsUserReportVO(param));
     }
 
+    @GetMapping("/userReportExport")
+    public  AjaxResult userReportExport(FsCourseWatchLogStatisticsListParam param) {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<FsUserReportVO> list = courseWatchLogService.selectFsUserReportVO(param);
+        ExcelUtil<FsUserReportVO> util = new ExcelUtil<FsUserReportVO>(FsUserReportVO.class);
+        return util.exportExcel(list, "会员积分报表");
+    }
+
     /**
      * 看课统计报表
      */
@@ -206,4 +219,104 @@ public class FsStoreStatisticsScrmController extends BaseController {
         return getDataTable(courseWatchLogService.selectWatchLogReportVO(param));
     }
 
+    @GetMapping("/watchLogReportExport")
+    public AjaxResult watchLogReportExport(FsCourseWatchLogStatisticsListParam param) {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<WatchLogReportVO> list = courseWatchLogService.selectWatchLogReportVO(param);
+        // 过滤掉所有字段都为空的对象
+        List<String> selectedFields = getOrderedFieldsWithData(list,param.getDimension());
+        ExcelUtil<WatchLogReportVO> util = new ExcelUtil<WatchLogReportVO>(WatchLogReportVO.class);
+        return util.exportExcelSelectedColumns(list,"看课统计报表",selectedFields);
+    }
+
+    /**
+     * 获取所有有数据的字段名称列表(按注解sort排序,根据type过滤特定字段)
+     * @param list 数据列表
+     * @param type 类型:sales-销售, company-公司
+     */
+    private List<String> getOrderedFieldsWithData(List<WatchLogReportVO> list, String type) {
+        if (list == null || list.isEmpty()) {
+            return new ArrayList<>();
+        }
+
+        // 收集所有有Excel注解的字段,并按sort排序
+        List<Field> excelFields = Arrays.stream(WatchLogReportVO.class.getDeclaredFields())
+                .filter(field -> field.isAnnotationPresent(Excel.class))
+                .sorted(Comparator.comparingInt(field -> field.getAnnotation(Excel.class).sort()))
+                .collect(Collectors.toList());
+
+        // 过滤出有数据的字段
+        List<String> fieldsWithData = excelFields.stream()
+                .filter(field -> hasAnyData(list, field))
+                .map(Field::getName)
+                .collect(Collectors.toList());
+
+        // 根据type参数过滤特定字段
+        return filterFieldsByType(fieldsWithData, type);
+    }
+
+    /**
+     * 根据类型过滤字段
+     */
+    private List<String> filterFieldsByType(List<String> fields, String type) {
+        if (type == null) {
+            return fields;
+        }
+
+        List<String> filteredFields = new ArrayList<>(fields);
+
+        switch (type.toLowerCase()) {
+            case "sales":
+                // 销售类型:过滤掉会员ID和销售数字段
+                filteredFields.removeIf(field ->
+                        field.equals("userId") ||
+                                field.equals("会员id") ||
+                                field.equals("salesCount") ||
+                                field.equals("销售数"));
+                break;
+
+            case "company":
+                // 公司类型:过滤掉会员ID和所属销售字段
+                filteredFields.removeIf(field ->
+                        field.equals("userId") ||
+                                field.equals("会员id") ||
+                                field.equals("salesName") ||
+                                field.equals("所属销售"));
+                break;
+
+            default:
+                // 其他类型不进行额外过滤
+                break;
+        }
+
+        return filteredFields;
+    }
+
+    /**
+     * 检查字段是否有任意非空数据
+     */
+    private boolean hasAnyData(List<WatchLogReportVO> list, Field field) {
+        field.setAccessible(true);
+        for (WatchLogReportVO item : list) {
+            try {
+                Object value = field.get(item);
+                if (!isEmpty(value)) {
+                    return true;
+                }
+            } catch (IllegalAccessException e) {
+                // 忽略异常
+            }
+        }
+        return false;
+    }
+
+    private boolean isEmpty(Object value) {
+        if (value == null) return true;
+        if (value instanceof String) return ((String) value).trim().isEmpty();
+        if (value instanceof Number) return ((Number) value).doubleValue() == 0;
+        return false;
+    }
+
 }

+ 31 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -716,6 +716,37 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      */
     List<WatchLogReportVO>  selectCompanyBaseData(FsCourseWatchLogStatisticsListParam param);
 
+    /**
+     * 销售端看课报表 公司维度基础数据(优化版本)
+     * @param param
+     * @return
+     */
+    List<WatchLogReportVO> selectCompanyBaseDataOptimized(FsCourseWatchLogStatisticsListParam param);
+
+    /**
+     * 销售端看课报表 公司维度基础数据(带ID字段,用于assembleStatisticsData)
+     * @param param
+     * @return
+     */
+    List<WatchLogReportVO> selectCompanyBaseDataWithIds(FsCourseWatchLogStatisticsListParam param);
+
+
+    /**
+     * 查询所有部门ID(用于分批处理)
+     * @param param
+     * @return
+     */
+    List<Long> selectAllDeptIds(FsCourseWatchLogStatisticsListParam param);
+
+    /**
+     * 按部门分批查询看课统计数据
+     * @param param
+     * @return
+     */
+    List<WatchLogReportVO> selectWatchStatsByDeptBatch(FsCourseWatchLogStatisticsListParam param);
+
+
+
     /**
      * 销售端看课报表 营期训练营明细
      * @param

+ 2 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseWatchLogStatisticsListParam.java

@@ -94,5 +94,7 @@ public class FsCourseWatchLogStatisticsListParam extends BaseEntity {
      */
     private  List<Long> companyIds;
 
+    private  List<Long> deptIds;
+
 
 }

+ 70 - 34
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -1537,11 +1537,76 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
             case "sales":
                 return fsCourseWatchLogMapper.selectSalesBaseData(param);
             case "company":
-                return fsCourseWatchLogMapper.selectCompanyBaseData(param);
+                return getCompanyBaseDataOptimized(param);
             default:
                 return Collections.emptyList();
         }
     }
+    /**
+     * 优化后的公司维度基础数据查询
+     */
+    private List<WatchLogReportVO> getCompanyBaseDataOptimized(FsCourseWatchLogStatisticsListParam param) {
+        //查询部门基础信息
+        List<WatchLogReportVO> deptBaseData = fsCourseWatchLogMapper.selectCompanyBaseDataOptimized(param);
+
+        if (CollectionUtils.isEmpty(deptBaseData)) {
+            return Collections.emptyList();
+        }
+
+//        //获取所有符合条件的部门ID
+//        List<Long> allDeptIds = fsCourseWatchLogMapper.selectAllDeptIds(param);
+        List<Long> allDeptIds = deptBaseData.stream().map(WatchLogReportVO::getDeptId).collect(Collectors.toList());
+        param.setDeptIds(allDeptIds);
+
+        if (CollectionUtils.isEmpty(allDeptIds)) {
+            return Collections.emptyList();
+        }
+//        FsCourseWatchLogStatisticsListParam allDeptsParam = new FsCourseWatchLogStatisticsListParam();
+//        // 复制原有参数
+//        copyProperties(param, allDeptsParam);
+//        allDeptsParam.setDeptIds(allDeptIds);
+
+        // 一次性查询所有部门的统计数据
+        List<WatchLogReportVO> allStats = fsCourseWatchLogMapper.selectWatchStatsByDeptBatch(param);
+
+        // 7. 将统计数据转换为Map便于后续查找
+        Map<Long, WatchLogReportVO> statsMap = allStats.stream()
+                .collect(Collectors.toMap(WatchLogReportVO::getDeptId, Function.identity()));
+
+        // 7. 将统计数据合并到基础数据中
+        for (WatchLogReportVO item : deptBaseData) {
+            WatchLogReportVO stats = statsMap.get(item.getDeptId());
+            if (stats != null) {
+                item.setTotalLogCount(stats.getTotalLogCount());
+                item.setFinishedCount(stats.getFinishedCount());
+                item.setUnfinishedCount(stats.getUnfinishedCount());
+                item.setNotWatchedCount(stats.getNotWatchedCount());
+                item.setVideoTitle(stats.getVideoTitle());
+                item.setPeriodId(stats.getPeriodId());
+                item.setLogId(stats.getLogId());
+                item.setUserId(stats.getUserId());
+            }
+        }
+
+        return deptBaseData;
+    }
+    /**
+     * 复制参数属性的辅助方法
+     */
+    private void copyProperties(FsCourseWatchLogStatisticsListParam source, FsCourseWatchLogStatisticsListParam target) {
+        target.setCompanyId(source.getCompanyId());
+        target.setDeptId(source.getDeptId());
+        target.setTrainingCampId(source.getTrainingCampId());
+        target.setPeriodId(source.getPeriodId());
+        target.setUserId(source.getUserId());
+        target.setUserPhone(source.getUserPhone());
+        target.setNickName(source.getNickName());
+        target.setProject(source.getProject());
+        target.setSTime(source.getSTime());
+        target.setETime(source.getETime());
+        target.setOrderSTime(source.getOrderSTime());
+        target.setOrderETime(source.getOrderETime());
+    }
 
     /**
      * 组装统计数据
@@ -1553,7 +1618,6 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
 
         List<Long> userIds = baseData.stream().map(WatchLogReportVO::getUserId).collect(Collectors.toList());
 
-        List<Long> salesIds = baseData.stream().map(WatchLogReportVO::getCompanyUserId).collect(Collectors.toList());
 
         // 批量查询统计数据
         //营期数据
@@ -1563,14 +1627,6 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 fsCourseWatchLogMapper.selectRedPacketStats(logIds)
         );
 
-        Map<Long, WatchLogReportVO> memberMap = convertMemberToMap(
-                fsCourseWatchLogMapper.getSalesMemberStats(salesIds)
-        );
-
-        Map<Long, WatchLogReportVO> salesDeptMap = convertMemberToMap(
-                fsCourseWatchLogMapper.getSalesDeptCompanyInfo(salesIds,param)
-        );
-
         Map<Long, WatchLogReportVO> orderMap = convertOrderToMap(
                 fsCourseWatchLogMapper.selectOrderStats(userIds,param)
         );
@@ -1584,51 +1640,31 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
             if(!"user".equals(param.getDimension())){
                 //完课率
                 item.setCompletionRate(calculateCompletionRate(item));
-                //用户销售信息
-                WatchLogReportVO member = memberMap.get(item.getCompanyUserId());
-                if (member != null) {
-                    item.setUserCount(member.getUserCount());
-                    item.setOnlineUserCount(member.getOnlineUserCount());
-                    item.setSalesName(member.getSalesName());
-                }
-                WatchLogReportVO salesVo = salesDeptMap.get(item.getCompanyUserId());
-                if (salesVo != null) {
-                    item.setSalesDept(salesVo.getSalesDept());
-                    item.setSalesCompany(salesVo.getSalesCompany());
-                    item.setSalesCount(salesVo.getSalesCount());
-                }
             }
             // 营期数据
-            WatchLogReportVO watchStats = perMap.get(item.getPeriodId());
+            WatchLogReportVO watchStats = perMap.getOrDefault(item.getPeriodId(), null);
             if (watchStats != null) {
                 item.setPeriodName(watchStats.getPeriodName());
                 item.setTrainingCampName(watchStats.getTrainingCampName());
             }
             // 红包数据
-            WatchLogReportVO redPacketStats = redPacketMap.get(item.getLogId());
+            WatchLogReportVO redPacketStats = redPacketMap.getOrDefault(item.getLogId(),null);
             if (redPacketStats != null) {
                 item.setRedPacketAmount(redPacketStats.getRedPacketAmount());
             }
 
             // 订单数据
-            WatchLogReportVO order = orderMap.get(item.getUserId());
+            WatchLogReportVO order = orderMap.getOrDefault(item.getUserId(),null);
             if (order != null) {
                 item.setHistoryOrderCount(order.getHistoryOrderCount());
             }
 
             // 答题数据
-            WatchLogReportVO answer = answerMap.get(item.getLogId());
+            WatchLogReportVO answer = answerMap.getOrDefault(item.getLogId(),null);
             if (answer != null) {
                 setAnswerData(item, answer, param.getDimension());
             }
         }
-        //看课统计部门/公司 过滤销售会员匹配不到的数据
-        if (!"user".equals(param.getDimension())) {
-         return   baseData.stream()
-                    .filter(item -> memberMap.containsKey(item.getCompanyUserId()) &&
-                            salesDeptMap.containsKey(item.getCompanyUserId()))
-                    .collect(Collectors.toList());
-        }
         return baseData;
     }
 

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

@@ -122,7 +122,7 @@ public interface FsPackageOrderMapper
             " 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_package fp on fp.package_id = o.package_id  " +
-            " left join fs_store_order fo on fo.order_id = o.order_id " +
+            " left join fs_store_order fo on fo.order_id = o.store_order_id " +
             " where o.order_id=#{orderId}")
     FsPackageOrderVO selectFsPackageOrderByOrderIdVO(Long orderId);
 
@@ -148,7 +148,7 @@ public interface FsPackageOrderMapper
     @Select("SELECT * FROM fs_store_payment where business_id=#{orderId} and status=1 and business_type=3")
     List<FsStorePayment> selectFsPackagePaymentByOrderId(Long orderId);
     @Select({"<script> " +
-            "select o.order_id,o.order_sn,o.package_name,o.source,o.pay_time,o.follow_rate,o.cycle,o.follow_num,o.inquiry_cost_price,o.product_cost_price,o.total_cost_price,o.cost_discount_money,o.total_price,o.discount_money,o.pay_delivery,o.is_pay,o.remark, o.days,o.pay_price,o.pay_money,o.pay_type,o.`status`,o.package_sub_type,o.create_time,o.start_time,o.refund_status,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 ,csc.name miniProgramName 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.order_sn,o.package_name,o.source,o.pay_time,o.follow_rate,o.cycle,o.follow_num,o.inquiry_cost_price,o.product_cost_price,o.total_cost_price,o.cost_discount_money,o.total_price,o.discount_money,o.pay_delivery,o.is_pay,o.remark, o.days,o.pay_price,o.pay_money,o.pay_type,o.`status`,o.package_sub_type,o.create_time,o.start_time,o.refund_status,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,fso.user_name,fso.user_phone,fso.user_address,csc.name miniProgramName 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 "+
             "LEFT JOIN (SELECT sp.*,ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn\n" +
             "        FROM fs_store_payment sp) sp_latest ON sp_latest.business_code = o.order_sn AND sp_latest.rn = 1\n" +
             "        LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id" +

+ 9 - 0
fs-service/src/main/java/com/fs/his/param/FsPackageOrderAddParam.java

@@ -1,9 +1,12 @@
 package com.fs.his.param;
 
+import com.fs.common.annotation.Excel;
 import io.swagger.models.auth.In;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
 
 @Data
 public class FsPackageOrderAddParam {
@@ -15,4 +18,10 @@ public class FsPackageOrderAddParam {
     private Long addressId;
     private Long companyId;
     private Long companyUserId;
+
+    /** 支付金额 */
+    private BigDecimal payMoney;
+
+    /** 产品id */
+    private List<Long> productIds;
 }

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

@@ -104,6 +104,13 @@ public interface IFsStoreOrderService
 
     R createOrder(Long prescribeId);
 
+    /**
+     * 手动录入订单
+     * @param param
+     * @return
+     */
+    R createOrderByManually(FsPackageOrderAddParam param);
+
     R createOrderByPackageOrder(FsPackageOrder packageOrder);
 
     R payConfirm(String orderCode,String payCode, String tradeNo,String payType,Integer type,String bankTransactionId,String bankSerialNo);

+ 232 - 99
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -2,6 +2,7 @@ package com.fs.his.service.impl;
 
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.net.URLDecoder;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
@@ -150,6 +151,9 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     @Autowired
     private FsStoreOrderMapper fsStoreOrderMapper;
 
+    @Autowired
+    private FsPatientMapper fsPatientMapper;
+
     @Autowired
     private FsStoreOrderScrmMapper fsStoreOrderScrmMapper;
 
@@ -301,6 +305,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     private Map<Integer, IErpOrderService> erpServiceMap;
 
     private IFsStoreOrderScrmService orderScrmService;
+
     @PostConstruct
     public void initErpServiceMap() {
         erpServiceMap = new HashMap<>();
@@ -358,17 +363,18 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         //推送修改的互联网医院订单地址到聚水潭ERP
         try {
             pushOrderAddressToErp(fsStoreOrder);
-        }catch (Exception e){
+        } catch (Exception e) {
             log.error("修改互联网医院订单地址推送到聚水潭ERP失败,orderId: {}", fsStoreOrder.getOrderId(), e);
         }
         return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder);
     }
+
     /**
      * 推送修改订单的最新地址到 ERP
      *
      * @param partialOrder 前端传入的部分订单对象,必须包含 id、userAddress
      */
-    public void pushOrderAddressToErp(FsStoreOrder partialOrder){
+    public void pushOrderAddressToErp(FsStoreOrder partialOrder) {
         if (partialOrder == null || partialOrder.getOrderId() == null) {
             log.info("传入订单为空或ID缺失,跳过ERP同步");
             return;
@@ -387,7 +393,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             return;
         }
         //目前只针对聚水潭ERP推送最新的修改地址
-        if (erpType != 5){
+        if (erpType != 5) {
             return;
         }
         // 2. 从数据库获取完整订单(用于补全必要字段;当前是修改商城订单接口,查询fs_store_order_scrm表)
@@ -402,22 +408,22 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             return;
         }
         // 3. 构造用于ERP推送的订单对象:订单地址用传入的新值
-        if (StrUtil.isBlank(partialOrder.getUserAddress())){
+        if (StrUtil.isBlank(partialOrder.getUserAddress())) {
             log.error("修改互联网医院订单地址为空,orderId: {}", partialOrder.getOrderId());
             return;
         }
         dbOrder.setUserAddress(partialOrder.getUserAddress());
         // 4. 构建 ERP 订单对象
         try {
-        ErpOrder erpOrder = buildErpOrder(dbOrder,sysConfig);
+            ErpOrder erpOrder = buildErpOrder(dbOrder, sysConfig);
 
-        // 5. 调用对应 ERP 服务(当前是聚水潭ERP)
-        IErpOrderService erpService = erpServiceMap.get(erpType);
+            // 5. 调用对应 ERP 服务(当前是聚水潭ERP)
+            IErpOrderService erpService = erpServiceMap.get(erpType);
 
-        //执行互联网医院订单推送逻辑
-        ErpOrderResponse response = erpService.addOrder(erpOrder);
-        log.info("ERP地址推送结果 - 互联网医院订单: {}, ERP类型: {}, 成功: {}, 外部单号: {}",
-                dbOrder.getOrderCode(), erpType, response.getSuccess(), response.getCode());
+            //执行互联网医院订单推送逻辑
+            ErpOrderResponse response = erpService.addOrder(erpOrder);
+            log.info("ERP地址推送结果 - 互联网医院订单: {}, ERP类型: {}, 成功: {}, 外部单号: {}",
+                    dbOrder.getOrderCode(), erpType, response.getSuccess(), response.getCode());
         } catch (Exception e) {
             log.error("推送修改互联网医院订单地址到ERP失败,orderId: {}", partialOrder.getOrderId(), e);
         }
@@ -512,7 +518,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         //userPhone 电话处理
         String userPhone = fsStoreOrder.getUserPhone();
         if (StringUtils.isNotBlank(userPhone)) {
-            if (!userPhone.contains("*")){
+            if (!userPhone.contains("*")) {
                 fsStoreOrder.setUserPhone(userPhone);
             } else {
                 userPhone = null;
@@ -521,7 +527,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
         String userAddress = fsStoreOrder.getUserAddress();
         if (StringUtils.isNotBlank(userAddress)) {
-            if (!userAddress.contains("*")){
+            if (!userAddress.contains("*")) {
                 fsStoreOrder.setUserAddress(userAddress);
             } else {
                 userAddress = null;
@@ -530,29 +536,29 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
         FsStoreOrder oldOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderId(fsStoreOrder.getOrderId());
         if (oldOrder == null) return R.error("修改订单不存在");
-        if (StringUtils.isNotBlank(userAddress)){
+        if (StringUtils.isNotBlank(userAddress)) {
             if (userAddress.equals(oldOrder.getUserAddress())) {
                 userAddress = null;
             }
         }
-        if (StringUtils.isNotBlank(userAddress) || StringUtils.isNotBlank(userPhone)){
+        if (StringUtils.isNotBlank(userAddress) || StringUtils.isNotBlank(userPhone)) {
             Integer status = fsStoreOrder.getStatus();
-            if (status == null){
+            if (status == null) {
                 status = oldOrder.getStatus();
-            } else if (status.equals(FsStoreOrderStatusEnum.STATUS_6.getValue())){
+            } else if (status.equals(FsStoreOrderStatusEnum.STATUS_6.getValue())) {
                 status = oldOrder.getStatus();
             }
             if (Objects.equals(FsStoreOrderStatusEnum.STATUS_1.getValue(), status) ||
                     (Objects.equals(FsStoreOrderStatusEnum.STATUS_2.getValue(), status) && StringUtils.isBlank(oldOrder.getExtendOrderId()))
-                ) {
-                fsStoreOrder.setUserAddress(StringUtils.isBlank(userAddress)?null:userAddress);
-                fsStoreOrder.setUserPhone(StringUtils.isBlank(userPhone)?null:userPhone);
+            ) {
+                fsStoreOrder.setUserAddress(StringUtils.isBlank(userAddress) ? null : userAddress);
+                fsStoreOrder.setUserPhone(StringUtils.isBlank(userPhone) ? null : userPhone);
             } else {
                 return R.error("该订单状态不支持修改收货地址/电话");
             }
         }
         fsStoreOrder.setUpdateTime(DateUtils.getNowDate());
-        return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder)>0?R.ok():R.error();
+        return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder) > 0 ? R.ok() : R.error();
     }
 
     /**
@@ -595,7 +601,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
 
     @Override
-    public int sendGoods(FsStoreOrder fsStoreOrder,String opeName) {
+    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("非法更改");
@@ -614,7 +620,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             companyService.subtractCompanyMoney(order);
         }
         FsStoreOrderLogs Logs = new FsStoreOrderLogs();
-        Logs.setChangeMessage(opeName+" 订单发货");
+        Logs.setChangeMessage(opeName + " 订单发货");
         Logs.setOrderId(fsStoreOrder.getOrderId());
         Logs.setChangeTime(new DateTime());
         Logs.setChangeType("delivery_goods");
@@ -631,7 +637,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     }
 
     @Override
-    public int getGoods(Long orderId,String opeName) {
+    public int getGoods(Long orderId, String opeName) {
         FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(orderId);
         if (order == null) throw new CustomException("订单不存在");
         if (order.getStatus() != FsStoreOrderStatusEnum.STATUS_3.getValue()) throw new CustomException("非法更改");
@@ -649,14 +655,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         fsUserWatchService.addUserWatch(order);
         int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
         try {
-            if (i > 0){
+            if (i > 0) {
                 HuiFuUtils.confirmByOrderCode(order.getOrderCode());
             }
         } catch (Exception e) {
             log.error("延迟分账确认交易失败:{}", e.getMessage());
         }
         fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
-                opeName + " " +FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
+                opeName + " " + FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
         return i;
     }
 
@@ -838,6 +844,128 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         return R.ok();
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R createOrderByManually(FsPackageOrderAddParam param) {
+        FsStoreOrder order = new FsStoreOrder();
+        String orderSn = OrderCodeUtils.getOrderSn();
+        if (StringUtils.isEmpty(orderSn)) {
+            return R.error("订单生成失败,请重试");
+        }
+        //商品信息
+        List<FsStoreProduct> storeProductInProductIds = fsStoreProductMapper.getStoreProductInProductIds(param.getProductIds());
+        if(CollectionUtils.isEmpty(storeProductInProductIds)){
+            return R.error("商品不存在");
+        }
+        //处方信息
+        FsPatient patient=null;
+        if(param.getPatientId()!=null){
+            patient=fsPatientMapper.selectFsPatientByPatientId(param.getPatientId());
+        }else {
+            return R.error("请提交患者信息");
+        }
+        if(patient== null){
+            return R.error("请提交患者信息");
+        }
+        String painJsonStr = JSONUtil.toJsonStr(patient);
+        FsPrescribe fsPrescribe = new FsPrescribe();
+        fsPrescribe.setStatus(1);
+        fsPrescribe.setAuditTime(DateUtils.getNowDate());
+        fsPrescribe.setCreateTime(DateUtils.getNowDate());
+        fsPrescribe.setUsageJson("{}");
+        fsPrescribe.setUserId(param.getUserId());
+        fsPrescribe.setPrescribeCode(IdUtil.getSnowflake(0, 0).nextIdStr());
+        FsPackagePatientDTO patJson = JSON.parseObject(painJsonStr,FsPackagePatientDTO.class);
+        long currentTimeMillis = System.currentTimeMillis();
+        long ageInMillis = currentTimeMillis - patJson.getBirthday();
+        long ageInSeconds = ageInMillis / 1000;
+        long ageInYears = ageInSeconds / (365 * 24 * 3600);
+        fsPrescribe.setPatientAge(ageInYears+"");
+        fsPrescribe.setPatientId(patJson.getPatientId()+0L);
+        fsPrescribe.setPatientName(patJson.getPatientName());
+        fsPrescribe.setPatientTel(patJson.getMobile());
+        fsPrescribe.setPatientGender(patJson.getSex().toString());
+        fsPrescribe.setPatientBirthday(new SimpleDateFormat("yyyy-MM-dd").format(new Date(patJson.getBirthday())));
+        int i = prescribeMapper.insertFsPrescribe(fsPrescribe);
+        if (i > 0) {
+            storeProductInProductIds.forEach(product -> {
+                FsPrescribeDrug  fsPrescribeDrug=new FsPrescribeDrug();
+                if(product.getIsDrug().equals(1)){
+                    fsPrescribeDrug.setProductId(product.getProductId());
+                    fsPrescribeDrug.setDrugPrice(product.getPrice());
+                    fsPrescribeDrug.setPrescribeId(fsPrescribe.getPrescribeId());
+                    fsPrescribeDrug.setDrugName(product.getProductName());
+                    prescribeDrugMapper.insertFsPrescribeDrug(fsPrescribeDrug);
+                }
+            });
+        }else {
+            return R.error("处方生成失败,请重试");
+        }
+        order.setOrderCode(orderSn);
+        order.setUserId(param.getUserId());
+        order.setStatus(4);
+        order.setPayType(param.getPayType());
+        order.setCompanyId(param.getCompanyId());
+        order.setCreateTime(new Date());
+        order.setCompanyUserId(param.getCompanyUserId());
+        order.setPrescribeId(fsPrescribe.getPrescribeId());
+        //收货人信息
+        FsUserAddress address=userAddressService.selectFsUserAddressByAddressId(param.getAddressId());
+        if(address!=null){
+            order.setUserName(address.getRealName());
+            order.setUserPhone(address.getPhone());
+            order.setUserAddress(address.getProvince()+address.getCity()+address.getDistrict()+address.getDetail());
+        }
+        Long totalNum = 0l;
+        BigDecimal totalPrice = new BigDecimal(0);
+        List<FsStoreOrderItem> items = new ArrayList<>();
+        for (FsStoreProduct product : storeProductInProductIds) {
+            totalPrice = totalPrice.add(product.getPrice().multiply(BigDecimal.valueOf(storeProductInProductIds.size())));
+            totalNum = totalNum + storeProductInProductIds.size();
+            FsStoreOrderItem item = new FsStoreOrderItem();
+            item.setProductId(product.getProductId());
+            item.setStoreId(product.getStoreId());
+            item.setNum(Long.valueOf(storeProductInProductIds.size()));
+            FsStoreOrderItemDTO dto = new FsStoreOrderItemDTO();
+            dto.setImage(product.getImages());
+            dto.setNum(Long.valueOf(storeProductInProductIds.size()));
+            dto.setProductName(product.getProductName());
+            dto.setProductId(product.getProductId());
+            dto.setSku(UUID.randomUUID().toString());
+            dto.setBarCode(product.getBarCode());
+            dto.setPrice(product.getPrice());
+            dto.setNum(Long.parseLong(product.getStock().toString()));
+            dto.setImage(product.getImages());
+            item.setIsDrug(product.getIsDrug());
+            item.setIsPrescribe(0);
+            item.setJsonInfo(JSON.toJSONString(dto));
+            item.setIsGift(0);
+            items.add(item);
+        }
+        order.setTotalNum(totalNum);
+        order.setTotalPrice(totalPrice);
+        order.setPayPrice(param.getPayMoney());
+        order.setPayMoney(param.getPayMoney());
+        order.setIsPay(1);
+        order.setItemJson(JSONUtil.toJsonStr(items));
+        if (fsStoreOrderMapper.insertFsStoreOrder(order) > 0) {
+            for (FsStoreOrderItem item : items) {
+                item.setOrderId(order.getOrderId());
+                fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
+            }
+            FsUser fsUser = fsUserService.selectFsUserByUserId(order.getUserId());
+            if (fsUser.getIsBuy() == null || fsUser.getIsBuy() == 0) {
+                FsUser u = new FsUser();
+                u.setUserId(order.getUserId());
+                u.setIsBuy(1);
+                fsUserService.updateFsUser(u);
+            }
+        }else {
+            return R.error("订单生成失败,请重试");
+        }
+        return R.ok();
+    }
+
     @Override
     public R createOrderByPackageOrder(FsPackageOrder packageOrder) {
         if (packageOrder.getDoctorId() == null) {
@@ -1136,7 +1264,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         StringBuilder failureMsg = new StringBuilder();
         for (FsStoreProductDeliverExcelVO vo : list) {
             try {
-                log.info("原始数据:{}",JSON.toJSONString(vo));
+                log.info("原始数据:{}", JSON.toJSONString(vo));
                 FsStoreOrder o = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(vo.getOrderCode());
                 if (storeId != null) {
                     if (o.getStoreId() != storeId) {
@@ -1179,7 +1307,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 }
                 FsStore store = fsStoreMapper.selectFsStoreByStoreId(o.getStoreId());
                 int i = fsStoreOrderMapper.updateFsStoreOrderByOrderCode(fsStoreOrder);
-                log.info("手动发货导入订单号:订单号为"+fsStoreOrder.getOrderCode() + "快递单号为:" + fsStoreOrder.getDeliverySn());
+                log.info("手动发货导入订单号:订单号为" + fsStoreOrder.getOrderCode() + "快递单号为:" + fsStoreOrder.getDeliverySn());
                 String lastFourNumber = "";
                 if (fsStoreOrder.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
                     if (store.getSendPhone() != null) {
@@ -1592,7 +1720,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
     @Override
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
-    public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type,String bankTransactionId,String bankSerialNo){
+    public R payConfirm(String orderCode, String payCode, String tradeNo, String payType, Integer type, String bankTransactionId, String bankSerialNo) {
         try {
             FsStoreOrder order = null;
             if (type.equals(1)) {
@@ -1674,7 +1802,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     // 从company_user表查出openid
                     String mpOpenId = companyUserService.selectMpOpenIdByCompanyUserId(companyUserId);
                     if (StringUtils.isNotEmpty(mpOpenId)) {
-                        wechatApi.sendTemplateMessage(wechatApi.getAccessToken(), mpOpenId,storeOrder.getPayTime(),order.getUserName(),order.getPayPrice(),order.getOrderCode());
+                        wechatApi.sendTemplateMessage(wechatApi.getAccessToken(), mpOpenId, storeOrder.getPayTime(), order.getUserName(), order.getPayPrice(), order.getOrderCode());
                         log.info("支付成功模板消息已发送给销售: {}", companyUserId);
                     } else {
                         log.warn("未找到 companyUserId={} 的 openId,跳过模板消息发送", companyUserId);
@@ -1724,7 +1852,8 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             return R.error();
         }
     }
-    public  BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
+
+    public BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
         if (value == null) {
             return defaultValue;
         }
@@ -1745,6 +1874,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             return defaultValue;
         }
     }
+
     @Override
     public Long selectFsStoreOrderTotalCount(int type, Long companyId) {
         return fsStoreOrderMapper.selectFsStoreOrderTotalCount(type, companyId);
@@ -1838,7 +1968,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         fsStoreAfterSalesLogsMapper.insertFsStoreAfterSalesLogs(logs);
         //添加订单日志
         fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getValue(),
-                fsStoreOrderSalesParam.getOperator() + " " +FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getDesc());
+                fsStoreOrderSalesParam.getOperator() + " " + FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getDesc());
         //判断是否开启erp
         FsSysConfig sysConfig = configUtil.getSysConfig();
         Integer erpOpen = sysConfig.getErpOpen();
@@ -1862,7 +1992,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     erpOrderService = dfOrderService;
                 } else if (erpType == 5) {
                     erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
+                } else if (erpType == 6) {
                     erpOrderService = k9OrderService;
                 }
                 if (erpOrderService != null && StringUtils.isNotEmpty(order.getExtendOrderId())) {
@@ -1928,7 +2058,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             //聚水潭
             erpOrderService = jSTOrderService;
             erpOrder.setShop_code(sysConfig.getErpJstShopCode());
-        }else if (erpType == 6) {
+        } else if (erpType == 6) {
             erpOrderService = k9OrderService;
         } else {
             return;
@@ -2082,34 +2212,34 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
 
         String[] address = order.getUserAddress().split(" ");
-      try{
-          if (address.length < 3) {
-              String kdnAddress = fsUserAddressService.getKdnAddress(order.getUserAddress());
-              Map<String, Object> addDAta = (Map<String, Object>) JSON.parse(kdnAddress);
-              Map<String, String> add = (Map<String, String>) addDAta.get("Data");
-              erpOrder.setReceiver_province(add.get("ProvinceName"));
-              erpOrder.setReceiver_city(add.get("CityName"));
-              erpOrder.setReceiver_district(add.get("ExpAreaName"));
-              erpOrder.setReceiver_address(add.get("StreetName") + add.get("Address"));
-          } else {
-              erpOrder.setReceiver_province(address[0]);
-              erpOrder.setReceiver_city(address[1]);
-              erpOrder.setReceiver_district(address[2]);
-              //处理地址多空隔问题
-              if (address.length > 3) {
-                  StringBuffer addrs = new StringBuffer();
-                  for (int i = 3; i < address.length; i++) {
-                      addrs.append(address[i]);
-                  }
-                  erpOrder.setReceiver_address(addrs.toString());
-              } else if (address.length == 3) {
-                  erpOrder.setReceiver_address(address[2]);
-              }
-          }
-      }catch (Exception e){
-          log.error("地址错误:{}",e);
-          throw new CustomException("地址格式不对请正确写入详细地址!!");
-      }
+        try {
+            if (address.length < 3) {
+                String kdnAddress = fsUserAddressService.getKdnAddress(order.getUserAddress());
+                Map<String, Object> addDAta = (Map<String, Object>) JSON.parse(kdnAddress);
+                Map<String, String> add = (Map<String, String>) addDAta.get("Data");
+                erpOrder.setReceiver_province(add.get("ProvinceName"));
+                erpOrder.setReceiver_city(add.get("CityName"));
+                erpOrder.setReceiver_district(add.get("ExpAreaName"));
+                erpOrder.setReceiver_address(add.get("StreetName") + add.get("Address"));
+            } else {
+                erpOrder.setReceiver_province(address[0]);
+                erpOrder.setReceiver_city(address[1]);
+                erpOrder.setReceiver_district(address[2]);
+                //处理地址多空隔问题
+                if (address.length > 3) {
+                    StringBuffer addrs = new StringBuffer();
+                    for (int i = 3; i < address.length; i++) {
+                        addrs.append(address[i]);
+                    }
+                    erpOrder.setReceiver_address(addrs.toString());
+                } else if (address.length == 3) {
+                    erpOrder.setReceiver_address(address[2]);
+                }
+            }
+        } catch (Exception e) {
+            log.error("地址错误:{}", e);
+            throw new CustomException("地址格式不对请正确写入详细地址!!");
+        }
         erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("+", "加"));
         erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("\n", ""));
 
@@ -2157,7 +2287,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                                 this.updateFsStoreOrder(map);
                                 //如果是正常签收,更新订单状态
                                 if (dto.getState().equals("3") && (dto.getStateEx().equals("301") || dto.getStateEx().equals("302") || dto.getStateEx().equals("304") || dto.getStateEx().equals("311"))) {
-                                    this.getGoods(order.getOrderId(),"物流签收");
+                                    this.getGoods(order.getOrderId(), "物流签收");
                                     //app订单签收通知
                                     try {
                                         uniPush2Service.pushOne(
@@ -2222,7 +2352,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     for (FsStoreOrderScrm order : orders2) {
                         logger.info("订单信息:" + JSONUtil.toJsonStr(order));
                         logger.info("运单号:" + dto.getLogisticCode());
-                        if (order != null && (order.getDeliveryStatus()==null|| order.getDeliveryStatus()!= 3)) {
+                        if (order != null && (order.getDeliveryStatus() == null || order.getDeliveryStatus() != 3)) {
                             FsStoreOrderScrm map = new FsStoreOrderScrm();
                             map.setDeliveryStatus(Integer.parseInt(dto.getState()));
                             map.setId(order.getId());
@@ -2248,7 +2378,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         return fsStoreOrderMapper.selectFsStoreOrderListByDeliverySn(logisticCode);
     }
 
-    public static R requestExpressInfo(Long orderId){
+    public static R requestExpressInfo(Long orderId) {
         String fileUrl = "http://ipad.cdwjyyh.com/msg/sendExpressInfo/" + orderId;
 
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
@@ -2307,7 +2437,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
             Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
             Object isUpdateOrder = config.get("isUpdateOrder");
             if (isUpdateOrder == null || "1".equals(isUpdateOrder.toString())) {
-                this.getGoods(order.getOrderId(),"物流签收");
+                this.getGoods(order.getOrderId(), "物流签收");
             }
         }
         return R.ok();
@@ -2347,7 +2477,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 } else if (erpType == 5) {
                     //聚水潭
                     erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
+                } else if (erpType == 6) {
                     erpOrderService = k9OrderService;
                 }
                 ErpOrderQueryResponse response = erpOrderService.getOrder(request);
@@ -2570,7 +2700,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("非法操作");
@@ -2943,12 +3073,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         } else {
             appId = payConfigDTO.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-            if (StringUtils.isBlank(openId)){
+            if (StringUtils.isBlank(openId)) {
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                         .eq(FsUserWx::getFsUserId, param.getUserId())
                         .eq(FsUserWx::getAppId, appId);
                 FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-                if (Objects.nonNull(fsUserWx)){
+                if (Objects.nonNull(fsUserWx)) {
                     openId = fsUserWx.getOpenId();
                 }
             }
@@ -2957,7 +3087,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         if (user != null && StringUtils.isNotEmpty(openId)) {
 
             if (order.getPayMoney().compareTo(new BigDecimal(0)) == 0) {
-                this.payConfirm(order.getOrderCode(), "", "", "", 2,null,null);
+                this.payConfirm(order.getOrderCode(), "", "", "", 2, null, null);
                 return R.ok().put("data", param.getOrderId()).put("isPay", "1");
             } else {
                 String payCode = OrderCodeUtils.getOrderSn();
@@ -3110,12 +3240,12 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         } else {
             appId = payConfigDTO.getAppId();
             openId = Objects.isNull(user) ? "" : user.getMaOpenId();
-            if (StringUtils.isBlank(openId)){
+            if (StringUtils.isBlank(openId)) {
                 Wrapper<FsUserWx> queryWrapper = Wrappers.<FsUserWx>lambdaQuery()
                         .eq(FsUserWx::getFsUserId, param.getUserId())
                         .eq(FsUserWx::getAppId, appId);
                 FsUserWx fsUserWx = fsUserWxMapper.selectOne(queryWrapper);
-                if (Objects.nonNull(fsUserWx)){
+                if (Objects.nonNull(fsUserWx)) {
                     openId = fsUserWx.getOpenId();
                 }
             }
@@ -3125,7 +3255,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
             if (order.getPayMoney().compareTo(new BigDecimal(0)) == 0) {
                 IFsStoreOrderService fsStoreOrderService1 = (IFsStoreOrderService) AopContext.currentProxy();
-                fsStoreOrderService1.payConfirm(order.getOrderCode(), "", "", "", 2,null,null);
+                fsStoreOrderService1.payConfirm(order.getOrderCode(), "", "", "", 2, null, null);
                 return R.ok().put("data", param.getOrderId()).put("isPay", "1");
             } else {
                 //在线支付
@@ -3588,7 +3718,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 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));
+                        param.getOpeName() + " " + FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhones.get(i));
             }
         } else {
             //2.手机号小于orderIds长度
@@ -3609,7 +3739,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     maps.add(map);
                     orderIndex++;
                     fsStoreOrderLogsService.create(orderIds.get(i), FsStoreOrderLogEnum.SET_PUSH_MOBILE.getValue(),
-                            param.getOpeName() + " " +FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhone);
+                            param.getOpeName() + " " + FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhone);
                 }
             }
         }
@@ -3680,7 +3810,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     tempOrder.setDeliverySn("");
                     fsStoreOrderMapper.updateFsStoreOrder(tempOrder);
                     fsStoreOrderLogsService.create(tempOrder.getOrderId(), FsStoreOrderLogEnum.UPDATE_ORDER_DF.getValue(),
-                            "运单不存在,"+FsStoreOrderLogEnum.UPDATE_ORDER_DF.getDesc());
+                            "运单不存在," + FsStoreOrderLogEnum.UPDATE_ORDER_DF.getDesc());
                 } else {
                     //有物流信息->售后处理
                     //取消订单
@@ -3690,7 +3820,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     afterSalesParam.setOperator("代服管家");
                     fsStoreOrderService.afterSales(afterSalesParam);
                     fsStoreOrderLogsService.create(tempOrder.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_DF.getValue(),
-                            "运单不存在,"+FsStoreOrderLogEnum.REFUND_ORDER_DF.getDesc());
+                            "运单不存在," + FsStoreOrderLogEnum.REFUND_ORDER_DF.getDesc());
                 }
                 FsStoreOrderDf df = new FsStoreOrderDf();
                 df.setOrderId(tempOrder.getOrderId());
@@ -3763,7 +3893,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 Map<String, Object> config = (Map<String, Object>) JSON.parse(sysConfig.getConfigValue());
                 Object isUpdateOrder = config.get("isUpdateOrder");
                 if (isUpdateOrder == null || "1".equals(isUpdateOrder.toString())) {
-                    this.getGoods(order.getOrderId(),"物流签收");
+                    this.getGoods(order.getOrderId(), "物流签收");
                 }
 
             }
@@ -3912,7 +4042,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 } else if (erpType == 5) {
                     //聚水潭
                     erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
+                } else if (erpType == 6) {
                     erpOrderService = k9OrderService;
                 }
                 return erpOrderService;
@@ -3941,7 +4071,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 //1.必填参数
                 ExcelUtils.validateRequiredFields(vo, list.indexOf(vo) + 1); // 传入行号
                 FsStoreOrder o = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(vo.getOrderCode());
-                if (o ==null){
+                if (o == null) {
                     failureNum++;
                     String msg = "<br/>" + failureNum + "、订单编号 " + vo.getOrderCode() + " 导入失败:";
                     failureMsg.append(msg).append("订单不存在");
@@ -3971,7 +4101,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
 
                 Integer status = o.getStatus();
 
-                if (StringUtils.isNotBlank(vo.getStatus())){
+                if (StringUtils.isNotBlank(vo.getStatus())) {
                     param.setStatus(Integer.valueOf(vo.getStatus()));
                     status = Integer.valueOf(vo.getStatus());
                 }
@@ -3980,10 +4110,10 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                  */
                 String userAddress = vo.getUserAddress();
                 String userPhone = vo.getUserPhone();
-                if (StringUtils.isNotBlank(userAddress) || StringUtils.isNotBlank(userPhone)){
+                if (StringUtils.isNotBlank(userAddress) || StringUtils.isNotBlank(userPhone)) {
                     if (Objects.equals(FsStoreOrderStatusEnum.STATUS_1.getValue(), status) || Objects.equals(FsStoreOrderStatusEnum.STATUS_6.getValue(), status)) {
-                        param.setUserAddress(userAddress.isEmpty()?null:userAddress);
-                        param.setUserPhone(userPhone.isEmpty()?null:userPhone);
+                        param.setUserAddress(userAddress.isEmpty() ? null : userAddress);
+                        param.setUserPhone(userPhone.isEmpty() ? null : userPhone);
                     } else {
                         failureNum++;
                         String msg = "<br/>" + failureNum + "、订单编号 " + vo.getOrderCode() + " 修改失败:";
@@ -3991,14 +4121,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                         continue;
                     }
                 }
-                param.setDeliveryStatus((vo.getDeliveryStatus()==null|| vo.getDeliveryStatus().isEmpty())?null:Integer.valueOf(vo.getDeliveryStatus()));
-                param.setDeliveryType(vo.getDeliveryType().isEmpty()?null:vo.getDeliveryType());
+                param.setDeliveryStatus((vo.getDeliveryStatus() == null || vo.getDeliveryStatus().isEmpty()) ? null : Integer.valueOf(vo.getDeliveryStatus()));
+                param.setDeliveryType(vo.getDeliveryType().isEmpty() ? null : vo.getDeliveryType());
                 param.setUpdateTime(DateUtils.getNowDate());
 
                 //修改订单金额
                 BigDecimal payRemain = vo.getPayRemain();
-                if (payRemain != null){
-                    if (!payRemain.equals(o.getPayRemain())){
+                if (payRemain != null) {
+                    if (!payRemain.equals(o.getPayRemain())) {
                         BigDecimal payMoney = o.getPayMoney(); //实收金额
                         param.setPayPrice(payMoney.add(payRemain)); //应收金额
                         param.setPayRemain(vo.getPayRemain());
@@ -4031,7 +4161,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     }
 
     @Override
-    public Map<String,BigDecimal> selectFsStoreOrderStatistics(FsStoreOrderParam fsStoreOrder) {
+    public Map<String, BigDecimal> selectFsStoreOrderStatistics(FsStoreOrderParam fsStoreOrder) {
         return fsStoreOrderMapper.selectFsStoreOrderStatistics(fsStoreOrder);
     }
 
@@ -4048,16 +4178,16 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         }
         //判断总退款金额是否小于等于实付金额
         BigDecimal refundAmount = param.getRefundAmount();
-        if (refundAmount.compareTo(order.getPayMoney())>0){
+        if (refundAmount.compareTo(order.getPayMoney()) > 0) {
             throw new CustomException("退款金额不能大于实付金额");
         }
         List<FsStoreOrderRefundByProductParam> refundList = param.getRefundList();
-        List<Long> itemIds = refundList.stream().filter(item->item.getNum()>0).map(FsStoreOrderRefundByProductParam::getItemId).collect(Collectors.toList());
-        if (itemIds.isEmpty()){
+        List<Long> itemIds = refundList.stream().filter(item -> item.getNum() > 0).map(FsStoreOrderRefundByProductParam::getItemId).collect(Collectors.toList());
+        if (itemIds.isEmpty()) {
             throw new CustomException("没有选择需要退款的商品/选择退款商品数量不能为0");
         }
         List<FsStoreOrderItem> fsStoreOrderItems = fsStoreOrderItemMapper.selectFsStoreOrderItemListByItemIds(itemIds);
-        if (fsStoreOrderItems.size() != itemIds.size()){
+        if (fsStoreOrderItems.size() != itemIds.size()) {
             throw new CustomException("所退商品明细不存在");
         }
         FsStoreAfterSales fsStoreAfterSales = new FsStoreAfterSales();
@@ -4112,7 +4242,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         fsStoreAfterSalesLogsMapper.insertFsStoreAfterSalesLogs(logs);
         //添加订单日志
         fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getValue(),
-                param.getOperator() + " " +FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getDesc());
+                param.getOperator() + " " + FsStoreOrderLogEnum.REFUND_ORDER_PLATFORM.getDesc());
         //判断是否开启erp
         FsSysConfig sysConfig = configUtil.getSysConfig();
         Integer erpOpen = sysConfig.getErpOpen();
@@ -4136,7 +4266,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                     erpOrderService = dfOrderService;
                 } else if (erpType == 5) {
                     erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
+                } else if (erpType == 6) {
                     erpOrderService = k9OrderService;
                 }
                 if (erpOrderService != null && StringUtils.isNotEmpty(order.getExtendOrderId())) {
@@ -4172,12 +4302,14 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     public FsStoreOrderAmountStatsVo selectFsStoreOrderAmountStats(FsStoreOrderAmountStatsQueryDto queryDto) {
         return fsStoreOrderMapper.selectFsStoreOrderAmountStats(queryDto);
     }
+
     @Autowired
     FsStoreOrderScrmMapper storeOrderScrmMapper;
 
 
     @Autowired
     IFsStoreOrderLogsScrmService iFsStoreOrderLogsScrmService;
+
     @Override
     public void deliveryOrderScrm(String orderCode, String deliveryId, String deliverCode, String deliverName) {
         FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderScrmByOrderCode(orderCode);
@@ -4220,6 +4352,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
     public FsStoreOrderScrm selectFsStoreOrderScrmByOrderCode(String soId) {
         return fsStoreOrderMapper.selectFsStoreOrderScrmByOrderCode(soId);
     }
+
     @Override
     public FsStoreOrder confirmOrder(FsPackageOrder packageOrder, Long doctorId) {
 
@@ -4230,13 +4363,13 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         Integer packageSubType = (Integer) packageJson.get("packageSubType");
         Integer productType = (Integer) packageJson.get("productType");
         FsStoreOrder order = new FsStoreOrder();
-        Long prescribeId =null;
-        if (productType==1 || packageSubType==2){
+        Long prescribeId = null;
+        if (productType == 1 || packageSubType == 2) {
             if (packageOrder.getDoctorId() == null) {
                 Long doctorID = iFsDoctorService.selectFsDoctorDoctorByPackage();
                 packageOrder.setDoctorId(doctorID);
             }
-            if (packageSubType == 3 ) {
+            if (packageSubType == 3) {
                 inquiryOrderService.createOrderByPackageOrderStatus4(packageOrder);
             }
             prescribeId = fsPrescribeService.insertFsPrescribeByPackageOrder(packageOrder);

+ 15 - 1
fs-service/src/main/java/com/fs/his/vo/FsCourseReportVO.java

@@ -1,5 +1,6 @@
 package com.fs.his.vo;
 
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -11,64 +12,77 @@ public class FsCourseReportVO {
     private  Long companyId;
 
     /** 公司名称 */
-
+    @Excel(name = "销售公司")
     private String companyName;
 
+
     /** 训练营名称 */
+    @Excel(name = "训练营名称")
     private  String trainingCampName;
     /**
      * 营期
      */
+    @Excel(name = "营期")
     private  String periodName;
 
     /**
      * 进线人数
      */
+    @Excel(name = "进线人数")
     private  Integer accessCount;
 
     /**
      * 待看课人数
      */
+    @Excel(name = "待看课人数")
     private  Integer pendingCount;
 
     /**
      * 看课中人数
      */
+    @Excel(name = "看课中人数")
     private  Integer watchingCount;
 
     /**
      * 完课人数
      */
+    @Excel(name = "完课人数")
     private  Integer finishedCount;
 
     /**
      * 看课中断人数
      */
+    @Excel(name = "看课中断人数")
     private  Integer interruptedCount;
 
     /**
      * 看课率
      */
+    @Excel(name = "看课率")
     private BigDecimal watchRate;
 
     /**
      * 完课率
      */
+    @Excel(name = "完课率")
     private   BigDecimal finishRate;
 
     /**
      * 答题人数
      */
+    @Excel(name = "答题人数")
     private  Integer answerUserCount;
 
     /**
      * 红包领取数
      */
+    @Excel(name = "红包领取数")
     private  Integer packetUserCount;
 
     /**
      * 红包金额
      */
+    @Excel(name = "红包金额")
     private  BigDecimal packetAmount;
 
     /**

+ 9 - 0
fs-service/src/main/java/com/fs/his/vo/FsOrderReportVO.java

@@ -1,5 +1,6 @@
 package com.fs.his.vo;
 
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -10,40 +11,48 @@ public class FsOrderReportVO {
     /**
      * 公司名称
      */
+    @Excel(name = "销售公司")
     private String companyName;
 
     /**
      * 部门名称
      */
+    @Excel(name = "销售部门")
     private String deptName;
 
     /**
      * 问诊订单数
      */
+    @Excel(name = "问诊订单数")
     private Long inquiryOrderCount;
 
     /**
      * 问诊金额
      */
+    @Excel(name = "问诊订单金额")
     private BigDecimal inquiryOrderAmount;
 
     /**
      * 积分订单数
      */
+    @Excel(name = "积分商品订单数")
     private  Long integralOrderCount;
 
     /**
      * 积分金额
      */
+    @Excel(name = "积分商品订单金额")
     private BigDecimal integralOrderAmount;
 
     /**
      * 套餐订单数
      */
+    @Excel(name = "套餐包订单数")
     private  Long packageOrderCount;
 
     /**
      * 套餐金额
      */
+    @Excel(name = "套餐包订单金额")
     private BigDecimal packageOrderAmount;
 }

+ 18 - 0
fs-service/src/main/java/com/fs/his/vo/FsPackageOrderExcelVO.java

@@ -119,4 +119,22 @@ public class FsPackageOrderExcelVO {
     private Integer source;
     @Excel(name = "微信小程序姓名")
     private String miniProgramName;
+
+    /**
+     * 收货人
+     */
+    @Excel(name = "收货人")
+    private String  userName;
+
+    /**
+     * 收货人手机
+     */
+    @Excel(name = "收货人电话")
+    private String  userPhone;
+
+    /**
+     * 收货地址
+     */
+    @Excel(name = "收货地址")
+    private String  userAddress;
 }

+ 12 - 4
fs-service/src/main/java/com/fs/his/vo/FsPackageOrderReportVO.java

@@ -1,5 +1,6 @@
 package com.fs.his.vo;
 
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -10,32 +11,39 @@ public class FsPackageOrderReportVO {
     /**
      * 公司名称
      */
+    @Excel(name = "销售公司")
     private String companyName;
 
+    /**
+     * 销售部门
+     */
+    @Excel(name = "销售部门")
+    private  String  deptName;
     /**
      * 订单数
      */
+    @Excel(name = "总订单数")
     private Long orderNum;
 
     /**
      * 金额
      */
+    @Excel(name = "定金金额")
     private BigDecimal money;
 
     /**
      * 确认收货订单数
      */
+    @Excel(name = "确认收货订单数")
     private Long receiptOrder;
 
     /**
      * 确认收货金额
      */
+    @Excel(name = "确认收货金额")
     private  BigDecimal receiptMoney;
 
-    /**
-     * 销售部门
-     */
-    private  String  deptName;
+
 
 
 }

+ 17 - 1
fs-service/src/main/java/com/fs/his/vo/FsUserReportVO.java

@@ -1,6 +1,7 @@
 package com.fs.his.vo;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -9,84 +10,99 @@ import java.util.Date;
 @Data
 public class FsUserReportVO {
 
-
+    @Excel(name = "会员id")
     private Long userId;
     /**
      * 昵称
      */
+    @Excel(name = "会员昵称")
     private String nickName;
 
+    @Excel(name = "用户状态")
     /** 1为正常,0为禁止 */
     private String status;
 
     /**
      * 所属销售
      */
+    @Excel(name = "所属销售")
     private String companyUserName;
 
 
     /**
      * 所属销售公司
      */
+    @Excel(name = "所属销售公司")
     private String companyName;
 
     /**
      * 注册时间
      */
+
     private Date registerDate;
 
     /**
      * 最近看课时间
      */
     @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "最近看课时间",dateFormat = "yyyy-MM-dd")
     private  Date lastWatchTime;
 
 
     /**
      *  看课数
      */
+    @Excel(name = "看课数")
     private  Integer watchCount;
 
 
     /**
      * 缺课数
      */
+    @Excel(name = "缺课数")
     private  Integer absentCount;
 
     /**
      * 参与营期数量
      */
+    @Excel(name = "参与营期数量")
     private  Integer  periodCount;
 
 
     /**
      * 观看状态
      */
+    @Excel(name = "看课状态")
     private  String watchStatus;
 
     /**
      * 消耗积分
      */
+    @Excel(name = "已消耗积分")
     private  Integer consumedIntegral;
 
     /**
      * 已领红包金额
      */
+    @Excel(name = "已领红包金额")
     private BigDecimal receivedAmount;
 
     /**
      * 已产生订单金额
      */
+    @Excel(name = "已产生订单金额")
     private  BigDecimal orderAmount;
 
     /**
      * 积分
      */
+    @Excel(name = "用户积分")
     private  Integer  Integral;
 
     /**
      * 部门名称
      */
+    @Excel(name = "所属销售部门")
     private  String  deptName;
     /**
      * 首次进线时间

+ 26 - 0
fs-service/src/main/java/com/fs/his/vo/WatchLogReportVO.java

@@ -1,6 +1,7 @@
 package com.fs.his.vo;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -9,118 +10,141 @@ import java.util.Date;
 @Data
 public class WatchLogReportVO {
 
+    @Excel(name = "会员id")
     private Long userId;
     /**
      * 昵称
      */
+    @Excel(name = "会员昵称")
     private String nickName;
 
     /**
      * 会员数
      */
+    @Excel(name = "会员数")
     private  Integer userCount;
 
 
     /**
      * 销售数
      */
+    @Excel(name = "销售数")
     private  Integer salesCount;
 
     /**
      * 所属销售数
      */
+    @Excel(name = "所属销售")
     private  String salesName;
 
     /**
      * 所属销售部门
      */
+    @Excel(name = "销售部门")
     private  String salesDept;
 
     /**
      * 所属销售公司
      */
+    @Excel(name = "所属销售公司")
     private  String salesCompany;
 
     /**
      * 在线会员数
      */
+    @Excel(name = "当前会员线上数")
     private  Integer onlineUserCount;
 
     /**
      * 培训营名称
      */
+    @Excel(name = "训练营")
     private String trainingCampName;
 
     /**
      * 营期
      */
+    @Excel(name = "营期")
     private  String periodName;
 
     /**
      * 视频名称
      */
+    @Excel(name = "小节名称")
     private  String videoTitle;
 
     /**
      * 观看状态
      */
+    @Excel(name = "看课状态")
     private  String watchStatus;
 
     /**
      * 观看时长
      */
+    @Excel(name = "观看时长")
     private  String duration;
 
     /**
      * 观看完成数
      */
+    @Excel(name = "完课数")
     private  Integer finishedCount;
 
     /**
      * 观看未完成数
      */
+    @Excel(name = "未完课")
     private  Integer unfinishedCount;
 
     /**
      * 观看完成率
      */
+    @Excel(name = "完课率")
     private BigDecimal completionRate;
 
     /**
      * 看课时间
      */
+    @Excel(name = "看课时间",dateFormat = "yyyy-MM-dd")
     @JsonFormat(pattern = "yyyy-MM-dd")
     private Date courseTime;
 
     /**
      * 观看完成时间
      */
+    @Excel(name = "完课时间",dateFormat = "yyyy-MM-dd")
     @JsonFormat(pattern = "yyyy-MM-dd")
     private  Date  finishTime;
 
     /**
      * 未看课数
      */
+    @Excel(name = "未看数")
     private  Integer notWatchedCount;
 
     /**
      * 未回答数
      */
+    @Excel(name = "未答题人数")
     private  Integer notAnsweredCount;
 
     /**
      * 回答状态
      */
+    @Excel(name = "答题状态")
     private  String answerStatus;
 
     /**
      * 领取红包金额
      */
+    @Excel(name = "红包金额")
     private  BigDecimal redPacketAmount;
 
     /**
      * 历史订单数
      */
+    @Excel(name = "历史疗法订单数")
     private  Integer historyOrderCount;
 
     /**
@@ -148,4 +172,6 @@ public class WatchLogReportVO {
      */
     private  Long logId;
 
+    private  Long deptId;
+
 }

+ 38 - 0
fs-service/src/main/java/com/fs/qw/vo/QwWatchLogAllStatisticsListVO.java

@@ -88,40 +88,78 @@ public class QwWatchLogAllStatisticsListVO {
     private Long d12Over;
     @Excel(name = "D13上线")
     private Long d13Online;
+    @Excel(name = "D13完课")
     private Long d13Over;
+    @Excel(name = "D14上线")
     private Long d14Online;
+    @Excel(name = "D14完课")
     private Long d14Over;
+    @Excel(name = "D15上线")
     private Long d15Online;
+    @Excel(name = "D15完课")
     private Long d15Over;
+
+    @Excel(name = "D16上线")
     private Long d16Online;
+
+    @Excel(name = "D16完课")
     private Long d16Over;
+
+    @Excel(name = "D17上线")
     private Long d17Online;
+    @Excel(name = "D17完课")
     private Long d17Over;
+    @Excel(name = "D18上线")
     private Long d18Online;
+    @Excel(name = "D18完课")
     private Long d18Over;
+    @Excel(name = "D19上线")
     private Long d19Online;
+    @Excel(name = "D19完课")
     private Long d19Over;
+    @Excel(name = "D20上线")
     private Long d20Online;
+    @Excel(name = "D20完课")
     private Long d20Over;
+    @Excel(name = "D21上线")
     private Long d21Online;
+    @Excel(name = "D21完课")
     private Long d21Over;
+    @Excel(name = "D22上线")
     private Long d22Online;
+    @Excel(name = "D22完课")
     private Long d22Over;
+    @Excel(name = "D23上线")
     private Long d23Online;
+    @Excel(name = "D23完课")
     private Long d23Over;
+    @Excel(name = "D24上线")
     private Long d24Online;
+    @Excel(name = "D24完课")
     private Long d24Over;
+    @Excel(name = "D25上线")
     private Long d25Online;
+    @Excel(name = "D25完课")
     private Long d25Over;
+    @Excel(name = "D26上线")
     private Long d26Online;
+    @Excel(name = "D26完课")
     private Long d26Over;
+    @Excel(name = "D27上线")
     private Long d27Online;
+    @Excel(name = "D27完课")
     private Long d27Over;
+    @Excel(name = "D28上线")
     private Long d28Online;
+    @Excel(name = "D28完课")
     private Long d28Over;
+    @Excel(name = "D29上线")
     private Long d29Online;
+    @Excel(name = "D29完课")
     private Long d29Over;
+    @Excel(name = "D30上线")
     private Long d30Online;
+    @Excel(name = "D30完课")
     private Long d30Over;
     /**
      * 项目

+ 224 - 30
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -1060,8 +1060,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
         <!-- 时间范围 - 使用BETWEEN -->
         <if test="sTime != null and eTime != null">
-            AND po.create_time BETWEEN #{sTime} AND #{eTime}
+            AND DATE(po.create_time)  BETWEEN #{sTime} AND #{eTime}
         </if>
+        order by u.create_time
     </select>
     <select id="selectWatchStatsByUserIds" resultType="com.fs.his.vo.FsUserReportVO">
         SELECT
@@ -1175,6 +1176,7 @@ FROM
          <if test="orderSTime != null and orderETime != null">
             AND DATE(po.create_time) BETWEEN #{orderSTime} AND #{orderETime}
         </if>
+        group by log.user_id
         ORDER BY u.register_date DESC
     </select>
     <select id="selectSalesBaseData" resultType="com.fs.his.vo.WatchLogReportVO">
@@ -1182,11 +1184,13 @@ FROM
         log.user_id userId,
         log.company_user_id companyUserId,
         log.period_id periodId,
-        log.video_id videoId,
         log.log_id logId,
         log.create_time courseTime,
-        log.finish_time finishTime,
-        log.duration,
+        cu.nick_name as salesName,
+        d.dept_name AS salesDept,
+        c.company_name AS salesCompany,
+        COUNT( DISTINCT u.user_id ) AS userCount,
+        COUNT( DISTINCT CASE WHEN u.STATUS = 1 THEN u.user_id END ) AS onlineUserCount,
         cv.title videoTitle,
         COUNT(DISTINCT log.log_id) AS totalLogCount,
         COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
@@ -1197,14 +1201,11 @@ FROM
         <if test="orderSTime != null and orderETime != null">
             LEFT JOIN fs_package_order po ON po.user_id = log.user_id
         </if>
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN fs_user u on log.user_id= u.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        LEFT JOIN company c ON d.company_id = c.company_id
         LEFT JOIN fs_user_course_video cv ON log.video_id = cv.video_id
-        <if test="deptId != null and deptId != ''">
-            LEFT JOIN company c ON log.company_id = c.company_id
-            LEFT JOIN company_dept cd ON c.company_id = cd.company_id
-        </if>
-        <if test="nickName != null and nickName != '' or userPhone != null and userPhone != ''">
-            LEFT JOIN fs_user u ON log.user_id = u.user_id
-        </if>
         WHERE log.send_type =1
         <if test="sTime != null and eTime != null">
             AND  DATE(log.create_time) BETWEEN #{sTime} AND #{eTime}
@@ -1217,7 +1218,7 @@ FROM
             AND log.company_id = #{companyId}
         </if>
         <if test="deptId != null and deptId != ''">
-            AND cd.dept_id = #{deptId}
+            AND d.dept_id = #{deptId}
         </if>
         <!-- 训练营 -->
         <if test="trainingCampId != null and trainingCampId != ''">
@@ -1243,37 +1244,35 @@ FROM
         <if test="nickName != null and nickName != ''">
             AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
         </if>
-        GROUP BY log.company_user_id
+        GROUP BY cu.user_id
 
     </select>
     <select id="selectCompanyBaseData" resultType="com.fs.his.vo.WatchLogReportVO">
         SELECT
         log.user_id userId,
-        log.company_user_id companyUserId,
         log.period_id periodId,
-        log.video_id videoId,
         log.log_id logId,
         log.create_time courseTime,
-        log.finish_time finishTime,
-        log.duration,
+        d.dept_id AS deptId,
+        d.dept_name AS salesDept,
+        c.company_name AS salesCompany,
+        COUNT(DISTINCT cu.user_id) AS salesCount,
+        COUNT(DISTINCT u.user_id) AS userCount,
+        COUNT(DISTINCT CASE WHEN u.STATUS = 1 THEN u.user_id END) AS onlineUserCount,
         cv.title videoTitle,
         COUNT(DISTINCT log.log_id) AS totalLogCount,
         COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
         COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
-        COUNT(DISTINCT log.log_id)-COUNT(DISTINCT log.user_id) AS notWatchedCount
-        FROM
-        fs_course_watch_log log
+        COUNT(DISTINCT log.user_id) - COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.user_id END) AS notWatchedCount
+        FROM fs_course_watch_log log
         <if test="orderSTime != null and orderETime != null">
             LEFT JOIN fs_package_order po ON po.user_id = log.user_id
         </if>
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN fs_user u on log.user_id= u.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        LEFT JOIN company c ON d.company_id = c.company_id
         LEFT JOIN fs_user_course_video cv ON log.video_id = cv.video_id
-        <if test="deptId != null and deptId != ''">
-            LEFT JOIN company c ON log.company_id = c.company_id
-            LEFT JOIN company_dept cd ON c.company_id = cd.company_id
-        </if>
-        <if test="nickName != null and nickName != '' or userPhone != null and userPhone != ''">
-            LEFT JOIN fs_user u ON log.user_id = u.user_id
-        </if>
         WHERE log.send_type =1
         <if test="sTime != null and eTime != null">
             AND  DATE(log.create_time)  BETWEEN #{sTime} AND #{eTime}
@@ -1283,11 +1282,11 @@ FROM
         </if>
         <!-- 销售公司 -->
         <if test="companyId != null and companyId != ''">
-            AND log.company_id = #{companyId}
+            AND c.company_id = #{companyId}
         </if>
           <!--部门 -->
         <if test="deptId != null and deptId != ''">
-            AND cd.dept_id = #{deptId}
+            AND d.dept_id = #{deptId}
         </if>
         <!-- 训练营 -->
         <if test="trainingCampId != null and trainingCampId != ''">
@@ -1312,7 +1311,7 @@ FROM
         <if test="nickName != null and nickName != ''">
             AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
         </if>
-        GROUP BY log.company_user_id
+        GROUP BY d.dept_id
     </select>
     <select id="selectUserWatchDetails" resultType="com.fs.his.vo.WatchLogReportVO">
         SELECT
@@ -1525,6 +1524,9 @@ FROM
             <if test="sTime != null and eTime != null">
                 AND DATE(w.create_time)  BETWEEN #{sTime} AND #{eTime}
             </if>
+            <if test="trainingCampId != null">
+                AND w.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+            </if>
             <if test="companyIds != null and companyIds.size() > 0">
                 AND w.company_id IN
                 <foreach collection="companyIds" item="companyId" open="(" separator="," close=")">
@@ -1602,6 +1604,198 @@ FROM
         </if>
         AND cu.del_flag = '0'
     </select>
+    <select id="selectCompanyBaseDataOptimized" resultType="com.fs.his.vo.WatchLogReportVO">
+        SELECT
+        d.dept_id AS deptId,
+        d.dept_name AS salesDept,
+        c.company_name AS salesCompany,
+        COUNT(DISTINCT cu.user_id) AS salesCount,
+        COUNT(DISTINCT u.user_id) AS userCount,
+        COUNT( DISTINCT CASE WHEN u.STATUS = 1 THEN u.user_id END ) AS onlineUserCount
+        FROM fs_course_watch_log log
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN fs_user u ON log.user_id = u.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        LEFT JOIN company c ON d.company_id = c.company_id
+        WHERE log.send_type = 1
+        <if test="sTime != null and eTime != null">
+            AND DATE(log.create_time) BETWEEN #{sTime} AND #{eTime}
+        </if>
+        <!-- 销售公司 -->
+        <if test="companyId != null and companyId != ''">
+            AND c.company_id = #{companyId}
+        </if>
+        <!--部门 -->
+        <if test="deptId != null and deptId != ''">
+            AND d.dept_id = #{deptId}
+        </if>
+        <!-- 训练营 -->
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND log.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        <!-- 营期 -->
+        <if test="periodId != null and periodId != ''">
+            AND log.period_id = #{periodId}
+        </if>
+        <!-- 会员id -->
+        <if test="userId != null and userId != ''">
+            AND log.user_id = #{userId}
+        </if>
+        <!-- 会员手机号 -->
+        <if test="userPhone != null and userPhone != ''">
+            AND u.phone LIKE CONCAT('%', #{userPhone}, '%')
+        </if>
+        <if test="project != null and project != ''">
+            AND log.project = #{project}
+        </if>
+        <!-- 会员昵称 -->
+        <if test="nickName != null and nickName != ''">
+            AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
+        </if>
+        GROUP BY d.dept_id, d.dept_name, c.company_name
+    </select>
+    <select id="selectAllDeptIds" resultType="java.lang.Long">
+        SELECT DISTINCT d.dept_id
+        FROM fs_course_watch_log log
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        LEFT JOIN company c ON d.company_id = c.company_id
+        LEFT JOIN fs_user u ON log.user_id = u.user_id
+        WHERE log.send_type = 1
+        <if test="sTime != null and eTime != null">
+            AND DATE(log.create_time) BETWEEN #{sTime} AND #{eTime}
+        </if>
+        <!-- 销售公司 -->
+        <if test="companyId != null and companyId != ''">
+            AND c.company_id = #{companyId}
+        </if>
+        <!--部门 -->
+        <if test="deptId != null and deptId != ''">
+            AND d.dept_id = #{deptId}
+        </if>
+        <!-- 训练营 -->
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND log.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        <!-- 营期 -->
+        <if test="periodId != null and periodId != ''">
+            AND log.period_id = #{periodId}
+        </if>
+        <!-- 会员id -->
+        <if test="userId != null and userId != ''">
+            AND log.user_id = #{userId}
+        </if>
+        <!-- 会员手机号 -->
+        <if test="userPhone != null and userPhone != ''">
+            AND u.phone LIKE CONCAT('%', #{userPhone}, '%')
+        </if>
+        <if test="project != null and project != ''">
+            AND log.project = #{project}
+        </if>
+        <!-- 会员昵称 -->
+        <if test="nickName != null and nickName != ''">
+            AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
+        </if>
+    </select>
+    <select id="selectWatchStatsByDeptBatch" resultType="com.fs.his.vo.WatchLogReportVO">
+        SELECT
+        d.dept_id AS deptId,
+        log.user_id AS userId,
+        log.period_id AS periodId,
+        log.log_id AS logId,
+        cv.title videoTitle,
+        COUNT(DISTINCT log.log_id) AS totalLogCount,
+        COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.log_id END) AS finishedCount,
+        COUNT(DISTINCT CASE WHEN log.log_type IN ('1', '3', '4') THEN log.log_id END) AS unfinishedCount,
+        COUNT(DISTINCT log.user_id) - COUNT(DISTINCT CASE WHEN log.log_type = '2' THEN log.user_id END) AS notWatchedCount
+        FROM fs_course_watch_log log
+        LEFT JOIN fs_user_course_video cv ON log.video_id = cv.video_id
+        <if test="orderSTime != null and orderETime != null">
+            LEFT JOIN fs_package_order po ON po.user_id = log.user_id
+        </if>
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        WHERE log.send_type = 1
+        AND d.dept_id IN
+        <foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
+            #{deptId}
+        </foreach>
+        <if test="sTime != null and eTime != null">
+            AND DATE(log.create_time) BETWEEN #{sTime} AND #{eTime}
+        </if>
+        <if test="orderSTime != null and orderETime != null">
+            AND DATE(po.create_time) BETWEEN #{orderSTime} AND #{orderETime}
+        </if>
+        <!-- 销售公司 -->
+        <if test="companyId != null and companyId != ''">
+            AND cu.company_id = #{companyId}
+        </if>
+        <!-- 训练营 -->
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND log.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        <!-- 营期 -->
+        <if test="periodId != null and periodId != ''">
+            AND log.period_id = #{periodId}
+        </if>
+        <!-- 会员id -->
+        <if test="userId != null and userId != ''">
+            AND log.user_id = #{userId}
+        </if>
+        GROUP BY d.dept_id
+    </select>
+    <select id="selectCompanyBaseDataWithIds" resultType="com.fs.his.vo.WatchLogReportVO">
+        SELECT
+        log.user_id userId,
+        log.period_id periodId,
+        log.log_id logId,
+        d.dept_id AS deptId,
+        d.dept_name AS salesDept,
+        c.company_name AS salesCompany
+        FROM fs_course_watch_log log
+        LEFT JOIN company_user cu ON log.company_user_id = cu.user_id
+        LEFT JOIN company_dept d ON cu.dept_id = d.dept_id
+        LEFT JOIN company c ON d.company_id = c.company_id
+        WHERE log.send_type = 1
+        <if test="sTime != null and eTime != null">
+            AND DATE(log.create_time) BETWEEN #{sTime} AND #{eTime}
+        </if>
+        <!-- 销售公司 -->
+        <if test="companyId != null and companyId != ''">
+            AND c.company_id = #{companyId}
+        </if>
+        <!--部门 -->
+        <if test="deptId != null and deptId != ''">
+            AND d.dept_id = #{deptId}
+        </if>
+        <!-- 训练营 -->
+        <if test="trainingCampId != null and trainingCampId != ''">
+            AND log.period_id IN (SELECT period_id FROM fs_user_course_period WHERE training_camp_id = #{trainingCampId})
+        </if>
+        <!-- 营期 -->
+        <if test="periodId != null and periodId != ''">
+            AND log.period_id = #{periodId}
+        </if>
+        <!-- 会员id -->
+        <if test="userId != null and userId != ''">
+            AND log.user_id = #{userId}
+        </if>
+        <!-- 会员手机号 -->
+        <if test="userPhone != null and userPhone != ''">
+            AND u.phone LIKE CONCAT('%', #{userPhone}, '%')
+        </if>
+        <if test="project != null and project != ''">
+            AND log.project = #{project}
+        </if>
+        <!-- 会员昵称 -->
+        <if test="nickName != null and nickName != ''">
+            AND u.nick_name LIKE CONCAT('%', #{nickName}, '%')
+        </if>
+        GROUP BY
+        d.dept_id,
+        d.dept_name,
+        c.company_name
+    </select>
     <sql id="commonConditions">
         <!-- 销售公司 -->
         <if test="companyId != null and companyId != ''">

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

@@ -331,7 +331,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         COUNT(CASE WHEN so.status = 3 THEN po.order_id END) AS receipt_order_count,
         COALESCE(SUM(CASE WHEN so.status = 3 THEN po.pay_money ELSE 0 END), 0) AS receipt_money
         FROM fs_package_order po
-        INNER JOIN fs_store_order so ON po.order_id = so.order_id
+        INNER JOIN fs_store_order so ON po.store_order_id = so.order_id
         GROUP BY po.company_id
         )
         <choose>