Browse Source

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

caoliqin 3 weeks ago
parent
commit
9b314c3a7a
64 changed files with 1302 additions and 93 deletions
  1. 18 0
      fs-ad-api/src/main/java/com/fs/framework/config/RedisConfig.java
  2. 5 5
      fs-admin/src/main/java/com/fs/company/controller/CompanyController.java
  3. 47 0
      fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java
  4. 2 2
      fs-admin/src/main/java/com/fs/course/controller/FsCoursePlaySourceConfigController.java
  5. 44 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCategoryController.java
  6. 3 3
      fs-admin/src/main/java/com/fs/his/controller/FsCompanyController.java
  7. 2 2
      fs-admin/src/main/java/com/fs/qw/controller/QwCompanyController.java
  8. 17 0
      fs-common-api/src/main/java/com/fs/framework/config/RedisConfig.java
  9. 19 0
      fs-company-app/src/main/java/com/fs/core/config/RedisConfig.java
  10. 14 5
      fs-company/src/main/java/com/fs/company/controller/course/FsCourseAnswerLogsController.java
  11. 14 4
      fs-company/src/main/java/com/fs/company/controller/course/FsCourseRedPacketLogController.java
  12. 19 0
      fs-company/src/main/java/com/fs/framework/config/RedisConfig.java
  13. 18 0
      fs-doctor-app/src/main/java/com/fs/framework/config/RedisConfig.java
  14. 18 0
      fs-framework/src/main/java/com/fs/framework/config/RedisConfig.java
  15. 17 0
      fs-hospital/src/main/java/com/fs/framework/config/RedisConfig.java
  16. 18 0
      fs-ipad-task/src/main/java/com/fs/framework/config/RedisConfig.java
  17. 18 0
      fs-live-app/src/main/java/com/fs/framework/config/RedisConfig.java
  18. 18 0
      fs-qw-api-msg/src/main/java/com/fs/framework/config/RedisConfig.java
  19. 18 0
      fs-qw-api/src/main/java/com/fs/framework/config/RedisConfig.java
  20. 19 0
      fs-qw-mq/src/main/java/com/fs/framework/config/RedisConfig.java
  21. 19 0
      fs-qw-task/src/main/java/com/fs/framework/config/RedisConfig.java
  22. 18 0
      fs-qw-voice/src/main/java/com/fs/framework/config/RedisConfig.java
  23. 18 0
      fs-qwhook-msg/src/main/java/com/fs/framework/config/RedisConfig.java
  24. 18 0
      fs-qwhook-sop/src/main/java/com/fs/framework/config/RedisConfig.java
  25. 19 0
      fs-qwhook/src/main/java/com/fs/framework/config/RedisConfig.java
  26. 18 0
      fs-redis/src/main/java/com/fs/framework/config/RedisConfig.java
  27. 17 0
      fs-repeat-api/src/main/java/com/fs/framework/config/RedisConfig.java
  28. 6 1
      fs-service/src/main/java/com/fs/core/config/RedissonConfig.java
  29. 2 0
      fs-service/src/main/java/com/fs/course/domain/FsUserCourseCategory.java
  30. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseCategoryMapper.java
  31. 1 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java
  32. 1 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java
  33. 2 1
      fs-service/src/main/java/com/fs/course/service/IFsUserCompanyUserService.java
  34. 1 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseCategoryService.java
  35. 10 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyUserServiceImpl.java
  36. 4 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseCategoryServiceImpl.java
  37. 74 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  38. 1 0
      fs-service/src/main/java/com/fs/course/vo/FsCoursePlaySourceConfigVO.java
  39. 2 2
      fs-service/src/main/java/com/fs/his/mapper/FsPackageOrderMapper.java
  40. 49 0
      fs-service/src/main/java/com/fs/his/mapper/FsStoreAfterSalesMapper.java
  41. 1 1
      fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java
  42. 4 0
      fs-service/src/main/java/com/fs/his/service/IFsStoreAfterSalesService.java
  43. 19 12
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java
  44. 1 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreCartScrmMapper.java
  45. 7 32
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  46. 3 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreProductQueryParam.java
  47. 11 3
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductScrmServiceImpl.java
  48. 5 0
      fs-service/src/main/java/com/fs/statis/domain/FsStatisSalerWatch.java
  49. 1 0
      fs-service/src/main/resources/application-config-bly.yml
  50. 1 0
      fs-service/src/main/resources/application-config-dev.yml
  51. 5 5
      fs-service/src/main/resources/application-config-druid-knt.yml
  52. 153 0
      fs-service/src/main/resources/application-druid-bnkc-test.yml
  53. 162 0
      fs-service/src/main/resources/application-druid-knt-test.yml
  54. 155 0
      fs-service/src/main/resources/application-druid-nmgyt-test.yml
  55. 10 6
      fs-service/src/main/resources/mapper/course/FsUserCourseCategoryMapper.xml
  56. 4 3
      fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml
  57. 33 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  58. 4 0
      fs-service/src/main/resources/mapper/statis/FsStatisSalerWatchMapper.xml
  59. 17 0
      fs-store/src/main/java/com/fs/framework/config/RedisConfig.java
  60. 17 0
      fs-user-app-ai-chat/src/main/java/com/fs/framework/config/RedisConfig.java
  61. 19 0
      fs-user-app/src/main/java/com/fs/framework/config/RedisConfig.java
  62. 2 2
      fs-user-app/src/main/resources/application.yml
  63. 18 0
      fs-watch/src/main/java/com/fs/framework/config/RedisConfig.java
  64. 19 0
      fs-wx-api/src/main/java/com/fs/framework/config/RedisConfig.java

+ 18 - 0
fs-ad-api/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -67,6 +67,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

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

@@ -71,7 +71,7 @@ public class CompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             param.setDeptId(loginUser.getDeptId());
         }
         List<CompanyVO> list = companyService.selectCompanyVOList(param);
@@ -89,7 +89,7 @@ public class CompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             company.setDeptId(loginUser.getDeptId());
         }
         List<CompanyVO> list = companyService.selectCompanyVOList(company);
@@ -178,7 +178,7 @@ public class CompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             map.setDeptId(loginUser.getDeptId());
         }
         List<Company> list = companyService.selectCompanyList(map);
@@ -194,7 +194,7 @@ public class CompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             param.setDeptId(loginUser.getDeptId());
         }
         List<CompanyCrmVO> list = companyService.selectCompanyCrmDayCountList(param);
@@ -276,7 +276,7 @@ public class CompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             deptId = loginUser.getDeptId();
         }
         List<OptionsVO> list = companyService.selectAllCompanyList(deptId);

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

@@ -19,6 +19,7 @@ import com.fs.crm.service.ICrmCustomerService;
 import com.fs.crm.service.ICrmCustomerVisitService;
 import com.fs.crm.vo.CrmCustomerStatisticsVO;
 import com.fs.crm.vo.CrmCustomerVisitStatisticsVO;
+import com.fs.his.service.IFsStoreAfterSalesService;
 import com.fs.his.service.IFsStoreOrderService;
 import com.fs.his.service.IFsStorePaymentService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -49,6 +50,10 @@ public class CompanyStatisticsController extends BaseController
 
     @Autowired
     private IFsStoreOrderService storeOrderService;
+
+    @Autowired
+    private IFsStoreAfterSalesService storeAfterSalesService;
+
     @Autowired
     private IFsStorePaymentService storePaymentService;
     @Autowired
@@ -146,6 +151,48 @@ public class CompanyStatisticsController extends BaseController
         }
     }
 
+    @GetMapping("/afterSalesOrder")
+    public R afterSalesOrder(FsStoreStatisticsParam param)
+    {
+        if(StringUtils.isNotEmpty(param.getUserIds())){
+            String[] userIds=param.getUserIds().split(",");
+            Long[] ids=new Long[userIds.length];
+            for(int i=0;i<ids.length; i++){
+                ids[i]=Long.parseLong(userIds[i]);
+            }
+            param.setUsers(ids);
+        }
+        else{
+            //获取部门下的所有用户
+            CompanyUser usermap=new CompanyUser();
+            usermap.setDeptId(param.getDeptId());
+            List<CompanyUser> users = userService.getUserListByDeptId(usermap);
+            List<Long> userIds = users.stream().map(element -> element.getUserId()).collect(Collectors.toList());
+            param.setUsers(userIds.toArray(new Long[userIds.size()]));
+        }
+        if(param.getUsers()!=null&&param.getUsers().length>0){
+            List<FsStoreOrderStatisticsVO> list= storeAfterSalesService.selectFsStoreAfterSalesServiceStatisticsList(param);
+
+            TimeUtils.TimeEntity timeEntity= TimeUtils.parseTime(param.getType().toString(),param.getStartTime(),param.getEndTime());
+            timeEntity.setUserIds(param.getUsers());
+            Integer cycleNum = timeEntity.getCycleNum();
+            Integer beginTime = timeEntity.getBeginTime();
+            List<Integer> timeList = new ArrayList<>();
+            for (int i = 1; i <= cycleNum; i++) {
+                timeList.add(beginTime);
+                beginTime = TimeUtils.formatTime(beginTime);
+            }
+            List<JSONObject> jsonObjectList = storeOrderService.selectFsPackageOrderCounts(timeEntity.toMap());
+            List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
+            List<Integer> orderCount = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("orderCount")).collect(Collectors.toList());
+            List<Integer> payPrice = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("payPrice")).collect(Collectors.toList());
+            return R.ok().put("list",list).put("dates",dates).put("orderCount",orderCount).put("payPrice",payPrice);
+        }
+        else {
+            return R.ok("未查找到数据");
+        }
+    }
+
 
     @GetMapping("/inquiryOrder")
     public R storeInquiryOrder(FsStoreStatisticsParam param)

+ 2 - 2
fs-admin/src/main/java/com/fs/course/controller/FsCoursePlaySourceConfigController.java

@@ -58,7 +58,7 @@ public class FsCoursePlaySourceConfigController extends BaseController {
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         Long userId = null;
         Long deptId = null;
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             deptId = loginUser.getDeptId();
             if(config.getDept() == null || !config.getDept()){
                 userId = loginUser.getUserId();
@@ -148,7 +148,7 @@ public class FsCoursePlaySourceConfigController extends BaseController {
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         QueryWrapper<FsCoursePlaySourceConfig> queryWrapper = new QueryWrapper<FsCoursePlaySourceConfig>().eq("is_del", 0);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             queryWrapper.eq("create_user_id", loginUser.getUserId()).eq(config.getDept() == null || !config.getDept(), "create_dept_id", loginUser.getDeptId());
         }
         if(companyId != null){

+ 44 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCategoryController.java

@@ -3,9 +3,18 @@ package com.fs.course.controller;
 import java.util.List;
 
 import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.utils.ServletUtils;
+import com.fs.framework.web.service.TokenService;
 import com.fs.his.domain.FsStoreProductCategory;
 import com.fs.his.vo.FsStoreProductCategoryVO;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
+import com.fs.course.config.CourseConfig;
+
 import com.fs.his.vo.OptionsVO;
+import com.fs.system.service.ISysConfigService;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -38,6 +47,12 @@ public class FsUserCourseCategoryController extends BaseController
     @Autowired
     private IFsUserCourseCategoryService fsUserCourseCategoryService;
 
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysConfigService configService;
+
     /**
      * 查询课堂分类列表
      */
@@ -45,6 +60,13 @@ public class FsUserCourseCategoryController extends BaseController
     @GetMapping("/list")
     public AjaxResult list(FsUserCourseCategory fsUserCourseCategory)
     {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsUserCourseCategory.setUserId(userId);
+        }
         List<FsUserCourseCategory> list = fsUserCourseCategoryService.selectFsUserCourseCategoryList(fsUserCourseCategory);
         return AjaxResult.success(list);
     }
@@ -57,6 +79,13 @@ public class FsUserCourseCategoryController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsUserCourseCategory fsUserCourseCategory)
     {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsUserCourseCategory.setUserId(userId);
+        }
         List<FsUserCourseCategory> list = fsUserCourseCategoryService.selectFsUserCourseCategoryList(fsUserCourseCategory);
         ExcelUtil<FsUserCourseCategory> util = new ExcelUtil<FsUserCourseCategory>(FsUserCourseCategory.class);
         return util.exportExcel(list, "课堂分类数据");
@@ -80,6 +109,13 @@ public class FsUserCourseCategoryController extends BaseController
     @PostMapping
     public AjaxResult add(@RequestBody FsUserCourseCategory fsUserCourseCategory)
     {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsUserCourseCategory.setUserId(userId);
+        }
         return toAjax(fsUserCourseCategoryService.insertFsUserCourseCategory(fsUserCourseCategory));
     }
 
@@ -119,6 +155,14 @@ public class FsUserCourseCategoryController extends BaseController
     @GetMapping("/getCatePidList")
     public R getCatePidList()
     {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList(userId);
+            return R.ok().put("data", list);
+        }
         List<OptionsVO> list = fsUserCourseCategoryService.selectFsUserCourseCategoryPidList();
         return R.ok().put("data", list);
     }

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

@@ -81,7 +81,7 @@ public class FsCompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             company.setDeptId(loginUser.getDeptId());
         }
         List<CompanyVO> list = companyService.selectCompanyListVO(company);
@@ -96,7 +96,7 @@ public class FsCompanyController extends BaseController
         Long depId = null;
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             depId = loginUser.getDeptId();
         }
         List<OptionsVO> list = companyService.selectAllCompanyList(depId);
@@ -152,7 +152,7 @@ public class FsCompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             company.setDeptId(loginUser.getDeptId());
         }
         return companyService.insertCompany(company);

+ 2 - 2
fs-admin/src/main/java/com/fs/qw/controller/QwCompanyController.java

@@ -57,7 +57,7 @@ public class QwCompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             qwCompany.setCreateDeptId(loginUser.getDeptId());
             qwCompany.setCreateUserId(loginUser.getUserId());
         }
@@ -74,7 +74,7 @@ public class QwCompanyController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if(!loginUser.isAdmin() && config.getIsBound() != null && config.getIsBound()){
+        if(!loginUser.isAdmin() && config.getDept() != null && config.getDept()){
             deptId = loginUser.getDeptId();
             if(config.getDept() == null || !config.getDept()){
                 userId = loginUser.getUserId();

+ 17 - 0
fs-common-api/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -67,7 +67,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 19 - 0
fs-company-app/src/main/java/com/fs/core/config/RedisConfig.java

@@ -64,6 +64,25 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();

+ 14 - 5
fs-company/src/main/java/com/fs/company/controller/course/FsCourseAnswerLogsController.java

@@ -1,5 +1,7 @@
 package com.fs.company.controller.course;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.controller.BaseController;
@@ -8,11 +10,13 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.param.FsCourseAnswerLogsParam;
 import com.fs.course.service.IFsCourseAnswerLogsService;
 import com.fs.course.vo.FsCourseAnswerLogsListVO;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
+import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -38,6 +42,9 @@ public class FsCourseAnswerLogsController extends BaseController
 
     @Autowired
     private TokenService tokenService;
+
+    @Autowired
+    private ISysConfigService configService;
     /**
      * 查询答题日志列表
      */
@@ -48,11 +55,13 @@ public class FsCourseAnswerLogsController extends BaseController
         if (param.getPhoneMk() != null && param.getPhoneMk() != "") {
             param.setPhone(param.getPhoneMk());
         }
-
-//        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        // 如果他可以看两个销售公司就会查不出来
-//        param.setCompanyId( loginUser.getCompany().getCompanyId());
-
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            param.setCompanyId( loginUser.getCompany().getCompanyId());
+        }
         List<FsCourseAnswerLogsListVO> list = fsCourseAnswerLogsService.selectFsCourseAnswerLogsListVONew(param);
         TableDataInfo rspData = new TableDataInfo();
         rspData.setCode(HttpStatus.SUCCESS);

+ 14 - 4
fs-company/src/main/java/com/fs/company/controller/course/FsCourseRedPacketLogController.java

@@ -1,5 +1,7 @@
 package com.fs.company.controller.course;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.controller.BaseController;
@@ -9,6 +11,7 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCourseRedPacketLog;
 import com.fs.course.mapper.FsUserCourseMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
@@ -19,6 +22,7 @@ import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.OptionsVO;
+import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -45,7 +49,8 @@ public class FsCourseRedPacketLogController extends BaseController
     FsUserCourseVideoMapper fsUserCourseVideoMapper;
     @Autowired
     private TokenService tokenService;
-
+    @Autowired
+    private ISysConfigService configService;
     /**
      * 查询短链课程看课记录列表
      */
@@ -57,9 +62,14 @@ public class FsCourseRedPacketLogController extends BaseController
         if (fsCourseRedPacketLog.getPhoneMk() != null && fsCourseRedPacketLog.getPhoneMk() != "") {
             fsCourseRedPacketLog.setPhone(encryptPhone(fsCourseRedPacketLog.getPhoneMk()));
         }
-//        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        // 如果他可以看两个销售公司就会查不出来
-//        fsCourseRedPacketLog.setCompanyId( loginUser.getCompany().getCompanyId());
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsCourseRedPacketLog.setCompanyId( loginUser.getCompany().getCompanyId());
+        }
 
         List<FsCourseRedPacketLogListPVO> list = fsCourseRedPacketLogService.selectFsCourseRedPacketLogListVO(fsCourseRedPacketLog);
         for (FsCourseRedPacketLogListPVO fsCourseRedPacketLogListPVO : list) {

+ 19 - 0
fs-company/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -56,6 +56,25 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     public RedisTemplate<String, Boolean> redisTemplateForBoolean(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, Boolean> template = new RedisTemplate<>();

+ 18 - 0
fs-doctor-app/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

+ 18 - 0
fs-framework/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

+ 17 - 0
fs-hospital/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -69,7 +69,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 18 - 0
fs-ipad-task/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 18 - 0
fs-live-app/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -67,6 +67,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

+ 18 - 0
fs-qw-api-msg/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();

+ 18 - 0
fs-qw-api/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -92,6 +92,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {

+ 19 - 0
fs-qw-mq/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,25 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 19 - 0
fs-qw-task/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,25 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 18 - 0
fs-qw-voice/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -67,6 +67,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

+ 18 - 0
fs-qwhook-msg/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 18 - 0
fs-qwhook-sop/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -67,6 +67,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
 
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })

+ 19 - 0
fs-qwhook/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,25 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
+
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 18 - 0
fs-redis/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -68,6 +68,24 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 17 - 0
fs-repeat-api/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -92,7 +92,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();

+ 6 - 1
fs-service/src/main/java/com/fs/core/config/RedissonConfig.java

@@ -19,6 +19,9 @@ public class RedissonConfig {
     @Value("${spring.redis.host}")
     private String host;
 
+    @Value("${spring.redis.database}")
+    private int database;
+
     @Bean(destroyMethod = "shutdown")
     public RedissonClient redissonClient() {
         String address = "redis://" + host + ":" + port;
@@ -26,7 +29,9 @@ public class RedissonConfig {
         config.useSingleServer()
                 .setAddress(address) // 设置连接地址
                 .setConnectionMinimumIdleSize(10) // 最小空闲连接数
-                .setConnectionPoolSize(64); // 最大连接数
+                .setConnectionPoolSize(64) // 最大连接数
+                .setDatabase(database); //数据库
+
         if (null!=password&&!"".equals(password)) {
             config.useSingleServer().setPassword(password);
         }

+ 2 - 0
fs-service/src/main/java/com/fs/course/domain/FsUserCourseCategory.java

@@ -40,4 +40,6 @@ public class FsUserCourseCategory extends BaseEntity
 
     private String pic;
 
+
+    private Long userId;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCourseCategoryMapper.java

@@ -71,6 +71,9 @@ public interface FsUserCourseCategoryMapper
     @Select("select cate_id dict_value, cate_name dict_label  from fs_user_course_category WHERE pid = 0 and is_del=0 ")
     List<OptionsVO> selectFsUserCourseCategoryPidList();
 
+    @Select("select cate_id dict_value, cate_name dict_label  from fs_user_course_category WHERE pid = 0 and is_del=0 and user_id = #{userId}")
+    List<OptionsVO> selectFsUserCourseCategoryPidListByUserId(Long userId);
+
     @Select("select cate_id dict_value, cate_name dict_label  from fs_user_course_category WHERE pid =#{pid} and is_del=0 ")
     List<OptionsVO> selectCateListByPid(Long pid);
 

+ 1 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java

@@ -48,4 +48,5 @@ public class FsCoursePlaySourceConfigCreateParam {
 
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
+    private Long createDeptId;
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java

@@ -45,4 +45,5 @@ public class FsCoursePlaySourceConfigEditParam {
 
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
+    private Long createDeptId;
 }

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

@@ -9,7 +9,7 @@ import java.util.Map;
 
 /**
  * 微信用户和销售关系Service接口
- * 
+ *
  * @author fs
  * @date 2025-05-09
  */
@@ -75,6 +75,7 @@ public interface IFsUserCompanyUserService extends IService<FsUserCompanyUser>{
      * @param projectId   项目ID
      * @return FsUserCompanyUser
      */
+    FsUserCompanyUser selectByUserIdAndProjectId(Long userId, Long projectId,Long companyUserId);
     FsUserCompanyUser selectByUserIdAndProjectId(Long userId, Long projectId);
 
     /**

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

@@ -64,6 +64,7 @@ public interface IFsUserCourseCategoryService
     List<OptionsVO> selectFsUserCoursePidList();
 
     List<OptionsVO> selectFsUserCourseCategoryPidList();
+    List<OptionsVO> selectFsUserCourseCategoryPidList(Long userId);
 
     List<OptionsVO> selectCateListByPid(Long pid);
 }

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

@@ -17,7 +17,7 @@ import java.util.Objects;
 
 /**
  * 微信用户和销售关系Service业务层处理
- * 
+ *
  * @author fs
  * @date 2025-05-09
  */
@@ -111,6 +111,15 @@ public class FsUserCompanyUserServiceImpl extends ServiceImpl<FsUserCompanyUserM
      * @param projectId   项目ID
      * @return FsUserCompanyUser
      */
+    @Override
+    public FsUserCompanyUser selectByUserIdAndProjectId(Long userId, Long projectId,Long companyUserId) {
+        LambdaQueryWrapper<FsUserCompanyUser> queryWrapper = Wrappers.<FsUserCompanyUser>lambdaQuery()
+                .eq(FsUserCompanyUser::getUserId, userId)
+                .eq(FsUserCompanyUser::getProjectId, projectId)
+                .eq(FsUserCompanyUser::getCompanyUserId, companyUserId);
+        return getOne(queryWrapper);
+    }
+
     @Override
     public FsUserCompanyUser selectByUserIdAndProjectId(Long userId, Long projectId) {
         LambdaQueryWrapper<FsUserCompanyUser> queryWrapper = Wrappers.<FsUserCompanyUser>lambdaQuery()

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

@@ -105,7 +105,10 @@ public class FsUserCourseCategoryServiceImpl implements IFsUserCourseCategorySer
         return fsUserCourseCategoryMapper.selectFsUserCourseCategoryPidList();
     }
 
-
+    @Override
+    public List<OptionsVO> selectFsUserCourseCategoryPidList(Long userId) {
+        return fsUserCourseCategoryMapper.selectFsUserCourseCategoryPidListByUserId(userId);
+    }
     @Override
     public List<OptionsVO> selectCateListByPid(Long pid) {
         return fsUserCourseCategoryMapper.selectCateListByPid(pid);

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

@@ -89,6 +89,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -125,6 +126,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
      */
     private static final String REDPACKET_COMPANY_MONEY = "redpacket_money";
 
+    /**
+     * 用户领取红包限制
+     */
+    private static final String REDPACKET_USER_LIMIT = "redpacket_user_limit:%s:%d";
+
     /**
      * 红包改变记录
      */
@@ -255,6 +261,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Autowired
     private RedisTemplate<String,BigDecimal> redisTemplate;
 
+    @Autowired
+    private RedisTemplate<String,Integer> redisTemplateInteger;
+
+    /**
+     * 红包领取数量限制 默认一个用户当天最多只能领取10个
+     */
+    @Value("${RED_PACKET_LIMIT_COUNT:10}")
+    private Integer RED_PACKET_LIMIT_COUNT;
 
     /**
      * 查询课堂视频
@@ -1024,6 +1038,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (log == null) {
             return R.error("无记录");
         }
+        if (log.getLogType() != 2) {
+            return R.error("未完课");
+        }
         if (log.getRewardType() != null) {
             FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
             if(packetLog != null && packetLog.getStatus() == 1) {
@@ -1239,6 +1256,25 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     private R sendRedPacketRewardToUser(FsCourseSendRewardUParam param, FsCourseWatchLog log, CourseConfig config, WxSendRedPacketParam packetParam, BigDecimal amount) {
 
+        // 判断当前用户是否限流
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String today = sdf.format(new Date());
+        String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, param.getUserId());
+        Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);
+
+        // 首次领取
+        if(userCount == null) {
+            userCount = 0;
+            long expireSeconds = getExpireSeconds();
+            redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
+        }
+
+        if(userCount >= RED_PACKET_LIMIT_COUNT){
+            logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",param.getUserId());
+            return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
+        }
+
+
         BigDecimal companyMoney = null;
         if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
             companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
@@ -1300,12 +1336,28 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 companyMoney = companyMoney.subtract(amount);
                 redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
             }
+
+            // 用户领取红包次数+1
+            redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
+
             return sendRedPacket;
         } else {
             return R.error("奖励发送失败,请联系客服");
         }
     }
 
+    private static long getExpireSeconds() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.DAY_OF_YEAR, 1);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        // 计算从现在到明天凌晨的秒数
+        long expireSeconds = (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
+        return expireSeconds;
+    }
+
 
     private void handleFsUserWx(FsUser user, String appId) {
         FsUserWx fsUserWx = new FsUserWx();
@@ -1421,6 +1473,24 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                     return R.error("[红包领取] 系统繁忙,请重试!");
                 }
 
+                // 判断当前用户是否限流
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+                String today = sdf.format(new Date());
+                String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, param.getUserId());
+                Integer userCount =  redisTemplateInteger.opsForValue().get(userLimitKey);
+
+                // 首次领取
+                if(userCount == null) {
+                    userCount = 0;
+                    long expireSeconds = getExpireSeconds();
+                    redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
+                }
+
+                if(userCount >= RED_PACKET_LIMIT_COUNT){
+                    logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",param.getUserId());
+                    return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
+                }
+
                 BigDecimal companyMoney = null;
                 if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
                     companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
@@ -1484,6 +1554,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                         redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
                     }
 
+                    // 用户领取红包次数+1
+                    redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
                     return sendRedPacket;
                 } else {
                     return R.error("奖励发送失败,请联系客服");
@@ -1796,7 +1868,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         }
 
         // 查询【用户-项目】关系
-        FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject);
+        FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject,companyUser.getUserId());
 
         // 添加逻辑:如果存在fs_user表数据,但是又不存在fs_user_company_user表,则表示是以前企微看课的,需要手动绑定
         if(Objects.isNull(userCompanyUser)) {
@@ -2856,3 +2928,4 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
 }
+

+ 1 - 0
fs-service/src/main/java/com/fs/course/vo/FsCoursePlaySourceConfigVO.java

@@ -54,4 +54,5 @@ public class FsCoursePlaySourceConfigVO {
      * 是否是互医/商城小程序
      */
     private Integer isMall;
+    private Long createDeptId;
 }

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

@@ -86,7 +86,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_store_order fso ON fso.order_id= o.store_order_id "+
-            "LEFT JOIN (SELECT sp.*,ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn\n" +
+            "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" +
             " where 1 = 1 \n" +
@@ -151,7 +151,7 @@ public interface FsPackageOrderMapper
     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 "+
-            "LEFT JOIN (SELECT sp.*,ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn\n" +
+            "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" +
             "  <where>  \n" +

+ 49 - 0
fs-service/src/main/java/com/fs/his/mapper/FsStoreAfterSalesMapper.java

@@ -1,6 +1,9 @@
 package com.fs.his.mapper;
 
 import java.util.List;
+
+import com.fs.company.param.FsStoreStatisticsParam;
+import com.fs.company.vo.FsStoreOrderStatisticsVO;
 import com.fs.his.domain.FsStoreAfterSales;
 import com.fs.his.domain.FsStoreAfterSalesItem;
 import com.fs.his.domain.FsStoreAfterSalesLogs;
@@ -238,4 +241,50 @@ public interface FsStoreAfterSalesMapper
             " order by so.id desc "+
             "</script>"})
     Long selectFsStoreAfterSalesExcelListVOCount(@Param("maps") FsStoreAfterSalesParam fsStoreAfterSales);
+
+    @Select({"<script> " +
+            "select u.nick_name, count(o.order_id) as order_count,sum(IFNULL(o.pay_price,0)) as pay_price  " +
+            "from  fs_store_after_sales o left join company_user u on o.company_user_id=u.user_id  " +
+            "where o.status &gt; 1 " +
+            "<if test = 'maps.type != null and maps.type ==1 '> " +
+            "and TO_DAYS(o.create_time) = TO_DAYS(NOW()) " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==2 '> " +
+            "and TO_DAYS(NOW()) - TO_DAYS(o.create_time) &lt;= 1 " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==3 '> " +
+            "and YEARWEEK(DATE_FORMAT(o.create_time,'%Y-%m-%d')) = YEARWEEK(NOW()) " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==4 '> " +
+            "and YEARWEEK(DATE_FORMAT(o.create_time,'%Y-%m-%d')) = YEARWEEK(NOW())-1 " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==5 '> " +
+            "and DATE_FORMAT(o.create_time,'%Y%m') = DATE_FORMAT(CURDATE(),'%Y%m') " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==6 '> " +
+            "and PERIOD_DIFF(DATE_FORMAT(NOW(),'%Y%m'),DATE_FORMAT(o.create_time,'%Y%m')) = 1 " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==7 '> " +
+            "and QUARTER(o.create_time) = QUARTER(NOW()) " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==8 '> " +
+            "and QUARTER(o.create_time) = QUARTER(DATE_SUB(NOW(),INTERVAL 1 QUARTER)) " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==9 '> " +
+            "and YEAR(o.create_time)=YEAR(NOW()) " +
+            "</if>" +
+            "<if test = 'maps.type != null and maps.type ==10 '> " +
+            "and  YEAR(o.create_time) = YEAR(DATE_SUB(NOW(),INTERVAL 1 YEAR))" +
+            "</if>" +
+            "<if test = 'maps.startTime != null and maps.startTime != \"\" '> " +
+            "AND date_format(o.create_time,'%y%m%d') &gt;= date_format(#{maps.startTime},'%y%m%d')"+
+            "</if>" +
+            "<if test = 'maps.endTime != null and maps.endTime != \"\" '> " +
+            "AND date_format(o.create_time,'%y%m%d') &lt;= date_format(#{maps.endTime},'%y%m%d')"+
+            "</if>" +
+            "and  o.`company_user_id` IN " +
+            "<foreach  item='item' index='index' collection='maps.users' open='(' separator=',' close=')'> #{item}    </foreach>"+
+            " group by o.company_user_id "+
+            "</script>"})
+    List<FsStoreOrderStatisticsVO> selectFsPackageOrderStatisticsList(@Param("maps")FsStoreStatisticsParam param);
 }

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

@@ -670,7 +670,7 @@ public interface FsStoreOrderMapper
             " left join company_user cu on cu.user_id=so.company_user_id " +
             " left join company_tcm_schedule cts on cts.id = so.schedule_id " +
             " left join fs_patient pat on pat.patient_id = p.patient_id " +
-            "LEFT JOIN (SELECT sp.*,ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn\n" +
+            "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 = so.order_code AND sp_latest.rn = 1\n" +
             "        LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id" +
             " WHERE so.is_del=0 "+

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

@@ -3,6 +3,8 @@ package com.fs.his.service;
 import java.util.List;
 
 import com.fs.common.core.domain.R;
+import com.fs.company.param.FsStoreStatisticsParam;
+import com.fs.company.vo.FsStoreOrderStatisticsVO;
 import com.fs.his.domain.FsStoreAfterSales;
 import com.fs.his.domain.FsStoreAfterSalesItem;
 import com.fs.his.domain.FsStoreAfterSalesLogs;
@@ -100,4 +102,6 @@ public interface IFsStoreAfterSalesService
     Long selectFsStoreAfterSalesExcelListVOCount(FsStoreAfterSalesParam fsStoreAfterSales);
 
     void exportData(FsStoreAfterSalesParam fsStoreAfterSales);
+
+    List<FsStoreOrderStatisticsVO> selectFsStoreAfterSalesServiceStatisticsList(FsStoreStatisticsParam param);
 }

+ 19 - 12
fs-service/src/main/java/com/fs/his/service/impl/FsStoreAfterSalesServiceImpl.java

@@ -18,8 +18,10 @@ import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.param.FsStoreStatisticsParam;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.impl.CompanyServiceImpl;
+import com.fs.company.vo.FsStoreOrderStatisticsVO;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.his.config.FsSysConfig;
@@ -543,18 +545,18 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
                 Map<String, Object> extendInfoMap = new HashMap<>();
                 extendInfoMap.put("org_req_seq_id", orderType + "-" + payment.getPayCode());
                 request.setExtendInfo(extendInfoMap);
-//                HuiFuRefundResult refund = huiFuService.refund(request);
-//                logger.info("订单退款返回结果:退款订单id:" + order.getOrderId() + refund);
-//                if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {
-//                    FsStorePayment paymentMap = new FsStorePayment();
-//                    paymentMap.setPaymentId(payment.getPaymentId());
-//                    paymentMap.setStatus(-1);
-//                    paymentMap.setRefundTime(DateUtils.getNowDate());
-//                    paymentMap.setRefundMoney(payment.getPayMoney());
-//                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
-//                } else {
-//                    throw new CustomException("退款请求失败" + refund.getResp_desc());
-//                }
+                HuiFuRefundResult refund = huiFuService.refund(request);
+                logger.info("订单退款返回结果:退款订单id:" + order.getOrderId() + refund);
+                if ((refund.getResp_code().equals("00000000") || refund.getResp_code().equals("00000100")) && (refund.getTrans_stat().equals("S") || refund.getTrans_stat().equals("P"))) {
+                    FsStorePayment paymentMap = new FsStorePayment();
+                    paymentMap.setPaymentId(payment.getPaymentId());
+                    paymentMap.setStatus(-1);
+                    paymentMap.setRefundTime(DateUtils.getNowDate());
+                    paymentMap.setRefundMoney(payment.getPayMoney());
+                    fsStorePaymentMapper.updateFsStorePayment(paymentMap);
+                } else {
+                    throw new CustomException("退款请求失败" + refund.getResp_desc());
+                }
             }
             //管易作废
             if (StringUtils.isNotEmpty(fsStoreOrder.getExtendOrderId())) {
@@ -951,4 +953,9 @@ public class FsStoreAfterSalesServiceImpl implements IFsStoreAfterSalesService {
         task.setFileUrl(result.get("msg").toString());
         fsExportTaskMapper.updateFsExportTask(task);
     }
+
+    @Override
+    public List<FsStoreOrderStatisticsVO> selectFsStoreAfterSalesServiceStatisticsList(FsStoreStatisticsParam param) {
+        return fsStoreAfterSalesMapper.selectFsPackageOrderStatisticsList(param);
+    }
 }

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

@@ -85,7 +85,7 @@ public interface FsStoreCartScrmMapper
             "</if>" +
             "and c.user_id= #{uid} " +
             "</script>"})
-    List<FsStoreCartVO> selectFsStoreCartListByUid(long uid,@Param("config") MedicalMallConfig config);
+    List<FsStoreCartVO> selectFsStoreCartListByUid(@Param("uid") long uid, @Param("config") MedicalMallConfig config);
     @Delete({"<script>"+
             "delete from fs_store_cart_scrm where id in"+
            "<foreach collection='array' item='id' open='(' separator=',' close=')'>#{id}</foreach>"+

+ 7 - 32
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.mapper;
 
 import java.util.List;
+import java.util.Map;
 
 import com.fs.his.param.FsStoreProductListSParam;
 import com.fs.his.vo.FsStoreProductListSVO;
@@ -180,7 +181,9 @@ public interface FsStoreProductScrmMapper
     @Select({"<script> " +
             "select p.* from fs_store_product_scrm p  " +
             //新增审核状态及所属店铺审核状态
+            "<if test = 'maps.isStores != null and maps.isStores == 1   '>"+
             "inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1 " +
+            "</if>" +
             "where p.is_del=0 and p.is_show=1  and p.is_audit = '1'" +
             "<if test = 'maps.productName != null and  maps.productName !=\"\"    '> " +
             "and (p.product_name like CONCAT('%',#{maps.productName},'%')  or p.keyword like concat('%',#{maps.productName},'%') ) " +
@@ -242,28 +245,10 @@ public interface FsStoreProductScrmMapper
     @Update("update fs_store_product_scrm set stock=stock+#{num}, sales=sales-#{num}" +
             " where product_id=#{productId}")
     int incStockDecSales( @Param("num")Long num, @Param("productId")Long productId);
-    @Select("select p.* from fs_store_product_scrm p " +
-            //新增审核状态及所属店铺审核状态
-            "<if test='config.isAudit == \"1\" '>" +
-            "inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1 " +
-            "</if>" +
-            "where p.is_del=0 and p.is_show=1 " +
-            "<if test='config.isAudit == \"1\" '>" +
-            "and p.is_audit = '1'  " +
-            "</if>" +
-            "and  p.is_new=1 and p.is_display=1 order by p.sort desc limit #{count}")
-    List<FsStoreProductListQueryVO> selectFsStoreProductNewQuery(int count,@Param("config") MedicalMallConfig  config);
-    @Select("select p.* from fs_store_product_scrm p " +
-            //新增审核状态及所属店铺审核状态
-            "<if test='config.isAudit == \"1\" '>" +
-            "inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1 " +
-            "</if>" +
-            "where p.is_del=0 and p.is_show=1 " +
-            "<if test='config.isAudit == \"1\" '>" +
-            "and p.is_audit = '1'" +
-            "</if>" +
-            "and  p.is_hot=1 and p.is_display=1 order by p.sort desc limit #{count}")
-    List<FsStoreProductListQueryVO> selectFsStoreProductHotQuery(int count,@Param("config") MedicalMallConfig  config);
+
+    List<FsStoreProductListQueryVO> selectFsStoreProductNewQuery(Map<String, Object> params);
+
+    List<FsStoreProductListQueryVO> selectFsStoreProductHotQuery(Map<String, Object> params);
     @Select("select p.* from fs_store_product_scrm p " +
             //新增审核状态及所属店铺审核状态
             "<if test='config.isAudit == \"1\" '>" +
@@ -276,16 +261,6 @@ public interface FsStoreProductScrmMapper
             "and  p.is_good=1 and p.is_display=1 order by p.sort desc limit #{count}")
     List<FsStoreProductListQueryVO> selectFsStoreProductGoodQuery(int count,@Param("config") MedicalMallConfig  config);
     List<FsStoreProductListQueryVO> selectFsStoreProductTuiListQuery(@Param("config") MedicalMallConfig  config);
-    @Select("select p.* from fs_store_product_scrm p " +
-            //新增审核状态及所属店铺审核状态
-            "<if test='config.isAudit == \"1\" '>" +
-            "inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1 " +
-            "</if>" +
-            "where p.is_del=0 and p.is_show=1 " +
-            "<if test='config.isAudit == \"1\" '>" +
-            "and p.is_audit = '1'" +
-            "</if>" +
-            "and  p.is_good=1 and p.is_display=1 order by p.sort desc")
     List<FsStoreProductListQueryVO> selectFsStoreProductGoodListQuery(@Param("config") MedicalMallConfig  config);
     @Select({"<script> " +
             "select count(1) from fs_store_product_scrm  " +

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

@@ -32,4 +32,7 @@ public class FsStoreProductQueryParam extends BaseQueryParam implements Serializ
     private Integer isDrug;
     //店铺id
     private Long storeId;
+
+    //是否多店铺 1是
+    private Integer isStores;
 }

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

@@ -338,7 +338,7 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
         product.setStoreId(param.getStoreId());
         product.setIsDrug(param.getIsDrug().toString());
         //校验店铺资质信息
-        if(!("益善缘".equals(cloudHostProper.getCompanyName()))){
+        if(!("益善缘".equals(cloudHostProper.getCompanyName())) && !("康年堂".equals(cloudHostProper.getCompanyName()))){
             //获取店铺
             FsStoreScrm store = fsStoreScrmService.selectFsStoreByStoreId(product.getStoreId());
             if(store == null || 1 != store.getStatus()){
@@ -679,6 +679,8 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
 
     @Override
     public List<FsStoreProductListQueryVO> selectFsStoreProductListQuery(FsStoreProductQueryParam param) {
+        boolean stores = medicalMallConfig.isStores();
+        param.setIsStores(stores?1:0);
         return fsStoreProductMapper.selectFsStoreProductListQuery(param);
     }
 
@@ -708,12 +710,18 @@ public class FsStoreProductScrmServiceImpl implements IFsStoreProductScrmService
 
     @Override
     public List<FsStoreProductListQueryVO> selectFsStoreProductNewQuery(int count) {
-        return fsStoreProductMapper.selectFsStoreProductNewQuery(count,medicalMallConfig);
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("count", count);
+        map.put("config", medicalMallConfig);
+        return fsStoreProductMapper.selectFsStoreProductNewQuery(map);
     }
 
     @Override
     public List<FsStoreProductListQueryVO> selectFsStoreProductHotQuery(int count) {
-        return fsStoreProductMapper.selectFsStoreProductHotQuery(count,medicalMallConfig);
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("count", count);
+        map.put("config", medicalMallConfig);
+        return fsStoreProductMapper.selectFsStoreProductHotQuery(map);
     }
 
     @Override

+ 5 - 0
fs-service/src/main/java/com/fs/statis/domain/FsStatisSalerWatch.java

@@ -24,6 +24,11 @@ public class FsStatisSalerWatch {
      */
     private Long id;
 
+    private Long companyId;
+
+    @Excel(name = "所属公司")
+    private String companyName;
+
     /**
      * 部门
      */

+ 1 - 0
fs-service/src/main/resources/application-config-bly.yml

@@ -133,6 +133,7 @@ ipad:
   ipadUrl:
   aiApi:
   voiceApi:
+  commonApi:
 wx_miniapp_temp:
   pay_order_temp_id: VXEvKaGNPFuJmhWK9O_QPrTZxe9umDCukq-maI8Vdek
   inquiry_temp_id: 9POPYeqhI48LOPvq-Rfoklze7H-9SlunJKh10Qt4_2I

+ 1 - 0
fs-service/src/main/resources/application-config-dev.yml

@@ -106,6 +106,7 @@ ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   aiApi: http://152.136.202.157:3000/api
   voiceApi:
+  commonApi:
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:

+ 5 - 5
fs-service/src/main/resources/application-config-druid-knt.yml

@@ -23,13 +23,13 @@ wx:
         token: PPKOdAlCoMO
         aesKey: PKvaxtpSv8NGpfTDm7VUHIK8Wok2ESyYX24qpXJAdMP
   pay:
-    appId: wx7cf96953a4be5181 #微信公众号或者小程序等的appid
-    mchId: 1611402045 #微信支付商户号
+    appId: wx1de020b57c05a990 #微信公众号或者小程序等的appid
+    mchId: 1723480901 #微信支付商户号:陕西康年堂医药连锁有限公司
     mchKey: 8cab128997a3547c1363b0898b877f38 #微信支付商户密钥
     subAppId:  #服务商模式下的子商户公众账号ID
     subMchId:  #服务商模式下的子商户号
     keyPath: c:\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
-    notifyUrl: https://userapp.his.runtzh.com/app/wxpay/wxPayNotify
+    notifyUrl: https://userapp.kangniantangyiyao.top/app/wxpay/wxPayNotify
   mp:
     useRedis: false
     redisConfig:
@@ -58,8 +58,8 @@ watch:
   password3: v9xsKuqn_$d2y
 
 fs :
-  commonApi: http://192.168.0.18:7771
-  h5CommonApi: http://192.168.0.18:7771
+  commonApi: http://192.168.0.196:7771
+  h5CommonApi: http://192.168.0.196:7771
 nuonuo:
   key: 10924508
   secret: A2EB20764D304D16

+ 153 - 0
fs-service/src/main/resources/application-druid-bnkc-test.yml

@@ -0,0 +1,153 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-bnkc,common
+    # redis 配置
+    redis:
+        host: 127.0.0.1
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 10s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 100
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+#        clickhouse:
+#            type: com.alibaba.druid.pool.DruidDataSource
+#            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+#            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+#            username: rt_2024
+#            password: Yzx_19860213
+#            initialSize: 10
+#            maxActive: 100
+#            minIdle: 10
+#            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                  url: jdbc:mysql://nj-cdb-n80v6uox.sql.tencentcdb.com:22935/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  username: root
+                  password: Ylrz_1q2w3e4r5t6y
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://nj-cdb-n80v6uox.sql.tencentcdb.com:22935/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_1q2w3e4r5t6y
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: rmq-16xj8o92zp.rocketmq.cd.qcloud.tencenttdmq.com:8080
+    producer:
+        group: my-producer-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+    consumer:
+        group: common-group
+        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
+        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+openIM:
+    secret: openIM123
+    userID: imAdmin
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true

+ 162 - 0
fs-service/src/main/resources/application-druid-knt-test.yml

@@ -0,0 +1,162 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-knt,common
+    # redis 配置
+    redis:
+        # 地址
+        host: 127.0.0.1
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 3
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 20s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 8
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        #        clickhouse:
+        #            type: com.alibaba.druid.pool.DruidDataSource
+        #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+        #            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+        #            username: rt_2024
+        #            password: Yzx_19860213
+        #            initialSize: 10
+        #            maxActive: 100
+        #            minIdle: 10
+        #            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://120.46.174.121:2345/fs_knt_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrztek250218!3@.
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://120.46.174.121:2345/knt_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrztek250218!3@.
+                read:
+                    url: jdbc:mysql://120.46.174.121:2345/knt_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrztek250218!3@.
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: 192.168.0.176:8100 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: jnmyunl # 替换为实际的 accessKey
+        secret-key: 73a!ul~xQl@-6u1 # 替换为实际的 secretKey
+        tls-enable: false
+    consumer:
+        topic: course-finish-notes
+        group: course-finish-group
+        access-key: jnmyunl # 替换为实际的 accessKey
+        secret-key: 73a!ul~xQl@-6u1 # 替换为实际的 secretKey
+        tls-enable: false
+openIM:
+    secret: openIM123
+    userID: imAdmin
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true

+ 155 - 0
fs-service/src/main/resources/application-druid-nmgyt-test.yml

@@ -0,0 +1,155 @@
+# 数据源配置
+spring:
+    profiles:
+        include: config-druid-nmgyt,common
+    # redis 配置
+    redis:
+        # 地址
+        host: 127.0.0.1
+        # 端口,默认为6379
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password:
+        # 连接超时时间
+        timeout: 20s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 8
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        #        clickhouse:
+        #            type: com.alibaba.druid.pool.DruidDataSource
+        #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+        #            url: jdbc:clickhouse://cc-2vc8zzo26w0l7m2l6.public.clickhouse.ads.aliyuncs.com/sop?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+        #            username: rt_2024
+        #            password: Yzx_19860213
+        #            initialSize: 10
+        #            maxActive: 100
+        #            minIdle: 10
+        #            maxWait: 6000
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://bj-cdb-b5ouwsa2.sql.tencentcdb.com:23018/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+        sop:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://bj-cdb-b5ouwsa2.sql.tencentcdb.com:23018/sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Ylrz_c123232014^$
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 20
+                # 配置获取连接等待超时的时间
+                maxWait: 60000
+                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+                timeBetweenEvictionRunsMillis: 60000
+                # 配置一个连接在池中最小生存的时间,单位是毫秒
+                minEvictableIdleTimeMillis: 300000
+                # 配置一个连接在池中最大生存的时间,单位是毫秒
+                maxEvictableIdleTimeMillis: 900000
+                # 配置检测连接是否有效
+                validationQuery: SELECT 1 FROM DUAL
+                testWhileIdle: true
+                testOnBorrow: false
+                testOnReturn: false
+                webStatFilter:
+                    enabled: true
+                statViewServlet:
+                    enabled: true
+                    # 设置白名单,不填则允许所有访问
+                    allow:
+                    url-pattern: /druid/*
+                    # 控制台管理用户名和密码
+                    login-username: fs
+                    login-password: 123456
+                filter:
+                    stat:
+                        enabled: true
+                        # 慢SQL记录
+                        log-slow-sql: true
+                        slow-sql-millis: 1000
+                        merge-sql: true
+                    wall:
+                        config:
+                            multi-statement-allow: true
+rocketmq:
+    name-server: rmq-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+    consumer:
+        group: test-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+openIM:
+    secret: openIM123
+    userID: imAdmin
+#是否为新商户,新商户不走mpOpenId
+isNewWxMerchant: true

+ 10 - 6
fs-service/src/main/resources/mapper/course/FsUserCourseCategoryMapper.xml

@@ -3,7 +3,7 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.course.mapper.FsUserCourseCategoryMapper">
-    
+
     <resultMap type="FsUserCourseCategory" id="FsUserCourseCategoryResult">
         <result property="cateId"    column="cate_id"    />
         <result property="pid"    column="pid"    />
@@ -13,6 +13,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime"    column="create_time"    />
         <result property="updateTime"    column="update_time"    />
         <result property="isDel"    column="is_del"    />
+        <result property="userId"    column="user_id"    />
     </resultMap>
 
     <sql id="selectFsUserCourseCategoryVo">
@@ -21,20 +22,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectFsUserCourseCategoryList" parameterType="FsUserCourseCategory" resultMap="FsUserCourseCategoryResult">
         <include refid="selectFsUserCourseCategoryVo"/>
-        <where>  
+        <where>
             <if test="pid != null "> and pid = #{pid}</if>
             <if test="cateName != null  and cateName != ''"> and cate_name like concat('%', #{cateName}, '%')</if>
             <if test="sort != null "> and sort = #{sort}</if>
             <if test="isShow != null "> and is_show = #{isShow}</if>
             <if test="isDel != null  and isDel != ''"> and is_del = #{isDel}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
         </where>
     </select>
-    
+
     <select id="selectFsUserCourseCategoryByCateId" parameterType="Long" resultMap="FsUserCourseCategoryResult">
         <include refid="selectFsUserCourseCategoryVo"/>
         where cate_id = #{cateId}
     </select>
-        
+
     <insert id="insertFsUserCourseCategory" parameterType="FsUserCourseCategory" useGeneratedKeys="true" keyProperty="cateId">
         insert into fs_user_course_category
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -45,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
             <if test="isDel != null">is_del,</if>
+            <if test="userId != null">user_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="pid != null">#{pid},</if>
@@ -54,6 +57,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createTime != null">#{createTime},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="isDel != null">#{isDel},</if>
+            <if test="userId != null">#{userId},</if>
          </trim>
     </insert>
 
@@ -76,9 +80,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </delete>
 
     <delete id="deleteFsUserCourseCategoryByCateIds" parameterType="String">
-        delete from fs_user_course_category where cate_id in 
+        delete from fs_user_course_category where cate_id in
         <foreach item="cateId" collection="array" open="(" separator="," close=")">
             #{cateId}
         </foreach>
     </delete>
-</mapper>
+</mapper>

+ 4 - 3
fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml

@@ -720,8 +720,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN (
         SELECT
         sp.*,
-        ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn
+        ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
         FROM fs_store_payment sp
+        WHERE sp.business_code IS NOT NULL
         ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
         LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id
         <where>
@@ -938,7 +939,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN (
         SELECT
         sp.*,
-        ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn
+        ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
         FROM fs_store_payment sp
         ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
         LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id
@@ -1389,7 +1390,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN (
         SELECT
         sp.*,
-        ROW_NUMBER() OVER (PARTITION BY sp.pay_code ORDER BY sp.create_time DESC) as rn
+        ROW_NUMBER() OVER (PARTITION BY sp.business_code ORDER BY sp.create_time DESC) as rn
         FROM fs_store_payment sp
         ) sp_latest ON sp_latest.business_code = so.order_code AND sp_latest.rn = 1
         LEFT JOIN fs_course_play_source_config csc ON csc.appid = sp_latest.app_id

+ 33 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -452,4 +452,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{productId}
         </foreach>
     </select>
+    <select id="selectFsStoreProductNewQuery" resultType="com.fs.hisStore.vo.FsStoreProductListQueryVO">
+        select p.* from fs_store_product_scrm p
+        <if test='config.isAudit == "1"'>
+            inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1
+        </if>
+        where p.is_del=0 and p.is_show=1
+        <if test='config.isAudit == "1"'>
+            and p.is_audit = '1'
+        </if>
+        and p.is_new=1 and p.is_display=1 order by p.sort desc limit #{count}
+    </select>
+    <select id="selectFsStoreProductHotQuery" resultType="com.fs.hisStore.vo.FsStoreProductListQueryVO">
+        select p.* from fs_store_product_scrm p
+        <if test='config.isAudit == "1" '>
+        inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1
+        </if>
+        where p.is_del=0 and p.is_show=1
+        <if test='config.isAudit == "1" '>
+        and p.is_audit = '1'
+        </if>
+        and  p.is_hot=1 and p.is_display=1 order by p.sort desc limit #{count}
+    </select>
+    <select id="selectFsStoreProductGoodListQuery" resultType="com.fs.hisStore.vo.FsStoreProductListQueryVO">
+        select p.* from fs_store_product_scrm p
+        <if test='config.isAudit == "1" '>
+        inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1
+        </if>
+        where p.is_del=0 and p.is_show=1
+        <if test='config.isAudit == "1" '>
+        and p.is_audit = '1'
+        </if>
+        and  p.is_good=1 and p.is_display=1 order by p.sort desc
+    </select>
 </mapper>

+ 4 - 0
fs-service/src/main/resources/mapper/statis/FsStatisSalerWatchMapper.xml

@@ -192,6 +192,7 @@
     </select>
     <select id="queryListExport" resultType="com.fs.statis.domain.FsStatisSalerWatch">
         SELECT
+        concat(u.company_id,'_',c.company_name) as company_name,
         concat(u.user_name,'_',u.nick_name) as company_user_name,
         ANY_VALUE(concat(dept.dept_id,'_',dept.dept_name)) as dept_name,
         SUM(watch.train_camp_num) as train_camp_num,
@@ -219,6 +220,8 @@
         on dept.del_flag=0 and watch.dept_id=dept.dept_id
         LEFT JOIN company_user u
         on u.del_flag=0 and watch.company_user_id=u.user_id
+        LEFT JOIN company c
+        on c.company_id=u.company_id
         <where>
             <if test="userIds != null and userIds.size() > 0">
                 AND watch.company_user_id IN
@@ -245,6 +248,7 @@
             </choose>
         </where>
         GROUP BY watch.company_user_id
+        order by u.company_id
     </select>
     <select id="generateSopData" resultType="com.fs.statis.domain.FsStatisSalerWatch">
         INSERT INTO fs_statis_saler_watch (

+ 17 - 0
fs-store/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -94,7 +94,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();

+ 17 - 0
fs-user-app-ai-chat/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -101,7 +101,24 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 19 - 0
fs-user-app/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -105,6 +105,25 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

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

@@ -11,6 +11,6 @@ spring:
 #    active: druid-yzt
 #    active: druid-hdt
 #    active: druid-sxjz
-    active: druid-qdtst
+#    active: druid-qdtst
 #    active: druid-yzt
-#    active: druid-jnmy-test
+    active: druid-knt-test

+ 18 - 0
fs-watch/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -69,6 +69,24 @@ public class RedisConfig extends CachingConfigurerSupport
         return template;
     }
 
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {

+ 19 - 0
fs-wx-api/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -92,6 +92,25 @@ public class RedisConfig extends CachingConfigurerSupport
         template.afterPropertiesSet();
         return template;
     }
+
+    @Bean
+    public RedisTemplate<String, Integer> redisTemplateForInteger(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Integer> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+
+        // 使用StringRedisSerializer来序列化和反序列化redis的key值
+        template.setKeySerializer(new StringRedisSerializer());
+
+        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
+        template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        // Hash的key也采用StringRedisSerializer的序列化方式
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
+
+        template.afterPropertiesSet();
+        return template;
+    }
     @Bean
     public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();