Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master'

zx 3 settimane fa
parent
commit
7a42f9b1bb
60 ha cambiato i file con 1075 aggiunte e 311 eliminazioni
  1. 16 4
      fs-admin/src/main/java/com/fs/company/controller/CompanyStatisticsController.java
  2. 36 2
      fs-admin/src/main/java/com/fs/course/controller/FsCourseQuestionBankController.java
  3. 16 0
      fs-admin/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java
  4. 52 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java
  5. 25 1
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseTrainingCampController.java
  6. 45 2
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseVideoController.java
  7. 34 2
      fs-admin/src/main/java/com/fs/course/controller/FsVideoResourceController.java
  8. 7 1
      fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java
  9. 25 0
      fs-admin/src/main/java/com/fs/his/task/Task.java
  10. 19 0
      fs-admin/src/main/java/com/fs/his/task/trafficlog/TrafficlogTask.java
  11. 6 0
      fs-common/src/main/java/com/fs/common/utils/DateUtils.java
  12. 9 0
      fs-company/src/main/java/com/fs/company/controller/company/IndexStatisticsController.java
  13. 1 1
      fs-company/src/main/java/com/fs/company/controller/course/FsUserCourseVideoController.java
  14. 120 0
      fs-company/src/main/java/com/fs/company/controller/store/FsCouponController.java
  15. 4 0
      fs-company/src/main/java/com/fs/company/controller/store/FsUserController.java
  16. 2 0
      fs-company/src/main/java/com/fs/company/controller/store/FsUserCouponController.java
  17. 0 49
      fs-qw-api-msg/src/main/java/com/fs/app/config/QWConfigProperties.java
  18. 6 4
      fs-service/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
  19. 7 4
      fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java
  20. 16 4
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  21. 15 0
      fs-service/src/main/java/com/fs/company/vo/QwIpadTotalVo.java
  22. 5 0
      fs-service/src/main/java/com/fs/course/config/CourseConfig.java
  23. 2 0
      fs-service/src/main/java/com/fs/course/domain/FsVideoResource.java
  24. 66 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseTrafficLogMapper.java
  25. 22 0
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  26. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java
  27. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java
  28. 9 0
      fs-service/src/main/java/com/fs/course/param/TrafficRecord.java
  29. 1 1
      fs-service/src/main/java/com/fs/course/service/IFsCourseQuestionBankService.java
  30. 1 1
      fs-service/src/main/java/com/fs/course/service/IFsCourseRedPacketLogService.java
  31. 10 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseTrafficLogService.java
  32. 1 1
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseTrainingCampService.java
  33. 1 2
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  34. 2 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java
  35. 11 11
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java
  36. 166 4
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseTrafficLogServiceImpl.java
  37. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  38. 8 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  39. 2 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseTrainingCampServiceImpl.java
  40. 45 47
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  41. 94 86
      fs-service/src/main/java/com/fs/course/service/impl/FsUserWatchCourseStatisticsServiceImpl.java
  42. 15 0
      fs-service/src/main/java/com/fs/course/vo/FsUserCourseParticipationRecordVO.java
  43. 3 2
      fs-service/src/main/java/com/fs/his/mapper/FsUserCouponMapper.java
  44. 2 0
      fs-service/src/main/java/com/fs/his/param/FsUserCouponParam.java
  45. 28 21
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  46. 4 4
      fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java
  47. 4 0
      fs-service/src/main/java/com/fs/statis/dto/TrafficLogDTO.java
  48. 19 19
      fs-service/src/main/java/com/fs/task/trafficlog/TrafficlogTask.java
  49. 1 1
      fs-service/src/main/resources/application-config-druid-hzyy.yml
  50. 5 5
      fs-service/src/main/resources/application-config-druid-kyt.yml
  51. 3 20
      fs-service/src/main/resources/application-config-zkzh.yml
  52. 22 0
      fs-service/src/main/resources/mapper/company/CompanyUserMapper.xml
  53. 7 2
      fs-service/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml
  54. 1 1
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  55. 3 0
      fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml
  56. 3 1
      fs-service/src/main/resources/mapper/course/FsUserCourseTrainingCampMapper.xml
  57. 3 0
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  58. 3 0
      fs-service/src/main/resources/mapper/course/FsVideoResourceMapper.xml
  59. 19 5
      fs-user-app/src/main/java/com/fs/app/controller/CouponController.java
  60. 16 0
      fs-user-app/src/main/java/com/fs/app/controller/UserController.java

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

@@ -13,10 +13,7 @@ import com.fs.company.param.FsStoreStatisticsParam;
 import com.fs.company.service.ICompanySmsLogsService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.service.ICompanyVoiceLogsService;
-import com.fs.company.vo.CompanySmsLogsStatisticsVO;
-import com.fs.company.vo.CompanyVoiceLogsStatisticsVO;
-import com.fs.company.vo.FsStoreOrderStatisticsVO;
-import com.fs.company.vo.FsStorePaymentStatisticsVO;
+import com.fs.company.vo.*;
 import com.fs.crm.param.CrmCustomerStatisticsParam;
 import com.fs.crm.service.ICrmCustomerService;
 import com.fs.crm.service.ICrmCustomerVisitService;
@@ -27,6 +24,7 @@ import com.fs.his.service.IFsStorePaymentService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -631,4 +629,18 @@ public class CompanyStatisticsController extends BaseController
         ExcelUtil<CrmCustomerVisitStatisticsVO> util = new ExcelUtil<CrmCustomerVisitStatisticsVO>(CrmCustomerVisitStatisticsVO.class);
         return util.exportExcel(list, "visit");
     }
+
+    @GetMapping("/ipadStaticTotal/{dateTime}")
+    public R ipadStaticTotal(@PathVariable("dateTime") String dateTime){
+        List<QwIpadTotalVo> qwIpadTotalVos = userService.selectCompanyByIpadStatus(dateTime);
+        return R.ok().put("list",qwIpadTotalVos);
+    }
+
+    @GetMapping("/exportIpadStaticByTime/{dateTime}")
+    public AjaxResult exportIpadStaticByTime(@PathVariable("dateTime") String dateTime){
+        List<QwIpadTotalVo> qwIpadTotalVos = userService.selectCompanyByIpadStatus(dateTime);
+        ExcelUtil<QwIpadTotalVo> util = new ExcelUtil<QwIpadTotalVo>(QwIpadTotalVo.class);
+        return util.exportExcel(qwIpadTotalVos, "visit");
+    }
+
 }

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

@@ -1,5 +1,7 @@
 package com.fs.course.controller;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -8,10 +10,12 @@ 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.FsCourseQuestionBank;
 import com.fs.course.dto.FsCourseQuestionBankImportDTO;
 import com.fs.course.service.IFsCourseQuestionBankService;
 import com.fs.framework.web.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.*;
@@ -34,7 +38,8 @@ public class FsCourseQuestionBankController extends BaseController
 
     @Autowired
     private TokenService tokenService;
-
+    @Autowired
+    private ISysConfigService configService;
     /**
      * 查询题库列表
      */
@@ -43,6 +48,13 @@ public class FsCourseQuestionBankController extends BaseController
     public TableDataInfo list(FsCourseQuestionBank fsCourseQuestionBank)
     {
         startPage();
+        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()){
+            fsCourseQuestionBank.setUserId(userId);
+        }
         List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankList(fsCourseQuestionBank);
         return getDataTable(list);
     }
@@ -55,6 +67,14 @@ public class FsCourseQuestionBankController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsCourseQuestionBank fsCourseQuestionBank)
     {
+        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()){
+            fsCourseQuestionBank.setUserId(userId);
+        }
+
         List<FsCourseQuestionBankImportDTO> list = fsCourseQuestionBankService.exportData(fsCourseQuestionBank);
         ExcelUtil<FsCourseQuestionBankImportDTO> util = new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
         return util.exportExcel(list, "题库数据");
@@ -81,6 +101,13 @@ public class FsCourseQuestionBankController extends BaseController
     {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         fsCourseQuestionBank.setCreateBy(loginUser.getUser().getNickName());
+        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()){
+            fsCourseQuestionBank.setUserId(userId);
+        }
+
         return toAjax(fsCourseQuestionBankService.insertFsCourseQuestionBank(fsCourseQuestionBank));
     }
 
@@ -121,7 +148,14 @@ public class FsCourseQuestionBankController extends BaseController
         List<FsCourseQuestionBankImportDTO> list = util.importExcel(file.getInputStream());
 
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        String message = fsCourseQuestionBankService.importData(list, loginUser.getUser().getNickName());
+        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()){
+            String message = fsCourseQuestionBankService.importData(list, loginUser.getUser().getNickName(),userId);
+            return AjaxResult.success(message);
+        }
+        String message = fsCourseQuestionBankService.importData(list, loginUser.getUser().getNickName(),null);
         return AjaxResult.success(message);
     }
 

+ 16 - 0
fs-admin/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java

@@ -4,8 +4,10 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
 import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.param.InternetTrafficParam;
 import com.fs.course.vo.FsCourseTrafficLogListVO;
 import com.fs.qw.param.QwWatchLogStatisticsListParam;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -121,4 +123,18 @@ public class FsCourseTrafficLogController extends BaseController
     {
         return toAjax(fsCourseTrafficLogService.deleteFsCourseTrafficLogByLogIds(logIds));
     }
+
+    /**
+     * 充值流量
+     *
+     * @param internetTrafficParam
+     * @return
+     */
+    @PostMapping(value = "/rechargeTraffic")
+    public R rechargeTraffic(@RequestBody InternetTrafficParam internetTrafficParam) {
+
+        fsCourseTrafficLogService.updateTrafficStatus(internetTrafficParam);
+        return R.ok().put("data", null);  // 返回计算结果
+    }
+
 }

+ 52 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java

@@ -2,13 +2,17 @@ package com.fs.course.controller;
 
 import java.util.List;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.model.LoginUser;
 import com.fs.common.utils.ServletUtils;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.vo.FsUserCourseListPVO;
 import com.fs.framework.web.service.TokenService;
 import com.fs.his.utils.RedisCacheUtil;
 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;
@@ -44,6 +48,12 @@ public class FsUserCourseController extends BaseController
     @Autowired
     private RedisCacheUtil redisCacheUtil;
 
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysConfigService configService;
+
     /**
      * 查询课程列表
      */
@@ -52,6 +62,13 @@ public class FsUserCourseController extends BaseController
     public TableDataInfo list(FsUserCourse fsUserCourse)
     {
         startPage();
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
         return getDataTable(list);
     }
@@ -64,6 +81,13 @@ public class FsUserCourseController extends BaseController
     public TableDataInfo publicList(FsUserCourse fsUserCourse)
     {
         startPage();
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
         return getDataTable(list);
     }
@@ -76,6 +100,13 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsUserCourse fsUserCourse)
     {
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
         ExcelUtil<FsUserCourse> util = new ExcelUtil<FsUserCourse>(FsUserCourse.class);
         return util.exportExcel(list, "课程数据");
@@ -89,6 +120,13 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/publicExport")
     public AjaxResult publicExport(FsUserCourse fsUserCourse)
     {
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
         ExcelUtil<FsUserCourse> util = new ExcelUtil<FsUserCourse>(FsUserCourse.class);
         return util.exportExcel(list, "课程数据");
@@ -122,6 +160,13 @@ public class FsUserCourseController extends BaseController
     @PostMapping
     public AjaxResult add(@RequestBody FsUserCourse fsUserCourse)
     {
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
 
@@ -136,6 +181,13 @@ public class FsUserCourseController extends BaseController
     @PostMapping("/public")
     public AjaxResult publicAdd(@RequestBody FsUserCourse fsUserCourse)
     {
+        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()){
+            fsUserCourse.setUserId(userId);
+        }
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
 

+ 25 - 1
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseTrainingCampController.java

@@ -1,5 +1,7 @@
 package com.fs.course.controller;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
@@ -7,12 +9,15 @@ import com.fs.common.core.domain.model.LoginUser;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.SortUtils;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsUserCourseTrainingCamp;
 import com.fs.course.dto.FsUserCourseTrainingCampDTO;
 import com.fs.course.dto.FsUserCourseTrainingCampUpdateDTO;
 import com.fs.course.service.IFsUserCourseTrainingCampService;
 import com.fs.course.vo.FsUserCourseTrainingCampVO;
+import com.fs.framework.web.service.TokenService;
 import com.fs.his.vo.OptionsVO;
+import com.fs.system.service.ISysConfigService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import lombok.AllArgsConstructor;
@@ -31,7 +36,9 @@ import java.util.Objects;
 public class FsUserCourseTrainingCampController {
 
     private final IFsUserCourseTrainingCampService fsUserCourseTrainingCampService;
+    private final TokenService tokenService;
 
+    private final ISysConfigService configService;
     /**
      * 查询训练营列表
      */
@@ -48,6 +55,14 @@ public class FsUserCourseTrainingCampController {
         params.put("scs", SortUtils.parseSort(scs));
         params.put("userId", userId);
 
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userIds = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            params.put("userIds", userIds);
+        }
+
         PageHelper.startPage(pageNum, pageSize);
         List<FsUserCourseTrainingCampVO> list = fsUserCourseTrainingCampService.selectFsUserCourseTrainingCampVOListByMap(params);
         return AjaxResult.success(new PageInfo<>(list));
@@ -62,7 +77,16 @@ public class FsUserCourseTrainingCampController {
     @Log(title = "训练营", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@Valid @RequestBody FsUserCourseTrainingCampDTO params) {
-        fsUserCourseTrainingCampService.add(params);
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userIds = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            fsUserCourseTrainingCampService.add(params,userIds);
+            return AjaxResult.success();
+        }
+        fsUserCourseTrainingCampService.add(params,null);
         return AjaxResult.success();
     }
 

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

@@ -1,5 +1,7 @@
 package com.fs.course.controller;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -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.FsUserCourse;
 import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
@@ -19,6 +22,7 @@ import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.service.IFsUserCourseVideoService;
 import com.fs.framework.web.service.TokenService;
 import com.fs.his.vo.OptionsVO;
+import com.fs.system.service.ISysConfigService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,6 +50,11 @@ public class FsUserCourseVideoController extends BaseController
     private FsUserCourseVideoMapper fsUserCourseVideoMapper;
     @Autowired
     private IFsUserCourseService fsUserCourseService;
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysConfigService configService;
 
     /**
      * 查询课堂视频列表
@@ -54,6 +63,13 @@ public class FsUserCourseVideoController extends BaseController
     @GetMapping("/list")
     public TableDataInfo list(FsUserCourseVideo fsUserCourseVideo)
     {
+        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()){
+            fsUserCourseVideo.setUserId(userId);
+        }
         startPage();
         List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoList(fsUserCourseVideo);
         return getDataTable(list);
@@ -67,6 +83,13 @@ public class FsUserCourseVideoController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsUserCourseVideo fsUserCourseVideo)
     {
+        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()){
+            fsUserCourseVideo.setUserId(userId);
+        }
         List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoList(fsUserCourseVideo);
         ExcelUtil<FsUserCourseVideo> util = new ExcelUtil<FsUserCourseVideo>(FsUserCourseVideo.class);
         return util.exportExcel(list, "课堂视频数据");
@@ -79,7 +102,14 @@ public class FsUserCourseVideoController extends BaseController
     @GetMapping(value = "/{videoId}")
     public AjaxResult getInfo(@PathVariable("videoId") Long videoId)
     {
-        return AjaxResult.success(fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId));
+        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()){
+            return AjaxResult.success(fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId,userId));
+        }
+        return AjaxResult.success(fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId,null));
     }
 
     /**
@@ -94,7 +124,13 @@ public class FsUserCourseVideoController extends BaseController
         if (count>0){
             return AjaxResult.error("课程排序重复");
         }
-
+        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()){
+            fsUserCourseVideo.setUserId(userId);
+        }
         // 设置项目ID
         FsUserCourse fsUserCourse = fsUserCourseService.selectFsUserCourseByCourseId(fsUserCourseVideo.getCourseId());
         fsUserCourseVideo.setProjectId(fsUserCourse.getProject());
@@ -128,6 +164,13 @@ public class FsUserCourseVideoController extends BaseController
     public TableDataInfo getVideoListByCourseId(FsUserCourseVideo fsUserCourseVideo)
     {
         startPage();
+        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()){
+            fsUserCourseVideo.setUserId(userId);
+        }
         List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoListByCourseId(fsUserCourseVideo);
         return getDataTable(list);
     }

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

@@ -1,5 +1,7 @@
 package com.fs.course.controller;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.annotation.Log;
@@ -9,10 +11,12 @@ import com.fs.common.core.domain.model.LoginUser;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsVideoResource;
 import com.fs.course.service.IFsVideoResourceService;
 import com.fs.course.vo.FsVideoResourceVO;
 import com.fs.framework.web.service.TokenService;
+import com.fs.system.service.ISysConfigService;
 import com.github.pagehelper.PageHelper;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +37,12 @@ public class FsVideoResourceController extends BaseController {
 
     private final IFsVideoResourceService fsVideoResourceService;
 
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysConfigService configService;
+
     /**
      * 查询视频素材库列表
      */
@@ -50,7 +60,12 @@ public class FsVideoResourceController extends BaseController {
         params.put("fileName", fileName);
         params.put("typeId", typeId);
         params.put("typeSubId", typeSubId);
-
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+            params.put("userId", loginUser.getUser().getUserId());
+        }
         PageHelper.startPage(pageNum, pageSize);
         List<FsVideoResourceVO> list = fsVideoResourceService.selectVideoResourceListByMap(params);
         return getDataTable(list);
@@ -75,6 +90,13 @@ public class FsVideoResourceController extends BaseController {
     @PostMapping
     public AjaxResult add(@RequestBody FsVideoResource fsVideoResource)
     {
+        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()){
+            fsVideoResource.setUserId(userId);
+        }
         fsVideoResource.setCreateTime(LocalDateTime.now());
         fsVideoResourceService.save(fsVideoResource);
         return AjaxResult.success();
@@ -151,7 +173,17 @@ public class FsVideoResourceController extends BaseController {
         if (Objects.isNull(list) || list.isEmpty()) {
             return AjaxResult.error("数据不能为空");
         }
-        list.forEach(v -> v.setCreateTime(LocalDateTime.now()));
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long userId = loginUser.getUser().getUserId();
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+
+        list.forEach(v ->{
+            v.setCreateTime(LocalDateTime.now());
+            if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+                v.setUserId(userId);
+            }
+        } );
         fsVideoResourceService.saveBatch(list);
         return AjaxResult.success();
     }

+ 7 - 1
fs-admin/src/main/java/com/fs/his/controller/FsStoreOrderController.java

@@ -604,7 +604,13 @@ public class FsStoreOrderController extends BaseController
             if (param.getUserPhoneMk() != null && !param.getUserPhoneMk().isEmpty()) {
                 param.setUserPhone(encryptPhone(param.getUserPhoneMk()));
             }
-            List<FsStoreOrderListVO> list = fsStoreOrderService.selectFsStoreOrderListVO(param);
+            List<FsStoreOrderListVO> list;
+            if (StringUtils.isNotBlank(param.getErpAccount())){
+                //金牛erp查询
+                list = fsStoreOrderService.selectFsStoreOrderListVOByErpAccount(param);
+            } else {
+                list = fsStoreOrderService.selectFsStoreOrderListVO(param);
+            }
             orderIds = list.stream().map(FsStoreOrderListVO::getOrderId).collect(Collectors.toList());
         }
         if (orderIds.isEmpty()){

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

@@ -5,12 +5,15 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.service.impl.SmsServiceImpl;
+import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.company.domain.CompanyMoneyLogs;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.domain.CompanyVoiceCaller;
 import com.fs.company.mapper.*;
 import com.fs.company.service.ICompanyService;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.company.vo.QwIpadTotalVo;
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.service.IFsCourseWatchLogService;
@@ -48,6 +51,7 @@ import com.fs.qwApi.service.QwApiService;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -59,6 +63,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+@Slf4j
 @Component("task")
 public class Task {
     @Autowired
@@ -153,6 +158,26 @@ public class Task {
     @Autowired
     private IQwUserService qwUserService;
 
+    @Autowired
+    private ICompanyUserService userService;
+
+    //定时查询ipad主机使用情况,建议每天凌晨1点执行一次
+    public void totalIpadTask(){
+        String dateTime = DateUtils.addDateDays(-1); // 昨天
+        List<QwIpadTotalVo> qwIpadTotalVos = userService.selectCompanyByIpadStatusCount();
+        if(qwIpadTotalVos != null && !qwIpadTotalVos.isEmpty()){
+            qwIpadTotalVos.forEach(qwIpadTotalVo ->
+                    qwIpadTotalVo.setStatTime(dateTime)
+            );
+            int a = userService.insertQwIpadTotal(qwIpadTotalVos);
+            if(a == 0){
+                log.error("插入ipad主机失败");
+            }
+        }else{
+            log.error("查询没有数据");
+        }
+    }
+
     public void addQwUserName(){
         QwCompany qwCompany = new QwCompany();
         List<QwCompany> companyList = qwCompanyService.selectQwCompanyList(qwCompany);

+ 19 - 0
fs-admin/src/main/java/com/fs/his/task/trafficlog/TrafficlogTask.java

@@ -0,0 +1,19 @@
+package com.fs.his.task.trafficlog;
+
+import com.fs.course.service.IFsCourseTrafficLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service("trafficlogTask")
+@Slf4j
+public class TrafficlogTask {
+    @Autowired
+    private IFsCourseTrafficLogService fsCourseTrafficLogService;
+    /**
+     * 红包流量统计
+     */
+    public void sumTrafficlog(){
+        fsCourseTrafficLogService.sumTrafficlog();
+    }
+}

+ 6 - 0
fs-common/src/main/java/com/fs/common/utils/DateUtils.java

@@ -264,5 +264,11 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         return endOfDay.format(OUTPUT_FORMATTER);
     }
 
+    // 返回昨天或明天的日期字符串(格式:yyyy-MM-dd)
+    public static String addDateDays(int days) {
+        Calendar cal = Calendar.getInstance();
+        cal.add(Calendar.DATE, days);
+        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
+    }
 
 }

+ 9 - 0
fs-company/src/main/java/com/fs/company/controller/company/IndexStatisticsController.java

@@ -7,6 +7,8 @@ import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.statis.StatisticsRedisConstant;
 import com.fs.statis.dto.*;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -26,6 +28,10 @@ public class IndexStatisticsController {
 
     @Autowired
     private TokenService tokenService;
+
+
+    @Autowired
+    private ISysConfigService sysConfigService;
     /**
      * 分析概览
      */
@@ -71,6 +77,9 @@ public class IndexStatisticsController {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long companyId = loginUser.getCompany().getCompanyId();
         TrafficLogDTO trafficLogDTO = redisCache.getCacheObject(String.format("%s:%d",DATA_OVERVIEW_TRAFFIC_LOG,companyId));
+        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("redPacket.Traffic.config");
+        String configValue = sysConfig.getConfigValue();
+        trafficLogDTO.setTraffic(configValue);
         return R.ok().put("data",trafficLogDTO);
     }
 

+ 1 - 1
fs-company/src/main/java/com/fs/company/controller/course/FsUserCourseVideoController.java

@@ -69,7 +69,7 @@ public class FsUserCourseVideoController extends BaseController
     @GetMapping(value = "/{videoId}")
     public AjaxResult getInfo(@PathVariable("videoId") Long videoId)
     {
-        return AjaxResult.success(fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId));
+        return AjaxResult.success(fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId,null));
     }
 
     /**

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

@@ -0,0 +1,120 @@
+package com.fs.company.controller.store;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.his.domain.FsCoupon;
+import com.fs.his.param.FsCouponParam;
+import com.fs.his.service.IFsCouponService;
+import com.fs.his.vo.FsCouponAllListVO;
+import com.fs.his.vo.FsCouponListVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 优惠券Controller
+ *
+ * @author fs
+ * @date 2023-09-04
+ */
+@RestController
+@RequestMapping("/store/coupon")
+public class FsCouponController extends BaseController
+{
+    @Autowired
+    private IFsCouponService fsCouponService;
+
+    /**
+     * 查询优惠券列表订单查询
+     */
+    @PreAuthorize("@ss.hasPermi('store:coupon:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsCouponParam fsCoupon)
+    {
+        startPage();
+        List<FsCouponListVO> list = fsCouponService.selectFsCouponListVO(fsCoupon);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询优惠券列表订单查询
+     */
+    @GetMapping("/allList")
+    public AjaxResult allList()
+    {
+        List<FsCouponAllListVO> list = fsCouponService.selectFsCouponListAll();
+        return AjaxResult.success(list);
+    }
+
+
+
+    /**
+     * 导出优惠券列表
+     */
+    @PreAuthorize("@ss.hasPermi('store:coupon:export')")
+    @Log(title = "优惠券", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsCoupon fsCoupon)
+    {
+        List<FsCoupon> list = fsCouponService.selectFsCouponList(fsCoupon);
+        ExcelUtil<FsCoupon> util = new ExcelUtil<FsCoupon>(FsCoupon.class);
+        return util.exportExcel(list, "优惠券数据");
+    }
+
+    /**
+     * 获取优惠券详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('store:coupon:query')")
+    @GetMapping(value = "/{couponId}")
+    public AjaxResult getInfo(@PathVariable("couponId") Long couponId)
+    {
+        return AjaxResult.success(fsCouponService.selectFsCouponByCouponId(couponId));
+    }
+
+//    /**
+//     * 新增优惠券
+//     */
+//    @PreAuthorize("@ss.hasPermi('store:coupon:add')")
+//    @Log(title = "优惠券", businessType = BusinessType.INSERT)
+//    @PostMapping
+//    public AjaxResult add(@RequestBody FsCoupon fsCoupon)
+//    {
+//        return toAjax(fsCouponService.insertFsCoupon(fsCoupon));
+//    }
+//
+//    /**
+//     * 修改优惠券
+//     */
+//    @PreAuthorize("@ss.hasPermi('store:coupon:edit')")
+//    @Log(title = "优惠券", businessType = BusinessType.UPDATE)
+//    @PutMapping
+//    public AjaxResult edit(@RequestBody FsCoupon fsCoupon)
+//    {
+//        FsCoupon c = fsCouponService.selectFsCouponByCouponId(fsCoupon.getCouponId());
+//        long l = c.getRemainNumber() + fsCoupon.getNumber() - c.getNumber();
+//        if (l<0){
+//            throw new CustomException("剩余卷不足");
+//        }
+//        fsCoupon.setRemainNumber(l);
+//        return toAjax(fsCouponService.updateFsCoupon(fsCoupon));
+//    }
+//
+//    /**
+//     * 删除优惠券
+//     */
+//    @PreAuthorize("@ss.hasPermi('store:coupon:remove')")
+//    @Log(title = "优惠券", businessType = BusinessType.DELETE)
+//	@DeleteMapping("/{couponIds}")
+//    public AjaxResult remove(@PathVariable Long[] couponIds)
+//    {
+//        return toAjax(fsCouponService.deleteFsCouponByCouponIds(couponIds));
+//    }
+}

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

@@ -233,6 +233,10 @@ public class FsUserController extends BaseController
     public TableDataInfo userlist(@PathVariable("name")String name)
     {
         List<UserVo> list = fsUserService.selectUserVOList(name);
+        if (list==null|| list.isEmpty()){
+            String s = encryptPhone(name);
+            list = fsUserService.selectUserVOList(s);
+        }
         return getDataTable(list);
     }
 

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

@@ -40,6 +40,8 @@ public class FsUserCouponController extends BaseController
     @GetMapping("/list")
     public TableDataInfo list(FsUserCouponParam fsUserCoupon)
     {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        fsUserCoupon.setCompanyId(loginUser.getCompany().getCompanyId());
         startPage();
         List<FsUserCouponListVO> list = fsUserCouponService.selectFsUserCouponListVO(fsUserCoupon);
         return getDataTable(list);

+ 0 - 49
fs-qw-api-msg/src/main/java/com/fs/app/config/QWConfigProperties.java

@@ -1,49 +0,0 @@
-package com.fs.app.config;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-@Component
-public class QWConfigProperties {
-
-    @Value("${custom.token}")
-    private String token;
-
-    @Value("${custom.encoding-aes-key}")
-    private String encodingAesKey;
-
-    @Value("${custom.corp-id}")
-    private String corpId;
-    @Value("${custom.secret}")
-    private String secret;
-
-    @Value("${custom.private-key-path}")
-    private String privateKeyPath;
-
-    @Value("${custom.webhook-url}")
-    private String webhookUrl;
-
-    public String getToken() {
-        return token;
-    }
-
-    public String getEncodingAesKey() {
-        return encodingAesKey;
-    }
-
-    public String getCorpId() {
-        return corpId;
-    }
-
-    public String getSecret() {
-        return secret;
-    }
-
-    public String getPrivateKeyPath() {
-        return privateKeyPath;
-    }
-
-    public String getWebhookUrl() {
-        return webhookUrl;
-    }
-}

+ 6 - 4
fs-service/src/main/java/com/fs/company/mapper/CompanyUserMapper.java

@@ -5,10 +5,7 @@ import com.fs.common.enums.DataSourceType;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserQwParam;
-import com.fs.company.vo.CompanyQwUserByIdsVo;
-import com.fs.company.vo.CompanyUserQwListVO;
-import com.fs.company.vo.CompanyUserVO;
-import com.fs.company.vo.DocCompanyUserVO;
+import com.fs.company.vo.*;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwOptionsVO;
@@ -308,4 +305,9 @@ public interface CompanyUserMapper
 
     int updateAllowedAllRegister(@Param("status") boolean status, @Param("userIds")List<Long> userIds);
 
+    List<QwIpadTotalVo> selectCompanyByIpadStatus(@Param("dateTime") String dateTime);
+
+    List<QwIpadTotalVo> selectCompanyByIpadStatusCount();
+
+    int insertQwIpadTotal(List<QwIpadTotalVo> qwIpadTotalVos);
 }

+ 7 - 4
fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -4,10 +4,7 @@ import com.fs.common.core.domain.R;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserQwParam;
-import com.fs.company.vo.CompanyQwUserByIdsVo;
-import com.fs.company.vo.CompanyUserQwListVO;
-import com.fs.company.vo.CompanyUserVO;
-import com.fs.company.vo.DocCompanyUserVO;
+import com.fs.company.vo.*;
 import com.fs.his.vo.CitysAreaVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.dto.UserProjectDTO;
@@ -220,4 +217,10 @@ public interface ICompanyUserService {
      */
     Boolean isAllowedAllRegister(boolean status,  List<Long> userIds);
 
+    List<QwIpadTotalVo> selectCompanyByIpadStatus(String dateTime);
+
+    List<QwIpadTotalVo> selectCompanyByIpadStatusCount();
+
+    int insertQwIpadTotal(List<QwIpadTotalVo> qwIpadTotalVos);
+
 }

+ 16 - 4
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -13,10 +13,7 @@ import com.fs.company.mapper.*;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserQwParam;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.company.vo.CompanyQwUserByIdsVo;
-import com.fs.company.vo.CompanyUserQwListVO;
-import com.fs.company.vo.CompanyUserVO;
-import com.fs.company.vo.DocCompanyUserVO;
+import com.fs.company.vo.*;
 import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.service.IFsCityService;
@@ -624,4 +621,19 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return true;
     }
 
+    @Override
+    public List<QwIpadTotalVo> selectCompanyByIpadStatus(String dateTime) {
+        return companyUserMapper.selectCompanyByIpadStatus(dateTime);
+    }
+
+    @Override
+    public List<QwIpadTotalVo> selectCompanyByIpadStatusCount() {
+        return companyUserMapper.selectCompanyByIpadStatusCount();
+    }
+
+    @Override
+    public int insertQwIpadTotal(List<QwIpadTotalVo> qwIpadTotalVos) {
+        return companyUserMapper.insertQwIpadTotal(qwIpadTotalVos);
+    }
+
 }

+ 15 - 0
fs-service/src/main/java/com/fs/company/vo/QwIpadTotalVo.java

@@ -0,0 +1,15 @@
+package com.fs.company.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+@Data
+public class QwIpadTotalVo {
+    private Long id;
+    private Long companyId;
+    @Excel(name = "公司名称")
+    private String companyName;
+    @Excel(name = "绑定数")
+    private Long bindCount;
+    private String statTime;
+}

+ 5 - 0
fs-service/src/main/java/com/fs/course/config/CourseConfig.java

@@ -52,6 +52,11 @@ public class CourseConfig implements Serializable {
      */
     private String userCourseAuthDomain;
 
+    /**
+     * 是否绑定
+     */
+    private Boolean isBound;
+
 
     @Data
     public static class DisabledTimeVo{

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

@@ -97,4 +97,6 @@ public class FsVideoResource {
     private String transcodeFileKey;//转码的文件key
 
     private Integer sort;
+
+    private Long userId;
 }

+ 66 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseTrafficLogMapper.java

@@ -1,14 +1,17 @@
 package com.fs.course.mapper;
 
+import java.util.Date;
 import java.util.List;
 
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
 import com.fs.course.domain.FsCourseTrafficLog;
 import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.param.TrafficRecord;
 import com.fs.course.vo.FsCourseTrafficLogListVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
 import org.springframework.stereotype.Repository;
 
 /**
@@ -110,4 +113,67 @@ public interface FsCourseTrafficLogMapper
     void insertCourseTrafficLogByTwoDaysLaterBatch(@Param("list") List<FsCourseTrafficLog> redPacketLogs);
 
     List<FsCourseTrafficLogListVO> selectTrafficNew(FsCourseTrafficLogParam param);
+
+    @Select("<script>" +
+            "SELECT COALESCE(sum(internet_traffic), 0) FROM fs_course_traffic_log " +
+            "WHERE status =0" +
+            "<if test='createTime != null'>AND create_time &lt;= #{createTime}</if> " +
+            "</script>")
+    Long findRecordsNumBYD( @Param("createTime") Date createTime);
+
+    @Select("<script>" +
+            "SELECT log_id FROM fs_course_traffic_log " +
+            "WHERE status =0" +
+            "<if test='createTime != null'>AND create_time &lt;= #{createTime}</if> " +
+            "</script>")
+    List<Long> findRecordsNumByIds( @Param("createTime") Date createTime);
+    @Update("<script>" +
+            "UPDATE fs_course_traffic_log SET status = #{status} WHERE log_id IN " +
+            "<foreach item='id' collection='ids' open='(' separator=',' close=')'>" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    int updateStatusByIds(@Param("ids") List<Long> ids,@Param("status")Integer status);
+
+
+
+    // 按创建时间查询未使用的流量记录(用于分批更新)
+    @Select("<script>" +
+            "SELECT COALESCE(sum(internet_traffic), 0) FROM fs_course_traffic_log " +
+            "WHERE status = 0" +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if> " +
+            "</script>")
+    Long findRecordsNum(@Param("companyId") Long companyId);
+
+    // 批量更新状态
+    @Update("<script>" +
+            "UPDATE fs_course_traffic_log SET status = 1 WHERE log_id IN " +
+            "<foreach item='id' collection='ids' open='(' separator=',' close=')'>" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    int updateStatusByIds(@Param("ids") List<Long> ids);
+
+    @Select("<script>" +
+            "SELECT internet_traffic FROM fs_course_traffic_log WHERE log_id IN " +
+            "<foreach item='id' collection='ids' open='(' separator=',' close=')'>" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    List<Long> getTrafficByIds(@Param("ids") List<Long> ids);
+
+    // 新增带流量字段的记录查询(按公司ID)
+    @Select("<script>" +
+            "SELECT log_id, internet_traffic FROM fs_course_traffic_log " +
+            "WHERE status = 0" +
+            "<if test='companyId != null'>AND company_id = #{companyId}</if> " +
+            "ORDER BY create_time ASC " +
+            "LIMIT #{offset}, #{pageSize}" +
+            "</script>")
+    List<TrafficRecord> findUnusedRecordsWithTraffic(
+            @Param("companyId") Long companyId,
+            @Param("offset") int offset,
+            @Param("pageSize") int pageSize);
+
+
 }

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

@@ -465,4 +465,26 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     FsCourseWatchLog getWatchCourseVideoIsOpen(@Param("userId") Long userId,@Param("videoId") Long videoId);
 
     void batchUpdateWatchLogIsOpen(@Param("list") List<FsCourseWatchLog> batchList);
+
+    @Select("select count(*) from fs_course_watch_log where user_id =#{userId} and project =#{projectId} ")
+    Long selectByWatchLjDay(@Param("userId") Long userId,@Param("projectId")  Long projectId);
+    @Select("SELECT IFNULL(MAX(streak), 0) AS current_consecutive_days\n" +
+            "FROM (\n" +
+            "    SELECT \n" +
+            "        watch_date,\n" +
+            "        @streak := IF(\n" +
+            "            DATEDIFF(@prev_date, watch_date) = 1, \n" +
+            "            @streak + 1, \n" +
+            "            1\n" +
+            "        ) AS streak,\n" +
+            "        @prev_date := watch_date\n" +
+            "    FROM (\n" +
+            "        SELECT DISTINCT DATE(create_time) AS watch_date\n" +
+            "        FROM fs_course_watch_log\n" +
+            "        WHERE user_id = #{userId} AND project = #{projectId}\n" +
+            "        ORDER BY watch_date DESC\n" +
+            "    ) AS dates,\n" +
+            "    (SELECT @streak := 0, @prev_date := NULL) AS vars\n" +
+            ") AS streak_data;")
+    Long selectByWatchlxDay(@Param("userId") Long userId,@Param("projectId")  Long projectId);
 }

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

@@ -140,6 +140,9 @@ public interface FsUserCourseMapper
             "<if test = ' maps.subCateId !=null '> " +
             "and c.sub_cate_id =#{maps.subCateId}" +
             "</if>" +
+            "<if test = ' maps.userId !=null '> " +
+            "and c.user_id =#{maps.userId}" +
+            "</if>" +
             "<if test = ' maps.courseName!=null and maps.courseName != \"\" '> " +
             "and c.course_name like concat('%', #{maps.courseName}, '%') " +
             "</if>" +

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

@@ -85,6 +85,9 @@ public interface FsUserCourseVideoMapper
             "<if test = ' maps.title!=null and maps.title != \"\" '> " +
             "and v.title = #{maps.title} " +
             "</if>" +
+            "<if test = ' maps.userId!=null and maps.userId != \"\" '> " +
+            "and v.user_id = #{maps.userId} " +
+            "</if>" +
             " order by v.course_sort  "+
             "</script>"})
     List<FsUserCourseVideo> selectFsUserCourseVideoListByCourseId(@Param("maps") FsUserCourseVideo fsUserCourseVideo);

+ 9 - 0
fs-service/src/main/java/com/fs/course/param/TrafficRecord.java

@@ -0,0 +1,9 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class TrafficRecord {
+    private Long logId;
+    private Long internetTraffic; // 单位:KB
+}

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

@@ -73,7 +73,7 @@ public interface IFsCourseQuestionBankService
      * @param nickName 昵称
      * @return String
      */
-    String importData(List<FsCourseQuestionBankImportDTO> list, String nickName);
+    String importData(List<FsCourseQuestionBankImportDTO> list, String nickName,Long userId);
 
     /**
      * 根据ID查询题目

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

@@ -64,7 +64,7 @@ public interface IFsCourseRedPacketLogService
      */
     public int deleteFsCourseRedPacketLogByLogId(Long logId);
 
-    R syncRedPacket(String outBatchNo);
+//    R syncRedPacket(String outBatchNo);
 
     R syncRedPacket(String outBatchNo, String batchId);
 

+ 10 - 0
fs-service/src/main/java/com/fs/course/service/IFsCourseTrafficLogService.java

@@ -3,6 +3,7 @@ package com.fs.course.service;
 import java.util.List;
 import com.fs.course.domain.FsCourseTrafficLog;
 import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.param.InternetTrafficParam;
 import com.fs.course.vo.FsCourseTrafficLogListVO;
 
 /**
@@ -70,4 +71,13 @@ public interface IFsCourseTrafficLogService
     void saveCourseTrafficLog();
 
     List<FsCourseTrafficLogListVO> selectTrafficNew(FsCourseTrafficLogParam param);
+
+
+    void updateTrafficStatus(InternetTrafficParam internetTrafficParam);
+
+
+    /**
+     * 定时统计流量总数
+     */
+    void sumTrafficlog();
 }

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

@@ -30,7 +30,7 @@ public interface IFsUserCourseTrainingCampService extends IService<FsUserCourseT
      * 新增训练营
      * @param params    参数
      */
-    void add(FsUserCourseTrainingCampDTO params);
+    void add(FsUserCourseTrainingCampDTO params,Long userId);
     /**
      * 删除训练营
      * @param ids   ids

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

@@ -186,8 +186,7 @@ public interface IFsUserCourseVideoService
 
     R checkUserInfo(Long userId);
 
-    FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId);
-
+    public FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId,Long userId);
     R updateWatchDurationIsOpen(FsUserCourseVideoFinishUParam param);
 
     R isAddKfIsOpen(FsUserCourseVideoAddKfUParam param);

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

@@ -467,7 +467,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
      * @return String
      */
     @Override
-    public String importData(List<FsCourseQuestionBankImportDTO> list, String nickName) {
+    public String importData(List<FsCourseQuestionBankImportDTO> list, String nickName,Long userId) {
         if (Objects.isNull(list) || list.isEmpty()) {
             throw new ServiceException("导入数据不能为空");
         }
@@ -487,6 +487,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
 
                 // 构建题目对象
                 FsCourseQuestionBank questionBank = buildQuestionBank(importDTO, categoryData, nickName);
+                questionBank.setUserId(userId);
                 importData.add(questionBank);
                 result.addSuccess(importDTO.getTitle());
 

+ 11 - 11
fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java

@@ -122,17 +122,17 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
         return fsCourseRedPacketLogMapper.deleteFsCourseRedPacketLogByLogId(logId);
     }
 
-    @Override
-    public R syncRedPacket(String outBatchNo) {
-        FsCourseRedPacketLog log = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByBatchNo(outBatchNo);
-        if (log!=null){
-            log.setStatus(1);
-            log.setUpdateTime(new Date());
-            fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(log);
-            return R.ok();
-        }
-        return R.error("批次不存在");
-    }
+//    @Override
+//    public R syncRedPacket(String outBatchNo) {
+//        FsCourseRedPacketLog log = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByBatchNo(outBatchNo);
+//        if (log!=null){
+//            log.setStatus(1);
+//            log.setUpdateTime(new Date());
+//            fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(log);
+//            return R.ok();
+//        }
+//        return R.error("批次不存在");
+//    }
 
     @Override
     public R syncRedPacket(String outBatchNo, String batchId) {

+ 166 - 4
fs-service/src/main/java/com/fs/course/service/impl/FsCourseTrafficLogServiceImpl.java

@@ -1,18 +1,21 @@
 package com.fs.course.service.impl;
 
 import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DictUtils;
 import com.fs.company.cache.ICompanyCacheService;
 import com.fs.course.param.FsCourseTrafficLogParam;
+import com.fs.course.param.InternetTrafficParam;
+import com.fs.course.param.TrafficRecord;
 import com.fs.course.vo.FsCourseTrafficLogListVO;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
 import com.hc.openapi.tool.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,7 +36,8 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
 {
     @Autowired
     private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
-
+    @Autowired
+    private ISysConfigService iSysConfigService;
     @Autowired
     private ICompanyCacheService companyCacheService;
 
@@ -202,6 +206,164 @@ public class FsCourseTrafficLogServiceImpl implements IFsCourseTrafficLogService
         return fsCourseTrafficLogListVOS;
     }
 
+    @Override
+    public void updateTrafficStatus(InternetTrafficParam internetTrafficParam) {
+        System.out.println("开始处理流量充值...");
+
+        // 计算充值对应的流量
+        double account = Double.parseDouble(internetTrafficParam.getAccount());
+
+        SysConfig config = iSysConfigService.selectConfigByConfigKey("statis.config");
+        JSONObject jsonObject = JSONObject.parseObject(config.getConfigValue());
+        float trafficPrice = jsonObject.getFloatValue("trafficPrice");
+
+        double trafficGB = account / trafficPrice;
+        long trafficKB = (long) (trafficGB * 1024 * 1024);
+
+        System.out.println("充值金额:" + account + " 元,对应可用流量:" + trafficKB + " KB");
+
+        long updatedTrafficKB = 0L;
+        int pageSize = 1000;  // 每次查询1000条
+        int pageNum = 0;      // 分页页码
+        int loopCount = 0;    // 查询次数
+        int maxLoop = 20;     // 最大循环次数
+
+        List<Long> idsToUpdate = new ArrayList<>();       // 用于更新状态为1的ID
+        Set<Long> processedIds = new HashSet<>();         // 用于去重
+        long remainingTrafficKB = trafficKB;              // 还需补充的流量
+        long totalInternetTrafficRemaining = 0L;          // 记录未处理的流量总和
+
+        // 第一阶段:处理需要用于充值的记录
+        while (updatedTrafficKB < trafficKB && loopCount < maxLoop) {
+            loopCount++;
+            int offset = pageNum * pageSize;
+
+            // 查询当前分页的数据
+            List<TrafficRecord> trafficRecords =
+                    fsCourseTrafficLogMapper.findUnusedRecordsWithTraffic(
+                            internetTrafficParam.getCompanyId(), offset, pageSize);
+
+            if (trafficRecords.isEmpty()) {
+                break;
+            }
+
+            // 处理当前批次的数据
+            for (TrafficRecord record : trafficRecords) {
+                Long logId = record.getLogId();
+
+                if (processedIds.contains(logId)) {
+                    continue;
+                }
+
+                if (updatedTrafficKB < trafficKB) {
+                    updatedTrafficKB += record.getInternetTraffic();
+                    idsToUpdate.add(logId);
+                    remainingTrafficKB = Math.max(0, trafficKB - updatedTrafficKB);
+                }
+
+                processedIds.add(logId);
+                totalInternetTrafficRemaining += record.getInternetTraffic();
+            }
+
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
+            }
+
+            pageNum++;
+        }
+
+        // 第二阶段:将所有未处理的记录状态改为3
+        List<Long> allUnprocessedIds = new ArrayList<>();
+        pageNum = 0;  // 重置分页
+        boolean hasMore = true;
+
+        while (hasMore && loopCount < maxLoop * 2) {  // 扩大循环次数限制
+            loopCount++;
+            int offset = pageNum * pageSize;
+
+            List<TrafficRecord> allRecords =
+                    fsCourseTrafficLogMapper.findUnusedRecordsWithTraffic(
+                            internetTrafficParam.getCompanyId(), offset, pageSize);
+
+            if (allRecords.isEmpty()) {
+                hasMore = false;
+                continue;
+            }
+
+            for (TrafficRecord record : allRecords) {
+                Long logId = record.getLogId();
+                if (!idsToUpdate.contains(logId)) {  // 不是已处理的记录
+                    allUnprocessedIds.add(logId);
+                }
+            }
+
+            pageNum++;
+        }
+
+        // 更新数据库状态
+        if (!idsToUpdate.isEmpty()) {
+            fsCourseTrafficLogMapper.updateStatusByIds(idsToUpdate, 1);
+            System.out.println("共更新状态为1的记录数:" + idsToUpdate.size());
+        }
+
+        if (!allUnprocessedIds.isEmpty()) {
+            fsCourseTrafficLogMapper.updateStatusByIds(allUnprocessedIds, 3);
+            System.out.println("共更新状态为3的记录数:" + allUnprocessedIds.size());
+        }
+
+        // 剩余的计算和输出逻辑保持不变...
+        Long count = fsCourseTrafficLogMapper.findRecordsNum(internetTrafficParam.getCompanyId());
+        long overflowTrafficKB = Math.max(0, updatedTrafficKB - trafficKB) + count;
+        if (overflowTrafficKB > 0) {
+            System.out.println("已使用流量超过充值流量,超出部分:" + overflowTrafficKB + " KB");
+        }
+
+        System.out.println("充值总流量:" + trafficKB + " KB");
+        System.out.println("已使用流量:" + updatedTrafficKB + " KB");
+        long finalRemainingTrafficKB = Math.max(0, trafficKB - updatedTrafficKB);
+        System.out.println("最终剩余流量:" + finalRemainingTrafficKB + " KB");
+
+        // 系统配置更新逻辑保持不变...
+        SysConfig sysConfig = iSysConfigService.selectConfigByConfigKey("redPacket.Traffic.config");
+        String trafficCount = finalRemainingTrafficKB == 0 ?
+                "-" + overflowTrafficKB : String.valueOf(finalRemainingTrafficKB);
+
+        if (ObjectUtils.isEmpty(sysConfig)) {
+            sysConfig = new SysConfig();
+            sysConfig.setConfigKey("redPacket.Traffic.config");
+            sysConfig.setConfigName("红包流量配置");
+            sysConfig.setConfigValue(trafficCount);
+            iSysConfigService.insertConfig(sysConfig);
+        } else {
+            sysConfig.setConfigValue(trafficCount);
+            iSysConfigService.updateConfig(sysConfig);
+        }
+    }
+    @Override
+    public void sumTrafficlog() {
+        SysConfig sysConfig = iSysConfigService.selectConfigByConfigKey("redPacket.Traffic.config");
+        Date date = new Date();
+        Long count = fsCourseTrafficLogMapper.findRecordsNumBYD(date);
+        List<Long> ids = fsCourseTrafficLogMapper.findRecordsNumByIds(date);
+        if (count<=0){
+            return;
+        }
+        if (ObjectUtils.isEmpty(sysConfig)){
+            sysConfig = new SysConfig();
+            sysConfig.setConfigKey("redPacket.Traffic.config");
+            sysConfig.setConfigName("红包流量配置");
+            sysConfig.setConfigValue("-"+count);
+            iSysConfigService.insertConfig(sysConfig);
+        }else {
+            sysConfig.setConfigValue(String.valueOf((Long.parseLong(sysConfig.getConfigValue())-count)));
+            iSysConfigService.updateConfig(sysConfig);
+        }
+        fsCourseTrafficLogMapper.updateStatusByIds(ids,2);
+    }
+
     private static String formatDuration(long millis) {
         long seconds = millis / 1000;
         long minutes = seconds / 60;

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

@@ -405,7 +405,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         if (videoDuration==null){
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             videoDuration=video.getDuration();
-            redisCache.setCacheObject(videoRedisKey,video.getDuration().toString());
+            redisCache.setCacheObject(videoRedisKey,video.getDuration());
         }
         return videoDuration;
     }

+ 8 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -529,6 +529,14 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
             // 观看时长
             recordVO.setWatchTime((BigDecimal) sumMap.getOrDefault("watchTime", BigDecimal.ZERO));
 
+            Long ljDay = fsCourseWatchLogMapper.selectByWatchLjDay(recordVO.getUserId(),recordVO.getProjectId());
+            System.out.println("进入了统计累计观看天数:"+ljDay+"天");
+            recordVO.setWatchLjCount(ljDay);
+            //连续观看天数
+            Long lxDay = fsCourseWatchLogMapper.selectByWatchlxDay(recordVO.getUserId(),recordVO.getProjectId());
+            System.out.println("进入了连续观看天数:"+lxDay+"天");
+            recordVO.setWatchLxCount(lxDay);
+
             // 领取状态
             Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getVideoId());
             if (Objects.nonNull(count) && count > 0) {

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

@@ -62,11 +62,12 @@ public class FsUserCourseTrainingCampServiceImpl extends ServiceImpl<FsUserCours
      * @param params    参数
      */
     @Override
-    public void add(FsUserCourseTrainingCampDTO params) {
+    public void add(FsUserCourseTrainingCampDTO params,Long userId) {
         FsUserCourseTrainingCamp trainingCamp = new FsUserCourseTrainingCamp();
         trainingCamp.setTrainingCampName(params.getTrainingCampName());
         trainingCamp.setOrderNumber(baseMapper.getOrderNumber());
         trainingCamp.setCreateTime(LocalDateTime.now());
+        trainingCamp.setUserId(userId);
         baseMapper.insert(trainingCamp);
     }
 

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

@@ -204,6 +204,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Autowired
     private SysDictDataMapper dictDataMapper;
 
+    @Autowired
+    private FsCourseAnswerLogsMapper courseAnswerLogsMapper;
+
 
     /**
      * 查询课堂视频
@@ -929,6 +932,13 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (log == null) {
             return R.error("无记录");
         }
+
+        FsCourseAnswerLogs rightLog = courseAnswerLogsMapper.selectRightLogByCourseVideo(param.getVideoId(), param.getUserId(), param.getQwUserId());
+
+        if (rightLog == null) {
+            logger.error("未答题:{}",param.getUserId());
+            return R.error("未答题");
+        }
         if (log.getRewardType() != null) {
             FsCourseRedPacketLog fsCourseRedPacketLog = redPacketLogMapper.selectUserFsCourseRedPacketLog(param.getVideoId(), param.getUserId(),param.getPeriodId());
             if(fsCourseRedPacketLog != null && fsCourseRedPacketLog.getStatus() == 1) {
@@ -1111,27 +1121,17 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
 
     private void handleFsUserWx(FsUser user, String appId) {
-        // 尝试更新
-        boolean updated = fsUserWxService.lambdaUpdate()
-                .eq(FsUserWx::getFsUserId, user.getUserId())
-                .eq(FsUserWx::getAppId,appId )
-                .eq(FsUserWx::getOpenId, user.getMaOpenId())
-//                .set(FsUserWx::getUnionId, session.getUnionid() == null ? "" : session.getUnionid())
-                .set(FsUserWx::getUpdateTime, new Date())
-                .update();
-
-        // 如果更新失败(记录不存在),则插入
-        if (!updated) {
-            FsUserWx fsUserWx = new FsUserWx();
-            fsUserWx.setType(1);
-            fsUserWx.setFsUserId(user.getUserId());
-            fsUserWx.setAppId(appId);
-            fsUserWx.setOpenId(user.getMaOpenId());
-//            fsUserWx.setUnionId(session.getUnionid() == null ? "" : session.getUnionid());
-            fsUserWx.setCreateTime(new Date());
-            fsUserWx.setUpdateTime(new Date());
-            fsUserWxService.save(fsUserWx);
-        }
+        FsUserWx fsUserWx = new FsUserWx();
+        fsUserWx.setType(1);
+        fsUserWx.setFsUserId(user.getUserId());
+        fsUserWx.setAppId(appId);
+        fsUserWx.setOpenId(user.getCourseMaOpenId());
+        fsUserWx.setUnionId(user.getUnionId());
+        fsUserWx.setCreateTime(new Date());
+        fsUserWx.setUpdateTime(new Date());
+        fsUserWxService.saveOrUpdateByUniqueKey(fsUserWx);
+
+        logger.info("zyp \n 【更新或插入用户与小程序{}的绑定关系】:{}", appId, user.getUserId());
     }
 
     /**
@@ -1145,20 +1145,19 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
      * @return 处理结果
      */
     private R sendRedPacketRewardFsUser(FsCourseSendRewardUParam param, FsUser user, FsCourseWatchLog log, FsUserCourseVideo video, CourseConfig config) {
-        // 判断是否属于领取红包时间(会员看课发放红包)
-        if (param.getPeriodId()!=null && param.getPeriodId()>0) {
-            FsUserCoursePeriodDays periodDays = new FsUserCoursePeriodDays();
-            periodDays.setVideoId(param.getVideoId());
-            periodDays.setPeriodId(param.getPeriodId());
-            //正常情况是只能查询到一条,之前可能存在重复的脏数据,暂使用查询list的方式
-            List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysList(periodDays);
-            if(fsUserCoursePeriodDays != null && !fsUserCoursePeriodDays.isEmpty()){
-                periodDays = fsUserCoursePeriodDays.get(0);
-            }
-            if(periodDays != null && periodDays.getLastJoinTime() !=null && LocalDateTime.now().isAfter(periodDays.getLastJoinTime())) {
-                return R.error(403,"已超过领取红包时间");
-            }
+
+        FsUserCoursePeriodDays periodDays = new FsUserCoursePeriodDays();
+        periodDays.setVideoId(param.getVideoId());
+        periodDays.setPeriodId(param.getPeriodId());
+        //正常情况是只能查询到一条,之前可能存在重复的脏数据,暂使用查询list的方式
+        List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysList(periodDays);
+        if(fsUserCoursePeriodDays != null && !fsUserCoursePeriodDays.isEmpty()){
+            periodDays = fsUserCoursePeriodDays.get(0);
         }
+        if(periodDays != null && periodDays.getLastJoinTime() !=null && LocalDateTime.now().isAfter(periodDays.getLastJoinTime())) {
+            return R.error(403,"已超过领取红包时间");
+        }
+
 
         // 确定红包金额
         BigDecimal amount = BigDecimal.ZERO;
@@ -1172,7 +1171,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 准备发送红包参数
         WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
-//        packetParam.setOpenId(getOpenId(user.getUserId(), param.getCompanyId(), param.getSource()));
         packetParam.setOpenId(user.getMpOpenId());
         // 来源是小程序切换openId
         if (param.getSource() == 2) {
@@ -1182,7 +1180,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 //                return R.error("销售公司参数错误,未绑定小程序");
 //            }
             FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(param.getAppId(),user.getUserId(),1);
-            if (fsUserWx ==null || fsUserWx.getOpenId()==null){
+            if (fsUserWx ==null){
+                if (user.getCourseMaOpenId()==null){
+                    logger.error("zyp \n 【转账openId参数错误】:{}", user.getUserId());
+                    return R.error("openId参数错误");
+                }
                 packetParam.setOpenId(user.getCourseMaOpenId());
                 try {
                     handleFsUserWx(user,param.getAppId());
@@ -1193,10 +1195,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             }else {
                 packetParam.setOpenId(fsUserWx.getOpenId());
             }
-
-            System.out.println("小程序id"+user.getCourseMaOpenId());
-            //查出公司绑定openid并赋值
-//            packetParam.setOpenId(fsUserWx.getOpenId());
         }
         packetParam.setAmount(amount);
         packetParam.setSource(param.getSource());
@@ -1206,9 +1204,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         System.out.println("红包金额"+amount);
         System.out.println("红包商户号"+packetParam);
-        if (ObjectUtils.isNotEmpty(config.getIsNegative())&&config.getIsNegative() == 1) {
-            return processRedPacket(config, packetParam, param, amount, log);
-        }
+//        if (ObjectUtils.isNotEmpty(config.getIsNegative())&&config.getIsNegative() == 1) {
+//            return processRedPacket(config, packetParam, param, amount, log);
+//        }
         //2025.6.19 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
 
@@ -1243,10 +1241,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                     redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
                 }else {
                     redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+                    redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
                 }
                 // 添加红包记录
                 redPacketLog.setCourseId(param.getCourseId());
-//            redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
                 redPacketLog.setCompanyId(param.getCompanyId());
                 redPacketLog.setUserId(param.getUserId());
                 redPacketLog.setVideoId(param.getVideoId());
@@ -2342,7 +2340,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         Long duration = redisCache.getCacheObject(redisKey);
 
         if (duration == null) {
-            FsUserCourseVideoQVO videoInfo = selectFsUserCourseVideoByVideoIdVO(videoId);
+            FsUserCourseVideoQVO videoInfo = selectFsUserCourseVideoByVideoIdVO(videoId,null);
             if (videoInfo == null || videoInfo.getDuration() == null) {
                 throw new IllegalArgumentException("视频时长信息不存在");
             }
@@ -2473,9 +2471,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
     @Override
-    public FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId) {
+    public FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId,Long userId) {
         FsUserCourseVideoQVO fsUserCourseVideoQVO = new FsUserCourseVideoQVO();
-        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
+        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoIdAndUserId(videoId,userId);
 
         BeanCopyUtils.copy(courseVideo,fsUserCourseVideoQVO);
 

+ 94 - 86
fs-service/src/main/java/com/fs/course/service/impl/FsUserWatchCourseStatisticsServiceImpl.java

@@ -8,6 +8,7 @@ import com.fs.course.service.IFsUserWatchCourseStatisticsService;
 import com.fs.his.mapper.FsUserMapper;
 import com.google.common.collect.Lists;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
@@ -33,6 +34,7 @@ import java.util.stream.Collectors;
  */
 @Service
 @AllArgsConstructor
+@Slf4j
 public class FsUserWatchCourseStatisticsServiceImpl extends ServiceImpl<FsUserWatchCourseStatisticsMapper, FsUserWatchCourseStatistics> implements IFsUserWatchCourseStatisticsService {
 
     private FsUserCoursePeriodDaysMapper fsUserCoursePeriodDaysMapper;
@@ -132,96 +134,102 @@ public class FsUserWatchCourseStatisticsServiceImpl extends ServiceImpl<FsUserWa
     public void insertWatchCourseStatistics() {
         // 1、获取统计数据
         // 查询课程相关数据
-        List<FsUserWatchCourseStatistics> fsUserWatchCourseStatistics = fsUserCoursePeriodDaysMapper.selectDaysCountList();
-
-        // 查询统计数据
-        List<FsUserWatchCourseStatistics> watchLog = fsUserMapper.selectWatchLogCount();
-        List<FsUserWatchCourseStatistics> redPacketLog = fsUserMapper.selectRedPacketLogCount();
-        List<FsUserWatchCourseStatistics> answerLog = fsUserMapper.selectAnswerLogCount();
-        List<FsUserWatchCourseStatistics> userTotal = fsUserMapper.selectFsUserDetail();
-
-        // 转化为自定义键的map
-        Map<String, FsUserWatchCourseStatistics> watchLogMap = watchLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
-        Map<String, FsUserWatchCourseStatistics> redPacketLogMap = redPacketLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
-        Map<String, FsUserWatchCourseStatistics> answerLogMap = answerLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
-        Map<Long, List<FsUserWatchCourseStatistics>> userTotalMap = userTotal.stream()
-                .collect(Collectors.groupingBy(FsUserWatchCourseStatistics::getCompanyUserId));
-
-        // 处理数据
-        List<FsUserWatchCourseStatistics> list = new ArrayList<>();
-        for (FsUserWatchCourseStatistics data : fsUserWatchCourseStatistics) {
-            FsUserWatchCourseStatistics vo = new FsUserWatchCourseStatistics();
-            String key = String.format("%s-%s-%s", data.getPeriodId(), data.getVideoId(), data.getCompanyUserId());
-            FsUserWatchCourseStatistics watchLogData = watchLogMap.get(key);
-            FsUserWatchCourseStatistics redPacketLogData = redPacketLogMap.get(key);
-            FsUserWatchCourseStatistics answerLogData = answerLogMap.get(key);
-            List<FsUserWatchCourseStatistics> userTotalDataList = userTotalMap.get(data.getCompanyUserId());
-            BeanUtils.copyProperties(data, vo);
-            // 改成使用营期线来表示营期开始时间
-            vo.setPeriodStartingTime(data.getPeriodLine() != null ? data.getPeriodLine() : data.getPeriodStartingTime());
-
-            // 单独一个一个set,不用copy,避免copy出来的结果被前面的覆盖
-            if(userTotalDataList != null && !userTotalDataList.isEmpty()){
-                // 获取过滤时间后的销售会员数量
-                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
-
-                int userNum = userTotalDataList.stream()
-                        .filter(v -> v.getUserCreateDate().before(data.getCourseStartDateTime())).mapToInt(FsUserWatchCourseStatistics::getUserNum).sum();
-                int newUserNum = userTotalDataList.stream()
-                        .filter(v -> sdf.format(v.getUserCreateDate()).equals(sdf.format(data.getCourseStartDateTime()))).mapToInt(FsUserWatchCourseStatistics::getUserNum).sum();
-                vo.setUserNum(userNum);
-                vo.setNewUserNum(newUserNum);
-            } else {
-                vo.setUserNum(0);
-                vo.setNewUserNum(0);
+        try{
+            List<FsUserWatchCourseStatistics> fsUserWatchCourseStatistics = fsUserCoursePeriodDaysMapper.selectDaysCountList();
+
+            // 查询统计数据
+            List<FsUserWatchCourseStatistics> watchLog = fsUserMapper.selectWatchLogCount();
+            List<FsUserWatchCourseStatistics> redPacketLog = fsUserMapper.selectRedPacketLogCount();
+            List<FsUserWatchCourseStatistics> answerLog = fsUserMapper.selectAnswerLogCount();
+            List<FsUserWatchCourseStatistics> userTotal = fsUserMapper.selectFsUserDetail();
+
+            // 转化为自定义键的map
+            Map<String, FsUserWatchCourseStatistics> watchLogMap = watchLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+            Map<String, FsUserWatchCourseStatistics> redPacketLogMap = redPacketLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+            Map<String, FsUserWatchCourseStatistics> answerLogMap = answerLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+            Map<Long, List<FsUserWatchCourseStatistics>> userTotalMap = userTotal.stream()
+                    .collect(Collectors.groupingBy(FsUserWatchCourseStatistics::getCompanyUserId));
+
+            // 处理数据
+            List<FsUserWatchCourseStatistics> list = new ArrayList<>();
+            for (FsUserWatchCourseStatistics data : fsUserWatchCourseStatistics) {
+                FsUserWatchCourseStatistics vo = new FsUserWatchCourseStatistics();
+                String key = String.format("%s-%s-%s", data.getPeriodId(), data.getVideoId(), data.getCompanyUserId());
+                FsUserWatchCourseStatistics watchLogData = watchLogMap.get(key);
+                FsUserWatchCourseStatistics redPacketLogData = redPacketLogMap.get(key);
+                FsUserWatchCourseStatistics answerLogData = answerLogMap.get(key);
+                List<FsUserWatchCourseStatistics> userTotalDataList = userTotalMap.get(data.getCompanyUserId());
+                BeanUtils.copyProperties(data, vo);
+                // 改成使用营期线来表示营期开始时间
+                vo.setPeriodStartingTime(data.getPeriodLine() != null ? data.getPeriodLine() : data.getPeriodStartingTime());
+
+                // 单独一个一个set,不用copy,避免copy出来的结果被前面的覆盖
+                if(userTotalDataList != null && !userTotalDataList.isEmpty()){
+                    // 获取过滤时间后的销售会员数量
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+
+                    int userNum = userTotalDataList.stream()
+                            .filter(v -> v.getUserCreateDate().before(data.getCourseStartDateTime())).mapToInt(FsUserWatchCourseStatistics::getUserNum).sum();
+                    int newUserNum = userTotalDataList.stream()
+                            .filter(v -> sdf.format(v.getUserCreateDate()).equals(sdf.format(data.getCourseStartDateTime()))).mapToInt(FsUserWatchCourseStatistics::getUserNum).sum();
+                    vo.setUserNum(userNum);
+                    vo.setNewUserNum(newUserNum);
+                } else {
+                    vo.setUserNum(0);
+                    vo.setNewUserNum(0);
+                }
+
+                if(watchLogData != null) {
+                    vo.setWatchNum(watchLogData.getWatchNum());
+                    vo.setCompleteWatchNum(watchLogData.getCompleteWatchNum());
+                    vo.setCompleteWatchRate(watchLogData.getCompleteWatchRate());
+                } else {
+
+                    vo.setWatchNum(0);
+                    vo.setCompleteWatchNum(0);
+                    vo.setCompleteWatchRate(BigDecimal.ZERO);
+                }
+
+                if(redPacketLogData != null) {
+                    vo.setRedPacketNum(redPacketLogData.getRedPacketNum());
+                    vo.setRedPacketAmount(redPacketLogData.getRedPacketAmount());
+                } else {
+                    vo.setRedPacketNum(0);
+                    vo.setRedPacketAmount(BigDecimal.ZERO);
+                }
+
+                if(answerLogData != null) {
+                    vo.setAnswerNum(answerLogData.getAnswerNum());
+                    vo.setAnswerRightNum(answerLogData.getAnswerRightNum());
+                    vo.setAnswerRightRate(answerLogData.getAnswerRightRate());
+                } else {
+                    vo.setAnswerNum(0);
+                    vo.setAnswerRightNum(0);
+                    vo.setAnswerRightRate(BigDecimal.ZERO);
+                }
+
+                // 设置上线率
+                BigDecimal watchNum = new BigDecimal(vo.getWatchNum());
+                BigDecimal userNum = new BigDecimal(vo.getUserNum());
+                if(!userNum.equals(BigDecimal.ZERO)){
+                    BigDecimal onlineRate = watchNum.divide(userNum, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                    vo.setOnlineRate(onlineRate);
+                } else{
+                    vo.setOnlineRate(BigDecimal.ZERO);
+                }
+
+                vo.setCreateTime(new Date());
+                vo.setUpdateTime(new Date());
+                list.add(vo);
             }
 
-            if(watchLogData != null) {
-                vo.setWatchNum(watchLogData.getWatchNum());
-                vo.setCompleteWatchNum(watchLogData.getCompleteWatchNum());
-                vo.setCompleteWatchRate(watchLogData.getCompleteWatchRate());
-            } else {
-                vo.setWatchNum(0);
-                vo.setCompleteWatchNum(0);
-                vo.setCompleteWatchRate(BigDecimal.ZERO);
-            }
-
-            if(redPacketLogData != null) {
-                vo.setRedPacketNum(redPacketLogData.getRedPacketNum());
-                vo.setRedPacketAmount(redPacketLogData.getRedPacketAmount());
-            } else {
-                vo.setRedPacketNum(0);
-                vo.setRedPacketAmount(BigDecimal.ZERO);
-            }
-
-            if(answerLogData != null) {
-                vo.setAnswerNum(answerLogData.getAnswerNum());
-                vo.setAnswerRightNum(answerLogData.getAnswerRightNum());
-                vo.setAnswerRightRate(answerLogData.getAnswerRightRate());
-            } else {
-                vo.setAnswerNum(0);
-                vo.setAnswerRightNum(0);
-                vo.setAnswerRightRate(BigDecimal.ZERO);
-            }
-
-            // 设置上线率
-            BigDecimal watchNum = new BigDecimal(vo.getWatchNum());
-            BigDecimal userNum = new BigDecimal(vo.getUserNum());
-            if(!userNum.equals(BigDecimal.ZERO)){
-                BigDecimal onlineRate = watchNum.divide(userNum, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-                vo.setOnlineRate(onlineRate);
-            } else{
-                vo.setOnlineRate(BigDecimal.ZERO);
-            }
-
-            vo.setCreateTime(new Date());
-            vo.setUpdateTime(new Date());
-            list.add(vo);
+            //2、分批次插入数据
+            this.batchInsert(list);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error("数据存在问题:{}",e.getMessage());
         }
 
-        //2、分批次插入数据
-        this.batchInsert(list);
-
     }
 
     private void batchInsert(List<FsUserWatchCourseStatistics> list) {

+ 15 - 0
fs-service/src/main/java/com/fs/course/vo/FsUserCourseParticipationRecordVO.java

@@ -64,4 +64,19 @@ public class FsUserCourseParticipationRecordVO {
      * 标签
      */
     private List<CompanyTag> tags;
+
+    /**
+     * 累计观看天数
+     */
+    private Long watchLjCount;
+
+    /**
+     * 连续观看天数
+     */
+    private Long watchLxCount;
+
+    /**
+     * 项目编号
+     */
+    private Long projectId;
 }

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

@@ -81,8 +81,9 @@ public interface FsUserCouponMapper
             "            <if test=\"businessId != null \"> and uc.business_id = #{businessId}</if>\n" +
             "            <if test=\"businessType != null \"> and uc.business_type = #{businessType}</if>\n" +
             "            <if test=\"status != null \"> and uc.status = #{status}</if>\n" +
-            "            <if test=\"companyName != null \">and com.company_name like concat('%', #{companyName}, '%') </if>\n" +
-            "            <if test=\"companyUserName != null \">and comu.user_name like concat('%', #{companyUserName}, '%') </if>\n" +
+            "            <if test=\"companyName != null and companyName != ''\">and com.company_name like concat('%', #{companyName}, '%') </if>\n" +
+            "            <if test=\"companyUserName != null and companyUserName != ''\">and comu.user_name like concat('%', #{companyUserName}, '%') </if>\n" +
+            "            <if test=\"companyId != null \">and uc.company_id = #{companyId} </if>\n" +
             "        </where> "+
             " order by id desc"+
             "</script>"})

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

@@ -55,4 +55,6 @@ public class FsUserCouponParam {
     private String companyName;
     private String companyUserName;
 
+    private Long companyId;
+
 }

+ 28 - 21
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -3402,28 +3402,35 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
         DFApiResponse dfApiResponse = JSON.parseObject(body, DFApiResponse.class);
         Object result = dfApiResponse.getResult();
         if (result != null) {
+
             String jsonString = JSON.toJSONString(result);
-            List<DFOrderStatusResultRequest> requestList = JSON.parseArray(jsonString, DFOrderStatusResultRequest.class);
-            if (requestList != null && !requestList.isEmpty()) {
-                //0待揽收 1已揽收 2运输中 3派送中 4异常件 5退回件 6退回签收 7转寄件 8作废件 9已签收 10 已取消
-                for (DFOrderStatusResultRequest temp : requestList) {
-                    if (temp.getStatus() == 10) {
-                        //取消订单
-                        String mailNumber = temp.getMailNumber();
-                        List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectFsStoreOrderListByDeliverySn(mailNumber);
-                        if (fsStoreOrders != null && !fsStoreOrders.isEmpty()) {
-                            fsStoreOrders.forEach(order -> {
-                                FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
-                                afterSalesParam.setOrderId(order.getOrderId());
-                                afterSalesParam.setReasons("代服管家取消订单");
-                                afterSalesParam.setOperator("代服管家");
-                                afterSales(afterSalesParam);
-                                FsStoreOrderDf df = new FsStoreOrderDf();
-                                df.setOrderId(order.getOrderId());
-                                df.setStatus(2);
-                                df.setUpdateTime(new Date());
-                                fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
-                            });
+            log.info("ct1111111111111111111{}", jsonString);
+            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsonString);
+            if (jsonObject != null) {
+                Object listObj = jsonObject.get("list");
+                String listJson = JSON.toJSONString(listObj);
+                List<DFOrderStatusResultRequest> requestList = JSON.parseArray(listJson, DFOrderStatusResultRequest.class);
+                if (requestList != null && !requestList.isEmpty()) {
+                    //0待揽收 1已揽收 2运输中 3派送中 4异常件 5退回件 6退回签收 7转寄件 8作废件 9已签收 10 已取消
+                    for (DFOrderStatusResultRequest temp : requestList) {
+                        if (temp.getStatus() == 10) {
+                            //取消订单
+                            String mailNumber = temp.getMailNumber();
+                            List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectFsStoreOrderListByDeliverySn(mailNumber);
+                            if (fsStoreOrders != null && !fsStoreOrders.isEmpty()) {
+                                fsStoreOrders.forEach(order -> {
+                                    FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
+                                    afterSalesParam.setOrderId(order.getOrderId());
+                                    afterSalesParam.setReasons("代服管家取消订单");
+                                    afterSalesParam.setOperator("代服管家");
+                                    afterSales(afterSalesParam);
+                                    FsStoreOrderDf df = new FsStoreOrderDf();
+                                    df.setOrderId(order.getOrderId());
+                                    df.setStatus(2);
+                                    df.setUpdateTime(new Date());
+                                    fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
+                                });
+                            }
                         }
                     }
                 }

+ 4 - 4
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -571,7 +571,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
 
         try {
             TransferBatchesResult transferBatchesResult = transferService.transferBatches(request);
-            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo());
+            return R.ok("发送红包成功").put("orderCode", transferBatchesResult.getOutBatchNo()).put("batchId", transferBatchesResult.getBatchId());
         } catch (WxPayException e) {
             e.printStackTrace();
             return R.error("发送失败");
@@ -597,8 +597,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             signatureHeader.setSignature(request.getHeader("Wechatpay-Signature"));
             WxPayTransferBatchesNotifyV3Result result = wxPayService.parseTransferBatchesNotifyV3Result(notifyData,signatureHeader);
             logger.info("到零钱回调:{}",result.getResult());
-            if (result.getResult().getBatchStatus().equals("FINISHED")) {
-                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo());
+            if (result.getResult().getBatchStatus().equals("FINISHED") && result.getResult().getFailNum()==0) {
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBatchNo(),result.getResult().getBatchId());
                 logger.info("result:{}",r);
                 if (r.get("code").equals(200)){
                     return WxPayNotifyResponse.success("处理成功");
@@ -720,7 +720,7 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
             TransferBillsNotifyResult result = wxPayService.parseTransferBillsNotifyV3Result(notifyData,signatureHeader);
             logger.info("到零钱回调:{}",result.getResult());
             if (result.getResult().getState().equals("SUCCESS")) {
-                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo());
+                R r = redPacketLogService.syncRedPacket(result.getResult().getOutBillNo(),result.getResult().getTransferBillNo());
                 logger.info("result:{}",r);
                 if (r.get("code").equals(200)){
                     return WxPayNotifyResponse.success("处理成功");

+ 4 - 0
fs-service/src/main/java/com/fs/statis/dto/TrafficLogDTO.java

@@ -22,4 +22,8 @@ public class TrafficLogDTO implements Serializable {
      * 本月流量
      */
     private Long thisMonth;
+    /**
+     * 剩余流量
+     */
+    private String traffic;
 }

+ 19 - 19
fs-service/src/main/java/com/fs/task/trafficlog/TrafficlogTask.java

@@ -1,19 +1,19 @@
-package com.fs.task.trafficlog;
-
-import com.fs.course.service.IFsCourseTrafficLogService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-@Service("trafficlogTask")
-@Slf4j
-public class TrafficlogTask {
-    @Autowired
-    private IFsCourseTrafficLogService fsCourseTrafficLogService;
-    /**
-     * 红包流量统计
-     */
-    /*public void sumTrafficlog(){
-        fsCourseTrafficLogService.sumTrafficlog();
-    }*/
-}
+//package com.fs.task.trafficlog;
+//
+//import com.fs.course.service.IFsCourseTrafficLogService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Service;
+//
+//@Service("trafficlogTask")
+//@Slf4j
+//public class TrafficlogTask {
+//    @Autowired
+//    private IFsCourseTrafficLogService fsCourseTrafficLogService;
+//    /**
+//     * 红包流量统计
+//     */
+//    /*public void sumTrafficlog(){
+//        fsCourseTrafficLogService.sumTrafficlog();
+//    }*/
+//}

+ 1 - 1
fs-service/src/main/resources/application-config-druid-hzyy.yml

@@ -88,7 +88,7 @@ headerImg:
   imgUrl: https://hzyy.obs.cn-north-4.myhuaweicloud.com/fs/20250616/1750067609692.png
 ipad:
   ipadUrl: http://139.159.133.223:8667
-  aiApi: http://154.8.194.176:3000/api
+  aiApi: http://1.95.196.10:3000/api
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:

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

@@ -42,10 +42,10 @@ wx:
       port: 6379
       timeout: 2000
     configs:
-      - appId:  # 第一个公众号的appid
-        secret:  # 公众号的appsecret
-        token:  # 接口配置里的Token值
-        aesKey:  # 接口配置里的EncodingAESKey值
+      - appId:  wxd0a67578869950ab # 第一个公众号的appid
+        secret: 645f649be6d748e33e71cefec2469e86  # 公众号的appsecret
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
 aifabu:  #爱链接
   appKey: 7b471be905ab17ef358c0dd117601d008
 watch:
@@ -77,7 +77,7 @@ cloud_host:
   company_name: 宽益堂
 #看课授权时显示的头像
 headerImg:
-  imgUrl: https://yztcourse-1325300895.cos.ap-guangzhou.myqcloud.com/yztcourse/20250523/e04871a98cc84be39a7f60c084698e21.jpg
+  imgUrl: https://kuanyitang-1317640934.cos.ap-shanghai.myqcloud.com/kuanyitang/20250813/6b3b62e01672407c98f0561b73e35f6a.jpg
 ipad:
   ipadUrl:
   aiApi:

+ 3 - 20
fs-service/src/main/resources/application-config-zkzh.yml

@@ -71,26 +71,6 @@ wx:
         token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
         aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
         msgDataFormat: JSON
-      - appid: wxedde588767b358b1   #中康未来智慧药房
-        secret: 928d2961c81610d8f64b019597212fcd
-        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
-        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
-        msgDataFormat: JSON
-      - appid: wxdbaca81abc336277   #虹恺百货店
-        secret: 31b39464bad4549b6c59f79e4e2c3f94
-        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
-        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
-        msgDataFormat: JSON
-      - appid: wxb025ac4091dbd4b7   #中康智慧店T
-        secret: fa122221b6bf9fd718db6e3cc0f9bc50
-        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
-        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
-        msgDataFormat: JSON
-      - appid: wxdf9b1a4d3c5b6572   #中康智慧坊
-        secret: 489055ace816380c0fceb53447381704
-        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
-        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
-        msgDataFormat: JSON
 
 
 
@@ -114,6 +94,9 @@ wx:
         secret: 473a992e28d5c524b4ff3783559026cb
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+    open:
+      appId: wx40f3de7bd405fb5c
+      secret: 4038e9209ddaf5f23dcde35e41be3120
 jpush:
   appKey: cc9a0120a3e4270c9cba340d
   masterSecret: cfc2575d3cd7470d584c990c

+ 22 - 0
fs-service/src/main/resources/mapper/company/CompanyUserMapper.xml

@@ -175,6 +175,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isAudit != null">#{isAudit},</if>
         </trim>
     </insert>
+    <insert id="insertQwIpadTotal">
+        insert into qw_ipad_total (company_id,company_name,bind_count,stat_time) values
+        <foreach item="item" collection="list" separator=",">
+            (#{item.companyId},#{item.companyName},#{item.bindCount},#{item.statTime})
+        </foreach>
+    </insert>
 
     <update id="updateCompanyUser" parameterType="CompanyUser">
         update company_user
@@ -531,6 +537,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectCompanyUserByCompanyUserId" resultMap="CompanyUserResult">
         select  * from company_user where user_id = #{companyUserId}
     </select>
+    <select id="selectCompanyByIpadStatus" resultType="com.fs.company.vo.QwIpadTotalVo">
+        select company_id companyId,company_name companyName,
+        sum(bind_count) bindCount,stat_time statTime from qw_ipad_total
+        <where>
+            <if test="dateTime != null">
+                and stat_time like concat(#{dateTime}, '%')
+            </if>
+        </where>
+        group by company_id,company_name
+    </select>
+    <select id="selectCompanyByIpadStatusCount" resultType="com.fs.company.vo.QwIpadTotalVo">
+        SELECT qw.company_id companyId,c.company_name companyName,count(1) bindCount
+        FROM `qw_user` qw left join company c on qw.company_id = c.company_id
+        where qw.ipad_status is not null
+        GROUP BY qw.company_id
+    </select>
 
     <update id="updateAllowedAllRegister" parameterType="Long">
         update company_user

+ 7 - 2
fs-service/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml

@@ -28,6 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="sort != null "> and sort = #{sort}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="questionType != null "> and question_type = #{questionType}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
             <if test="questionSubType != null "> and question_sub_type = #{questionSubType}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="question != null  and question != ''"> and question = #{question}</if>
@@ -54,6 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createBy != null">create_by,</if>
             <if test="questionType != null">question_type,</if>
             <if test="questionSubType != null">question_sub_type,</if>
+            <if test="userId != null">user_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="title != null">#{title},</if>
@@ -66,6 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="createBy != null">#{createBy},</if>
             <if test="questionType != null">#{questionType},</if>
             <if test="questionSubType != null">#{questionSubType},</if>
+            <if test="userId != null">#{userId},</if>
          </trim>
     </insert>
 
@@ -80,7 +83,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         answer,
         create_by,
         question_type,
-        question_sub_type
+        question_sub_type,
+        user_id
         )
         VALUES
         <foreach collection="list" item="item" separator=",">
@@ -94,7 +98,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{item.answer, jdbcType=CLOB},
             #{item.createBy, jdbcType=VARCHAR},
             #{item.questionType, jdbcType=VARCHAR},
-            #{item.questionSubType, jdbcType=VARCHAR}
+            #{item.questionSubType, jdbcType=VARCHAR},
+            #{item.userId, jdbcType=BIGINT}
             )
         </foreach>
     </insert>

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

@@ -429,7 +429,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             send_type = 1
           AND video_id = #{videoId}
           AND user_id = #{fsUserId}
-          AND company_user_id = #{companyUserId}
+          AND company_user_id = #{companyUserId}  order by log_id desc limit 1
     </select>
     <select id="selectFsCourseWatchLogStatisticsListVONew"
             resultType="com.fs.course.vo.FsCourseWatchLogStatisticsListVO">

+ 3 - 0
fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml

@@ -85,6 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="talentId != null "> and talent_id = #{talentId}</if>
             <if test="isNext != null "> and is_next = #{isNext}</if>
             <if test="isPrivate != null "> and is_private = #{isPrivate}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
         </where>
     </select>
 
@@ -193,6 +194,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isPrivate != null">is_private,</if>
             <if test="secondImg != null">second_img,</if>
             <if test="companyIds != null">company_ids,</if>
+            <if test="userId != null">user_id,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="cateId != null">#{cateId},</if>
@@ -232,6 +234,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isPrivate != null">#{isPrivate},</if>
             <if test="secondImg != null">#{secondImg},</if>
             <if test="companyIds != null">#{companyIds},</if>
+            <if test="userId != null">#{userId},</if>
          </trim>
     </insert>
 

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

@@ -24,7 +24,9 @@
             <if test="params.companyId != null and params.companyId != ''">
                 and ctp.company_id like concat('%',#{params.companyId},'%')
             </if>
-
+            <if test="params.userIds != null and params.userIds != ''">
+                and ctc.user_id =#{params.userIds}
+            </if>
             <if test="params.userId != null and params.userId != ''">
                 and cu.user_id = #{params.userId}
             </if>

+ 3 - 0
fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml

@@ -58,6 +58,7 @@
             <if test="questionBankId != null "> and question_bank_id = #{questionBankId}</if>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="projectId != null "> and project_id = #{projectId}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
         </where>
     </select>
 
@@ -103,6 +104,7 @@
             <if test="productId != null">product_id,</if>
             <if test="listingStartTime != null">listing_start_time,</if>
             <if test="listingEndTime != null">listing_end_time,</if>
+            <if test="userId != null">user_id,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="fileId != null">#{fileId},</if>
@@ -139,6 +141,7 @@
             <if test="listingStartTime != null">#{listingStartTime},</if>
             <if test="listingEndTime != null">#{listingEndTime},</if>
             <if test="projectId != null">#{projectId},</if>
+            <if test="userId != null">#{userId},</if>
         </trim>
     </insert>
     <insert id="insertBatchFsUserCourseVideo" parameterType="FsUserCourseVideo" useGeneratedKeys="true" keyProperty="videoId">

+ 3 - 0
fs-service/src/main/resources/mapper/course/FsVideoResourceMapper.xml

@@ -18,6 +18,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="params.typeId != null">
             and rr.type_id = #{params.typeId}
         </if>
+        <if test="params.userId != null">
+            and rr.user_id = #{params.userId}
+        </if>
         <if test="params.typeSubId != null">
             and rr.type_sub_id = #{params.typeSubId}
         </if>

+ 19 - 5
fs-user-app/src/main/java/com/fs/app/controller/CouponController.java

@@ -4,17 +4,17 @@ package com.fs.app.controller;
 import cn.hutool.Hutool;
 import cn.hutool.core.util.IdUtil;
 import com.fs.app.annotation.Login;
+import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.enums.BusinessType;
 import com.fs.his.domain.FsCoupon;
-import com.fs.his.domain.FsPackage;
 import com.fs.his.param.*;
 import com.fs.his.service.IFsCouponService;
-import com.fs.his.service.IFsDoctorService;
-import com.fs.his.service.IFsPackageService;
+import com.fs.his.service.IFsUserCouponService;
 import com.fs.his.vo.FsCouponListUVO;
-import com.fs.his.vo.FsDoctorListUVO;
-import com.fs.his.vo.FsPackageListUVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
@@ -40,6 +40,9 @@ public class CouponController extends  AppBaseController {
     @Autowired
     private RedisCache redisCache;
 
+    @Autowired
+    private IFsUserCouponService fsUserCouponService;
+
     @ApiOperation("获取优惠券列表")
     @GetMapping("/getCouponList")
     public R getCouponList(FsCouponListUParam param)
@@ -84,5 +87,16 @@ public class CouponController extends  AppBaseController {
         return couponService.receive(param);
     }
 
+    /**
+     * 发送会员优惠券
+     */
+    @RepeatSubmit
+    @Log(title = "发送会员优惠券", businessType = BusinessType.INSERT)
+    @PostMapping("/sendCoupon")
+    public AjaxResult sendCoupon(@RequestBody FsUserCouponSendParam fsUserCoupon)
+    {
+        return toAjax(fsUserCouponService.sendFsUserCoupon(fsUserCoupon));
+    }
+
 
 }

+ 16 - 0
fs-user-app/src/main/java/com/fs/app/controller/UserController.java

@@ -6,6 +6,7 @@ import com.fs.app.annotation.Login;
 import com.fs.app.param.FsDoctorRegisterParam;
 import com.fs.app.param.FsUserEditParam;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.sign.Md5Utils;
@@ -23,6 +24,7 @@ import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.his.vo.FsDoctorListUVO;
 import com.fs.his.vo.FsUserCouponCountUVO;
 import com.fs.his.vo.FsUserCouponListUVO;
+import com.fs.his.vo.UserVo;
 import com.fs.qw.service.IQwAppContactWayService;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
@@ -277,4 +279,18 @@ public class UserController extends  AppBaseController {
         return userService.updateStatus(id);
     }
 
+    /**
+     * 查询用户
+     */
+    @GetMapping("/user/list/{name}")
+    public TableDataInfo userlist(@PathVariable("name")String name)
+    {
+        List<UserVo> list = userService.selectUserVOList(name);
+        if (list==null|| list.isEmpty()){
+            String s = encryptPhone(name);
+            list = userService.selectUserVOList(s);
+        }
+        return getDataTable(list);
+    }
+
 }