Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	fs-service/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java
zx 1 Minggu lalu
induk
melakukan
c86b3eb730
70 mengubah file dengan 1674 tambahan dan 227 penghapusan
  1. 1 8
      fs-admin/src/main/java/com/fs/course/controller/FsCourseQuestionBankController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/course/controller/FsCourseRedPacketLogController.java
  3. 2 26
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java
  4. 1 12
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseTrainingCampController.java
  5. 0 12
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseVideoController.java
  6. 1 14
      fs-admin/src/main/java/com/fs/course/controller/FsVideoResourceController.java
  7. 33 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  8. 20 0
      fs-admin/src/main/java/com/fs/his/task/SendRedPacketTask.java
  9. 19 0
      fs-admin/src/main/java/com/fs/qw/OrderTask.java
  10. 1 1
      fs-admin/src/main/java/com/fs/qw/controller/QwSopController.java
  11. 1 1
      fs-admin/src/main/resources/application.yml
  12. 5 1
      fs-company/pom.xml
  13. 34 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyRechargeController.java
  14. 1 1
      fs-company/src/main/java/com/fs/company/controller/course/FsCourseTrafficLogController.java
  15. 1 1
      fs-company/src/main/java/com/fs/company/controller/course/FsUserCourseController.java
  16. 8 0
      fs-company/src/main/java/com/fs/company/controller/pay/WxPayApiController.java
  17. 189 0
      fs-company/src/main/java/com/fs/company/controller/pay/WxPayController.java
  18. 98 0
      fs-company/src/main/java/com/fs/company/controller/pay/bean/AliPayBean.java
  19. 71 0
      fs-company/src/main/java/com/fs/company/controller/pay/bean/WxPayBean.java
  20. 106 0
      fs-company/src/main/java/com/fs/company/controller/pay/bean/WxPayV3Bean.java
  21. 1 0
      fs-company/src/main/java/com/fs/framework/config/SecurityConfig.java
  22. 83 0
      fs-service/src/main/java/com/fs/company/constant/PaymentStatus.java
  23. 75 0
      fs-service/src/main/java/com/fs/company/domain/CompanyRechargeOrder.java
  24. 18 0
      fs-service/src/main/java/com/fs/company/dto/CompBuySmsDTO.java
  25. 13 0
      fs-service/src/main/java/com/fs/company/dto/CompanyIdAndUserDTO.java
  26. 15 0
      fs-service/src/main/java/com/fs/company/dto/RechargeDTO.java
  27. 74 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyRechargeOrderMapper.java
  28. 16 0
      fs-service/src/main/java/com/fs/company/service/CompanyRechargeOrderService.java
  29. 17 0
      fs-service/src/main/java/com/fs/company/service/ICompanyRechargeService.java
  30. 100 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyRechargeOrderServiceImpl.java
  31. 61 3
      fs-service/src/main/java/com/fs/company/service/impl/CompanyRechargeServiceImpl.java
  32. 8 52
      fs-service/src/main/java/com/fs/core/config/WxPayProperties.java
  33. 1 0
      fs-service/src/main/java/com/fs/course/config/CourseConfig.java
  34. 1 1
      fs-service/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java
  35. 0 2
      fs-service/src/main/java/com/fs/course/domain/FsVideoResource.java
  36. 2 5
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java
  37. 0 3
      fs-service/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java
  38. 1 1
      fs-service/src/main/java/com/fs/course/service/IFsCourseQuestionBankService.java
  39. 1 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseRedPacketLogService.java
  40. 2 2
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseService.java
  41. 1 1
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseTrainingCampService.java
  42. 0 1
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  43. 1 2
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java
  44. 142 0
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseRedPacketLogServiceImpl.java
  45. 3 5
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  46. 1 2
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseTrainingCampServiceImpl.java
  47. 70 27
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  48. 12 0
      fs-service/src/main/java/com/fs/statis/domain/FsStatisQwWatch.java
  49. 44 0
      fs-service/src/main/java/com/fs/wx/utils/OrderUtils.java
  50. 2 1
      fs-service/src/main/resources/application-config-druid-kyt.yml
  51. 142 0
      fs-service/src/main/resources/application-druid-kyt-test.yml
  52. 3 0
      fs-service/src/main/resources/application-druid-kyt.yml
  53. 12 0
      fs-service/src/main/resources/application-druid-sxjz.yml
  54. 2 7
      fs-service/src/main/resources/mapper/course/FsCourseQuestionBankMapper.xml
  55. 1 0
      fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml
  56. 0 11
      fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml
  57. 0 3
      fs-service/src/main/resources/mapper/course/FsUserCourseTrainingCampMapper.xml
  58. 0 7
      fs-service/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  59. 0 3
      fs-service/src/main/resources/mapper/course/FsVideoResourceMapper.xml
  60. 39 9
      fs-service/src/main/resources/mapper/statis/FsStatisQwWatchMapper.xml
  61. 10 0
      fs-service/src/main/resources/pay/alipay.properties
  62. 8 0
      fs-service/src/main/resources/pay/alipay1.properties
  63. TEMPAT SAMPAH
      fs-service/src/main/resources/pay/cert/apiclient_cert.p12
  64. 26 0
      fs-service/src/main/resources/pay/cert/apiclient_cert.pem
  65. 28 0
      fs-service/src/main/resources/pay/cert/apiclient_key.pem
  66. 18 0
      fs-service/src/main/resources/pay/cert/证书使用说明.txt
  67. 8 0
      fs-service/src/main/resources/pay/wxpay.properties
  68. 9 0
      fs-service/src/main/resources/pay/wxpay_v3.properties
  69. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/IndexController.java
  70. 9 0
      fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java

+ 1 - 8
fs-admin/src/main/java/com/fs/course/controller/FsCourseQuestionBankController.java

@@ -43,9 +43,6 @@ public class FsCourseQuestionBankController extends BaseController
     public TableDataInfo list(FsCourseQuestionBank fsCourseQuestionBank)
     {
         startPage();
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsCourseQuestionBank.setUserId(userId);
         List<FsCourseQuestionBank> list = fsCourseQuestionBankService.selectFsCourseQuestionBankList(fsCourseQuestionBank);
         return getDataTable(list);
     }
@@ -58,9 +55,6 @@ public class FsCourseQuestionBankController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsCourseQuestionBank fsCourseQuestionBank)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsCourseQuestionBank.setUserId(userId);
         List<FsCourseQuestionBankImportDTO> list = fsCourseQuestionBankService.exportData(fsCourseQuestionBank);
         ExcelUtil<FsCourseQuestionBankImportDTO> util = new ExcelUtil<>(FsCourseQuestionBankImportDTO.class);
         return util.exportExcel(list, "题库数据");
@@ -87,7 +81,6 @@ public class FsCourseQuestionBankController extends BaseController
     {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         fsCourseQuestionBank.setCreateBy(loginUser.getUser().getNickName());
-        fsCourseQuestionBank.setUserId(loginUser.getUser().getUserId());
         return toAjax(fsCourseQuestionBankService.insertFsCourseQuestionBank(fsCourseQuestionBank));
     }
 
@@ -128,7 +121,7 @@ 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(), loginUser.getUser().getUserId());
+        String message = fsCourseQuestionBankService.importData(list, loginUser.getUser().getNickName());
         return AjaxResult.success(message);
     }
 

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

@@ -135,7 +135,7 @@ public class FsCourseRedPacketLogController extends BaseController
     @GetMapping("/courseList")
     public R courseList()
     {
-        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList(null);
+        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList();
         return R.ok().put("list", optionsVOS);
     }
 

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

@@ -44,9 +44,6 @@ public class FsUserCourseController extends BaseController
     @Autowired
     private RedisCacheUtil redisCacheUtil;
 
-    @Autowired
-    private TokenService tokenService;
-
     /**
      * 查询课程列表
      */
@@ -55,9 +52,6 @@ public class FsUserCourseController extends BaseController
     public TableDataInfo list(FsUserCourse fsUserCourse)
     {
         startPage();
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
         return getDataTable(list);
     }
@@ -70,9 +64,6 @@ public class FsUserCourseController extends BaseController
     public TableDataInfo publicList(FsUserCourse fsUserCourse)
     {
         startPage();
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
         return getDataTable(list);
     }
@@ -85,9 +76,6 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsUserCourse fsUserCourse)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
         ExcelUtil<FsUserCourse> util = new ExcelUtil<FsUserCourse>(FsUserCourse.class);
         return util.exportExcel(list, "课程数据");
@@ -101,9 +89,6 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/publicExport")
     public AjaxResult publicExport(FsUserCourse fsUserCourse)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
         ExcelUtil<FsUserCourse> util = new ExcelUtil<FsUserCourse>(FsUserCourse.class);
         return util.exportExcel(list, "课程数据");
@@ -137,9 +122,6 @@ public class FsUserCourseController extends BaseController
     @PostMapping
     public AjaxResult add(@RequestBody FsUserCourse fsUserCourse)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
 
@@ -154,9 +136,6 @@ public class FsUserCourseController extends BaseController
     @PostMapping("/public")
     public AjaxResult publicAdd(@RequestBody FsUserCourse fsUserCourse)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourse.setUserId(userId);
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
 
@@ -197,9 +176,7 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/copy/{courseId}")
     public AjaxResult copy(@PathVariable Long courseId)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        int i = fsUserCourseService.copyFsUserCourse(courseId, userId);
+        int i = fsUserCourseService.copyFsUserCourse(courseId);
         return toAjax(i);
     }
 
@@ -232,8 +209,7 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/getAllList")
     public R getAllList()
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        List<OptionsVO> list = fsUserCourseService.selectFsUserCourseAllList(loginUser.getUser().getUserId());
+        List<OptionsVO> list = fsUserCourseService.selectFsUserCourseAllList();
         return R.ok().put("data", list);
     }
 

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

@@ -12,14 +12,10 @@ 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.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import lombok.AllArgsConstructor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
@@ -34,12 +30,8 @@ import java.util.Objects;
 @AllArgsConstructor
 public class FsUserCourseTrainingCampController {
 
-    private static final Logger log = LoggerFactory.getLogger(FsUserCourseTrainingCampController.class);
     private final IFsUserCourseTrainingCampService fsUserCourseTrainingCampService;
 
-    @Autowired
-    private TokenService tokenService;
-
     /**
      * 查询训练营列表
      */
@@ -70,10 +62,7 @@ public class FsUserCourseTrainingCampController {
     @Log(title = "训练营", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@Valid @RequestBody FsUserCourseTrainingCampDTO params) {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-
-        fsUserCourseTrainingCampService.add(params, userId);
+        fsUserCourseTrainingCampService.add(params);
         return AjaxResult.success();
     }
 

+ 0 - 12
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseVideoController.java

@@ -47,9 +47,6 @@ public class FsUserCourseVideoController extends BaseController
     @Autowired
     private IFsUserCourseService fsUserCourseService;
 
-    @Autowired
-    private TokenService tokenService;
-
     /**
      * 查询课堂视频列表
      */
@@ -70,9 +67,6 @@ public class FsUserCourseVideoController extends BaseController
     @GetMapping("/export")
     public AjaxResult export(FsUserCourseVideo fsUserCourseVideo)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourseVideo.setUserId(userId);
         List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoList(fsUserCourseVideo);
         ExcelUtil<FsUserCourseVideo> util = new ExcelUtil<FsUserCourseVideo>(FsUserCourseVideo.class);
         return util.exportExcel(list, "课堂视频数据");
@@ -100,9 +94,6 @@ public class FsUserCourseVideoController extends BaseController
         if (count>0){
             return AjaxResult.error("课程排序重复");
         }
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourseVideo.setUserId(userId);
 
         // 设置项目ID
         FsUserCourse fsUserCourse = fsUserCourseService.selectFsUserCourseByCourseId(fsUserCourseVideo.getCourseId());
@@ -137,9 +128,6 @@ public class FsUserCourseVideoController extends BaseController
     public TableDataInfo getVideoListByCourseId(FsUserCourseVideo fsUserCourseVideo)
     {
         startPage();
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsUserCourseVideo.setUserId(userId);
         List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoListByCourseId(fsUserCourseVideo);
         return getDataTable(list);
     }

+ 1 - 14
fs-admin/src/main/java/com/fs/course/controller/FsVideoResourceController.java

@@ -33,9 +33,6 @@ public class FsVideoResourceController extends BaseController {
 
     private final IFsVideoResourceService fsVideoResourceService;
 
-    @Autowired
-    private TokenService tokenService;
-
     /**
      * 查询视频素材库列表
      */
@@ -53,8 +50,6 @@ public class FsVideoResourceController extends BaseController {
         params.put("fileName", fileName);
         params.put("typeId", typeId);
         params.put("typeSubId", typeSubId);
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        params.put("userId", loginUser.getUser().getUserId());
 
         PageHelper.startPage(pageNum, pageSize);
         List<FsVideoResourceVO> list = fsVideoResourceService.selectVideoResourceListByMap(params);
@@ -80,9 +75,6 @@ public class FsVideoResourceController extends BaseController {
     @PostMapping
     public AjaxResult add(@RequestBody FsVideoResource fsVideoResource)
     {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
-        fsVideoResource.setUserId(userId);
         fsVideoResource.setCreateTime(LocalDateTime.now());
         fsVideoResourceService.save(fsVideoResource);
         return AjaxResult.success();
@@ -156,15 +148,10 @@ public class FsVideoResourceController extends BaseController {
     @Log(title = "视频素材库", businessType = BusinessType.INSERT)
     @PostMapping("/batchAddVideoResource")
     public AjaxResult batchAddVideoResource(@RequestBody List<FsVideoResource> list) {
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        Long userId = loginUser.getUser().getUserId();
         if (Objects.isNull(list) || list.isEmpty()) {
             return AjaxResult.error("数据不能为空");
         }
-        list.forEach(v -> {
-            v.setCreateTime(LocalDateTime.now());
-            v.setUserId(userId);
-        });
+        list.forEach(v -> v.setCreateTime(LocalDateTime.now()));
         fsVideoResourceService.saveBatch(list);
         return AjaxResult.success();
     }

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

@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -13,9 +14,12 @@ import com.fs.common.exception.CustomException;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.course.domain.FsUserWatchStatistics;
+import com.fs.course.mapper.FsUserWatchStatisticsMapper;
 import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
+import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.param.FsUserAddIntegralTemplateParam;
 import com.fs.his.param.FsUserAddPointsParam;
 import com.fs.his.param.FsUserParam;
@@ -29,8 +33,12 @@ import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.vo.h5.FsUserPageListVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.google.common.collect.Lists;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -71,6 +79,9 @@ public class FsUserController extends BaseController
     @Autowired
     private IFsUserCompanyUserService userCompanyUserService;
 
+    @Autowired
+    private SqlSessionFactory sqlSessionFactory;
+
     /**
      * 查询用户列表
      */
@@ -273,4 +284,26 @@ public class FsUserController extends BaseController
         return userIntegralLogsService.addIntegralTemplate(integralTemplateParam);
     }
 
+    @PutMapping("/encryptPhoneTemp")
+    @ApiOperation("临时接口")
+    public void encryptPhoneTemp(){
+        FsUser fsUser = new FsUser();
+        List<FsUser> list = fsUserService.selectFsUserList(fsUser);
+        List<FsUser> fsUserList = list.stream().peek(v -> v.setPhone(encryptPhone(v.getPhone()))).collect(Collectors.toList());
+
+        // 分批次处理,一次提交500条
+        List<List<FsUser>> batches = Lists.partition(fsUserList, 500);
+        batches.forEach(batch -> {
+            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
+            try {
+                FsUserMapper mapper = sqlSession.getMapper(FsUserMapper.class);
+                batch.forEach(mapper::updateFsUser);
+                sqlSession.commit();
+            } finally {
+                sqlSession.close();
+            }
+        });
+
+    }
+
 }

+ 20 - 0
fs-admin/src/main/java/com/fs/his/task/SendRedPacketTask.java

@@ -0,0 +1,20 @@
+package com.fs.his.task;
+
+import com.fs.course.service.IFsCourseRedPacketLogService;
+import com.fs.course.service.IFsUserCourseVideoRedPackageService;
+import com.fs.course.service.IFsUserCourseVideoService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service("sendRedPacketTask")
+public class SendRedPacketTask {
+    @Autowired
+    private IFsCourseRedPacketLogService redPacketLogService;
+
+    public void sendRedPacket(){
+        redPacketLogService.sendRedPacketBf();
+    }
+
+}

+ 19 - 0
fs-admin/src/main/java/com/fs/qw/OrderTask.java

@@ -0,0 +1,19 @@
+package com.fs.qw;
+
+import com.fs.company.service.CompanyRechargeOrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component("orderTask")
+public class OrderTask {
+    @Autowired
+    private CompanyRechargeOrderService companyRechargeOrderService;
+
+
+    /**
+     * 自动关闭超时订单
+     */
+    public void autoCloseTimeOutOrder(){
+        companyRechargeOrderService.autoClosedOrder();
+    }
+}

+ 1 - 1
fs-admin/src/main/java/com/fs/qw/controller/QwSopController.java

@@ -77,7 +77,7 @@ public class QwSopController extends BaseController
     @GetMapping("/courseList")
     public R courseList()
     {
-        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList(null);
+        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList();
         return R.ok().put("list", optionsVOS);
     }
 

+ 1 - 1
fs-admin/src/main/resources/application.yml

@@ -9,5 +9,5 @@ spring:
 #    active: druid-yzt
 #    active: druid-sxjz
 #    active: druid-sft
-    active: druid-hzyy-test
+    active: druid-fby
 

+ 5 - 1
fs-company/pom.xml

@@ -39,7 +39,11 @@
             <version>1.9.3</version>
         </dependency>
 
-
+        <dependency>
+            <groupId>com.github.javen205</groupId>
+            <artifactId>IJPay-All</artifactId>
+            <version>2.7.8</version>
+        </dependency>
         <!-- Mysql驱动包 -->
         <dependency>
             <groupId>mysql</groupId>

+ 34 - 0
fs-company/src/main/java/com/fs/company/controller/company/CompanyRechargeController.java

@@ -11,6 +11,8 @@ import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyRecharge;
+import com.fs.company.domain.CompanyRechargeOrder;
+import com.fs.company.dto.RechargeDTO;
 import com.fs.company.service.ICompanyRechargeService;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.util.OrderUtils;
@@ -72,6 +74,38 @@ public class CompanyRechargeController extends BaseController
     }
 
 
+    /**
+     * 充值
+     * @return AjaxResult
+     */
+    @PostMapping("/wxRecharge")
+    public AjaxResult recharge(@RequestBody RechargeDTO dto){
+        CompanyRechargeOrder companyRechargeOrder;
+        try {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
+            dto.setCompanyId(loginUser.getCompany().getCompanyId());
+            dto.setUserId(loginUser.getUser().getUserId());
+            companyRechargeOrder = companyRechargeService.recharge(dto);
+        }catch (Exception e) {
+            logger.error("给公司充值失败",e);
+            return AjaxResult.error(e.getMessage());
+        }
+        return AjaxResult.success(companyRechargeOrder);
+    }
+
+    /**
+     * 查询订单
+     * @param orderNo 订单号
+     * @return AjaxResult
+     */
+    @GetMapping("/queryOrder")
+    public AjaxResult queryOrder(@RequestParam("orderNo") String orderNo) {
+        CompanyRechargeOrder order = companyRechargeService.queryOrder(orderNo);
+
+        return AjaxResult.success(order);
+    }
+
 
     /**
      * 新增充值

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

@@ -124,7 +124,7 @@ public class FsCourseTrafficLogController extends BaseController
     @GetMapping("/courseList")
     public R courseList()
     {
-        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList(null);
+        List<OptionsVO> optionsVOS = fsUserCourseMapper.selectFsUserCourseAllList();
         return R.ok().put("list", optionsVOS);
     }
 }

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

@@ -78,7 +78,7 @@ public class FsUserCourseController extends BaseController
     @GetMapping("/getAllList")
     public R getAllList()
     {
-        List<OptionsVO> list = fsUserCourseService.selectFsUserCourseAllList(null);
+        List<OptionsVO> list = fsUserCourseService.selectFsUserCourseAllList();
         return R.ok().put("data", list);
     }
 

+ 8 - 0
fs-company/src/main/java/com/fs/company/controller/pay/WxPayApiController.java

@@ -0,0 +1,8 @@
+package com.fs.company.controller.pay;
+
+
+import com.ijpay.wxpay.WxPayApiConfig;
+
+public abstract class WxPayApiController {
+	public abstract WxPayApiConfig getApiConfig();
+}

+ 189 - 0
fs-company/src/main/java/com/fs/company/controller/pay/WxPayController.java

@@ -0,0 +1,189 @@
+package com.fs.company.controller.pay;
+
+
+import com.fs.common.core.domain.R;
+import com.fs.common.utils.StringUtils;
+import com.fs.company.controller.pay.bean.WxPayBean;
+import com.fs.company.domain.CompanyRecharge;
+import com.fs.company.service.ICompanyRechargeService;
+import com.fs.core.config.WxPayProperties;
+import com.github.binarywang.wxpay.util.SignUtils;
+import com.ijpay.core.enums.SignType;
+import com.ijpay.core.enums.TradeType;
+import com.ijpay.core.kit.HttpKit;
+import com.ijpay.core.kit.IpKit;
+import com.ijpay.core.kit.WxPayKit;
+import com.ijpay.wxpay.WxPayApi;
+import com.ijpay.wxpay.WxPayApiConfig;
+import com.ijpay.wxpay.WxPayApiConfigKit;
+import com.ijpay.wxpay.model.UnifiedOrderModel;
+import io.swagger.annotations.ApiParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+@Controller
+@RequestMapping(value="/pay/wxPay")
+public class WxPayController extends WxPayApiController {
+
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    WxPayBean wxPayBean;
+
+    private String notifyUrl;
+    private String refundNotifyUrl;
+
+    @Autowired
+    ICompanyRechargeService rechargeService;
+
+    @Autowired
+    private WxPayProperties wxPayProperties;
+
+
+    @Override
+    public WxPayApiConfig getApiConfig() {
+        WxPayApiConfig apiConfig;
+
+        try {
+            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
+        } catch (Exception e) {
+            apiConfig = WxPayApiConfig.builder()
+                    .appId(wxPayBean.getAppId())
+                    .mchId(wxPayBean.getMchId())
+                    .partnerKey(wxPayBean.getPartnerKey())
+                    .certPath(wxPayBean.getCertPath())
+                    .domain(wxPayBean.getDomain())
+                    .build();
+        }
+        notifyUrl = apiConfig.getDomain().concat("/pay/wxPay/payNotify");
+        refundNotifyUrl = apiConfig.getDomain().concat("/pay/wxPay/refundNotify");
+        return apiConfig;
+    }
+    @GetMapping("/test")
+    @ResponseBody
+    public WxPayBean test() {
+        return wxPayBean;
+    }
+
+    @GetMapping(value="/qrPay")
+    @ResponseBody
+    public R qrPay(
+            @ApiParam(required = true, name = "orderNo", value = "订单ID") @RequestParam(value = "orderNo", required = false) String orderNo,
+            @ApiParam(required = true, name = "orderType", value = "订单类型 1 充值") @RequestParam(value = "orderType", required = false) Integer orderType,
+            HttpServletRequest request){
+        if(orderType.equals(1)){
+            CompanyRecharge recharge=rechargeService.selectCompanyRechargeByNo(orderNo);
+            if(recharge==null){
+                return R.error("充值订单不存在");
+            }
+            if(recharge.getStatus()!=0){
+                return R.error("此订单已支付");
+            }
+            Integer money= recharge.getMoney().multiply(new BigDecimal(100)).intValue();
+            String ip = IpKit.getRealIp(request);
+            if (StringUtils.isEmpty(ip)) {
+                ip = "127.0.0.1";
+            }
+            WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
+            Map<String, String> params = UnifiedOrderModel
+                    .builder()
+                    .appid(wxPayApiConfig.getAppId())
+                    .mch_id(wxPayApiConfig.getMchId())
+                    .nonce_str(WxPayKit.generateStr())
+                    .body("充值订单")
+                    .out_trade_no("recharge-"+recharge.getRechargeNo())
+                    .total_fee(money.toString())
+                    .spbill_create_ip(ip)
+                    .notify_url(notifyUrl)
+                    .trade_type(TradeType.NATIVE.getTradeType())
+                    .build()
+                    .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
+
+            String xmlResult = WxPayApi.pushOrder(false, params);
+            log.info("统一下单:" + xmlResult);
+
+            Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
+
+            String returnCode = result.get("return_code");
+            String returnMsg = result.get("return_msg");
+            System.out.println(returnMsg);
+            if (!WxPayKit.codeIsOk(returnCode)) {
+                return R.error("error:" + returnMsg);
+            }
+            String resultCode = result.get("result_code");
+            if (!WxPayKit.codeIsOk(resultCode)) {
+                return R.error("error:" + returnMsg);
+            }
+            //生成预付订单success
+            //生成预付订单success
+            String qrCodeUrl = result.get("code_url");
+//            String name = order.getOrderNo()+".png";
+//            String filePath = FSConfig.getUploadPath();
+//            boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
+//                    filePath +"/"+ File.separator + name);
+//            if (encode) {
+//                //在页面上显示
+//                order.setPayType(1);
+//                goodsOrderService.updateFsGoodsOrder(order);
+//                return R.ok().put("name",name);
+//            }
+            recharge.setPayType(1);
+            rechargeService.updateCompanyRecharge(recharge);
+            return R.ok().put("qr",qrCodeUrl);
+
+        }
+        return R.error("订单类型不正确");
+    }
+
+    @RequestMapping(value = "/payNotify",method={RequestMethod.POST, RequestMethod.GET})
+    @ResponseBody
+    public String payNotify(HttpServletRequest request) {
+        // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
+        String xmlMsg = HttpKit.readData(request);
+        log.info("支付通知 {}", xmlMsg);
+        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
+        String returnCode = params.get("return_code");
+        // 微信支付订单号
+        String transaction_id = params.get("transaction_id");
+        // 商户订单号
+        String out_trade_no = params.get("out_trade_no");
+        // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
+        // 注意此处签名方式需与统一下单的签名类型一致1
+        if (SignUtils.checkSign(params, String.valueOf(SignType.HMACSHA256), wxPayProperties.getMchKey())) {
+            if (WxPayKit.codeIsOk(returnCode)) {
+                // 更新订单信息
+                // 发送通知等
+                String[] order=out_trade_no.split("-");
+                R r;
+                if (order[0].equals("recharge")) {
+                    r = rechargeService.payNotify(order[1],transaction_id);
+                    if (r.get("code").equals(200)) {
+                        Map<String, String> xml = new HashMap<String, String>(2);
+                        xml.put("return_code", "SUCCESS");
+                        xml.put("return_msg", "OK");
+                        return WxPayKit.toXml(xml);
+
+                    } else {
+                        return null;
+                    }
+                }
+            }
+        }
+        return null;
+
+    }
+
+
+
+
+
+
+}

+ 98 - 0
fs-company/src/main/java/com/fs/company/controller/pay/bean/AliPayBean.java

@@ -0,0 +1,98 @@
+package com.fs.company.controller.pay.bean;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+@Component
+@PropertySource("classpath:/pay/alipay.properties")
+@ConfigurationProperties(prefix = "alipay")
+public class AliPayBean {
+    private String appId;
+    private String privateKey;
+    private String publicKey;
+    private String appCertPath;
+    private String aliPayCertPath;
+    private String aliPayRootCertPath;
+    private String serverUrl;
+    private String domain;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public String getAppCertPath() {
+        return appCertPath;
+    }
+
+    public void setAppCertPath(String appCertPath) {
+        this.appCertPath = appCertPath;
+    }
+
+    public String getAliPayCertPath() {
+        return aliPayCertPath;
+    }
+
+    public void setAliPayCertPath(String aliPayCertPath) {
+        this.aliPayCertPath = aliPayCertPath;
+    }
+
+    public String getAliPayRootCertPath() {
+        return aliPayRootCertPath;
+    }
+
+    public void setAliPayRootCertPath(String aliPayRootCertPath) {
+        this.aliPayRootCertPath = aliPayRootCertPath;
+    }
+
+    public String getServerUrl() {
+        return serverUrl;
+    }
+
+    public void setServerUrl(String serverUrl) {
+        this.serverUrl = serverUrl;
+    }
+
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String toString() {
+        return "AliPayBean{" +
+                "appId='" + appId + '\'' +
+                ", privateKey='" + privateKey + '\'' +
+                ", publicKey='" + publicKey + '\'' +
+                ", appCertPath='" + appCertPath + '\'' +
+                ", aliPayCertPath='" + aliPayCertPath + '\'' +
+                ", aliPayRootCertPath='" + aliPayRootCertPath + '\'' +
+                ", serverUrl='" + serverUrl + '\'' +
+                ", domain='" + domain + '\'' +
+                '}';
+    }
+}

+ 71 - 0
fs-company/src/main/java/com/fs/company/controller/pay/bean/WxPayBean.java

@@ -0,0 +1,71 @@
+package com.fs.company.controller.pay.bean;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+@Component
+@PropertySource("classpath:/pay/wxpay.properties")
+@ConfigurationProperties(prefix = "wxpay")
+public class WxPayBean {
+    private String appId;
+    private String appSecret;
+    private String mchId;
+    private String partnerKey;
+    private String certPath;
+    private String domain;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getAppSecret() {
+        return appSecret;
+    }
+
+    public void setAppSecret(String appSecret) {
+        this.appSecret = appSecret;
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId;
+    }
+
+    public String getPartnerKey() {
+        return partnerKey;
+    }
+
+    public void setPartnerKey(String partnerKey) {
+        this.partnerKey = partnerKey;
+    }
+
+    public String getCertPath() {
+        return certPath;
+    }
+
+    public void setCertPath(String certPath) {
+        this.certPath = certPath;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String toString() {
+        return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
+                + partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
+    }
+}

+ 106 - 0
fs-company/src/main/java/com/fs/company/controller/pay/bean/WxPayV3Bean.java

@@ -0,0 +1,106 @@
+package com.fs.company.controller.pay.bean;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+@Component
+@PropertySource("classpath:/pay/wxpay_v3.properties")
+@ConfigurationProperties(prefix = "v3")
+public class WxPayV3Bean {
+    private String appId;
+    private String keyPath;
+    private String certPath;
+    private String certP12Path;
+    private String platformCertPath;
+    private String mchId;
+    private String apiKey;
+    private String apiKey3;
+    private String domain;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getKeyPath() {
+        return keyPath;
+    }
+
+    public void setKeyPath(String keyPath) {
+        this.keyPath = keyPath;
+    }
+
+    public String getCertPath() {
+        return certPath;
+    }
+
+    public void setCertPath(String certPath) {
+        this.certPath = certPath;
+    }
+
+    public String getCertP12Path() {
+        return certP12Path;
+    }
+
+    public void setCertP12Path(String certP12Path) {
+        this.certP12Path = certP12Path;
+    }
+
+    public String getPlatformCertPath() {
+        return platformCertPath;
+    }
+
+    public void setPlatformCertPath(String platformCertPath) {
+        this.platformCertPath = platformCertPath;
+    }
+
+    public String getMchId() {
+        return mchId;
+    }
+
+    public void setMchId(String mchId) {
+        this.mchId = mchId;
+    }
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    public void setApiKey(String apiKey) {
+        this.apiKey = apiKey;
+    }
+
+    public String getApiKey3() {
+        return apiKey3;
+    }
+
+    public void setApiKey3(String apiKey3) {
+        this.apiKey3 = apiKey3;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    @Override
+    public String toString() {
+        return "WxPayV3Bean{" +
+                "keyPath='" + keyPath + '\'' +
+                ", certPath='" + certPath + '\'' +
+                ", certP12Path='" + certP12Path + '\'' +
+                ", platformCertPath='" + platformCertPath + '\'' +
+                ", mchId='" + mchId + '\'' +
+                ", apiKey='" + apiKey + '\'' +
+                ", apiKey3='" + apiKey3 + '\'' +
+                ", domain='" + domain + '\'' +
+                '}';
+    }
+}

+ 1 - 0
fs-company/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -119,6 +119,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/msg").anonymous()
                 .antMatchers("/common/getId**").anonymous()
                 .antMatchers("/common/uploadOSS**").anonymous()
+                .antMatchers("/pay/wxPay/payNotify**").anonymous()
                 .antMatchers("/common/uploadWang**").anonymous()
                 .antMatchers("/common/download**").anonymous()
                 .antMatchers("/common/download/resource**").anonymous()

+ 83 - 0
fs-service/src/main/java/com/fs/company/constant/PaymentStatus.java

@@ -0,0 +1,83 @@
+package com.fs.company.constant;
+
+import lombok.Getter;
+
+/**
+ * 支付状态枚举类
+ *
+ * 描述支付过程中可能的状态
+ */
+@Getter
+public enum PaymentStatus {
+
+    /**
+     * 支付创建,初始状态
+     */
+    CREATED(0, "创建"),
+
+    /**
+     * 支付处理中
+     */
+    PROCESSING(1, "处理中"),
+
+    /**
+     * 支付成功
+     */
+    SUCCESS(2, "支付成功"),
+
+    /**
+     * 支付失败
+     */
+    FAILED(3, "支付失败");
+
+    /**
+     * 状态码
+     * -- GETTER --
+     *  获取状态码
+     *
+     * @return 状态码
+
+     */
+    private final int code;
+
+    /**
+     * 状态描述
+     * -- GETTER --
+     *  获取状态描述
+     *
+     * @return 状态描述
+
+     */
+    private final String description;
+
+    /**
+     * 构造函数
+     *
+     * @param code 状态码
+     * @param description 状态描述
+     */
+    PaymentStatus(int code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    /**
+     * 根据状态码获取对应的枚举值
+     *
+     * @param code 状态码
+     * @return 对应的支付状态枚举,如果没找到则返回null
+     */
+    public static PaymentStatus getByCode(int code) {
+        for (PaymentStatus status : PaymentStatus.values()) {
+            if (status.getCode() == code) {
+                return status;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return code + ":" + description;
+    }
+}

+ 75 - 0
fs-service/src/main/java/com/fs/company/domain/CompanyRechargeOrder.java

@@ -0,0 +1,75 @@
+package com.fs.company.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 公司充值订单表
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CompanyRechargeOrder {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 订单号
+     */
+    private String orderNo;
+
+    /**
+     * 支付平台交易号
+     */
+    private String transactionId;
+
+    /**
+     * 支付方式:1-微信 2-支付宝 3-银行卡 4-其他
+     */
+    private Integer payType;
+
+    /**
+     * 支付金额
+     */
+    private BigDecimal payAmount;
+
+    private Long companyId;
+
+    private Long userId;
+
+    /**
+     * 支付状态:0-创建 1-处理中 2-支付成功 3-支付失败
+     */
+    private Integer payStatus;
+
+    /**
+     * 支付时间
+     */
+    private LocalDateTime paymentTime;
+
+    /**
+     * 回调内容
+     */
+    private String callbackContent;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    private String qrLink;
+}

+ 18 - 0
fs-service/src/main/java/com/fs/company/dto/CompBuySmsDTO.java

@@ -0,0 +1,18 @@
+package com.fs.company.dto;
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class CompBuySmsDTO implements Serializable {
+    /**
+     * 公司id
+     */
+    private String companyId;
+    /**
+     * 套餐id
+     */
+    private String packageId;
+}

+ 13 - 0
fs-service/src/main/java/com/fs/company/dto/CompanyIdAndUserDTO.java

@@ -0,0 +1,13 @@
+package com.fs.company.dto;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+@EqualsAndHashCode
+@Data
+public class CompanyIdAndUserDTO implements Serializable {
+    private Long companyId;
+    private Long companyUserId;
+}

+ 15 - 0
fs-service/src/main/java/com/fs/company/dto/RechargeDTO.java

@@ -0,0 +1,15 @@
+package com.fs.company.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class RechargeDTO {
+    /**
+     * 充值金额
+     */
+    private BigDecimal amount;
+    private Long companyId;
+    private Long userId;
+}

+ 74 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyRechargeOrderMapper.java

@@ -0,0 +1,74 @@
+package com.fs.company.mapper;
+
+import com.fs.company.domain.CompanyRechargeOrder;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+/**
+ * 公司充值订单表 Mapper
+ */
+@Mapper
+public interface CompanyRechargeOrderMapper {
+
+    /**
+     * 根据ID查询订单
+     */
+    @Select("SELECT * FROM company_recharge_order WHERE id = #{id}")
+    CompanyRechargeOrder selectById(Long id);
+
+    /**
+     * 根据订单号查询订单
+     */
+    @Select("SELECT * FROM company_recharge_order WHERE order_no = #{orderNo}")
+    CompanyRechargeOrder selectByOrderNo(String orderNo);
+
+    /**
+     * 根据交易号查询订单
+     */
+    @Select("SELECT * FROM company_recharge_order WHERE transaction_id = #{transactionId}")
+    CompanyRechargeOrder selectByTransactionId(String transactionId);
+
+    /**
+     * 查询所有订单
+     */
+    @Select("SELECT * FROM company_recharge_order")
+    List<CompanyRechargeOrder> selectAll();
+
+    /**
+     * 新增订单
+     */
+    @Insert("INSERT INTO company_recharge_order (order_no, transaction_id, pay_type, pay_amount, pay_status, payment_time, callback_content,company_id,user_id) " +
+            "VALUES (#{orderNo}, #{transactionId}, #{payType}, #{payAmount}, #{payStatus}, #{paymentTime}, #{callbackContent},#{companyId},#{userId})")
+    @Options(useGeneratedKeys = true, keyProperty = "id")
+    int insert(CompanyRechargeOrder order);
+
+    /**
+     * 更新订单
+     */
+    @Update("UPDATE company_recharge_order SET " +
+            "transaction_id = #{transactionId}, " +
+            "pay_type = #{payType}, " +
+            "pay_amount = #{payAmount}, " +
+            "pay_status = #{payStatus}, " +
+            "payment_time = #{paymentTime}, " +
+            "callback_content = #{callbackContent} " +
+            "WHERE order_no = #{orderNo}")
+    int updateByOrderNo(CompanyRechargeOrder order);
+
+    /**
+     * 更新订单支付状态
+     */
+    @Update("UPDATE company_recharge_order SET " +
+            "pay_status = #{payStatus}, " +
+            "payment_time = #{paymentTime}, " +
+            "transaction_id = #{transactionId}, " +
+            "callback_content = #{callbackContent} " +
+            "WHERE order_no = #{orderNo}")
+    int updatePayStatus(CompanyRechargeOrder order);
+
+    @Select("SELECT * FROM company_recharge_order " +
+            "WHERE pay_status = 1 " +
+            "AND create_time <= DATE_SUB(NOW(), INTERVAL 2 HOUR)")
+    List<CompanyRechargeOrder> queryOverdueOrder();
+}

+ 16 - 0
fs-service/src/main/java/com/fs/company/service/CompanyRechargeOrderService.java

@@ -0,0 +1,16 @@
+package com.fs.company.service;
+
+import com.fs.company.domain.CompanyRechargeOrder;
+
+import java.util.List;
+
+public interface CompanyRechargeOrderService {
+
+    List<CompanyRechargeOrder> queryOverdueOrder();
+
+    void autoClosedOrder();
+
+    CompanyRechargeOrder createOrder(CompanyRechargeOrder order) throws Exception;
+
+    CompanyRechargeOrder queryOrder(String orderNo);
+}

+ 17 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyRechargeService.java

@@ -5,6 +5,8 @@ import java.util.List;
 
 import com.fs.common.core.domain.R;
 import com.fs.company.domain.CompanyRecharge;
+import com.fs.company.domain.CompanyRechargeOrder;
+import com.fs.company.dto.RechargeDTO;
 import com.fs.company.vo.CompanyRechargeExportVO;
 import com.fs.company.vo.CompanyRechargeVO;
 
@@ -72,6 +74,7 @@ public interface ICompanyRechargeService
     CompanyRecharge selectCompanyRechargeByNo(String s);
 
     R payNotify(CompanyRecharge recharge);
+    R payNotify(String orderNo,String transactionId);
 
     BigDecimal selectCompanyRechargeMoney();
 
@@ -82,4 +85,18 @@ public interface ICompanyRechargeService
      * @return 充值集合
      */
     List<CompanyRechargeExportVO> selectCompanyRechargeExportList(CompanyRecharge companyRecharge);
+
+    /**
+     * 充值
+     * @param dto 参数
+     * @return 地址
+     */
+    CompanyRechargeOrder recharge(RechargeDTO dto) throws Exception;
+
+    /**
+     * 查询订单
+     * @param orderNo 订单号
+     * @return CompanyRechargeOrder
+     */
+    CompanyRechargeOrder queryOrder(String orderNo);
 }

+ 100 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyRechargeOrderServiceImpl.java

@@ -0,0 +1,100 @@
+package com.fs.company.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.fs.common.utils.IpUtil;
+import com.fs.company.constant.PaymentStatus;
+import com.fs.company.domain.CompanyRechargeOrder;
+import com.fs.company.mapper.CompanyRechargeOrderMapper;
+import com.fs.company.service.CompanyRechargeOrderService;
+import com.fs.core.config.WxPayProperties;
+import com.fs.wx.utils.OrderUtils;
+import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.constant.WxPayConstants;
+import com.github.binarywang.wxpay.service.WxPayService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Service
+public class CompanyRechargeOrderServiceImpl implements CompanyRechargeOrderService {
+    @Autowired
+    private CompanyRechargeOrderMapper companyRechargeOrderMapper;
+
+    @Autowired
+    private WxPayProperties wxPayProperties;
+
+    @Autowired
+    private WxPayService wxPayService;
+    @Override
+    public List<CompanyRechargeOrder> queryOverdueOrder() {
+        return companyRechargeOrderMapper.queryOverdueOrder();
+    }
+
+    /**
+     * 自动关闭超时订单号
+     */
+    @Override
+    public void autoClosedOrder(){
+        List<CompanyRechargeOrder> companyRechargeOrders = companyRechargeOrderMapper.queryOverdueOrder();
+        for (CompanyRechargeOrder order : companyRechargeOrders) {
+            order.setPayStatus(PaymentStatus.FAILED.getCode());
+            companyRechargeOrderMapper.updateByOrderNo(order);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
+    public CompanyRechargeOrder createOrder(CompanyRechargeOrder order) throws Exception{
+
+        WxPayConfig payConfig = new WxPayConfig();
+        payConfig.setAppId(wxPayProperties.getAppId());
+        payConfig.setMchId(wxPayProperties.getMchId());
+        payConfig.setMchKey(wxPayProperties.getMchKey());
+        payConfig.setPrivateKeyPath(wxPayProperties.getPrivateKeyPath());
+        payConfig.setPrivateCertPath(wxPayProperties.getPrivateCertPath());
+        payConfig.setCertSerialNo(wxPayProperties.getCertSerialNo());
+        payConfig.setUseSandboxEnv(false);
+        payConfig.setSignType(WxPayConstants.SignType.HMAC_SHA256);
+
+        wxPayService.setConfig(payConfig);
+
+        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
+        String orderNo = OrderUtils.getOrderNo();
+        orderRequest.setBody("公司余额充值");
+        orderRequest.setOutTradeNo("recharge-"+orderNo);
+        orderRequest.setTotalFee(order.getPayAmount().multiply(BigDecimal.valueOf(100)).intValue());
+        orderRequest.setSpbillCreateIp(IpUtil.getLocalhostIp());
+        orderRequest.setNotifyUrl(wxPayProperties.getNativeNotifyUrl());
+        orderRequest.setTradeType(WxPayConstants.TradeType.NATIVE);
+        orderRequest.setProductId(String.valueOf(order.getId()));
+
+
+        WxPayNativeOrderResult wxOrder = wxPayService.createOrder(orderRequest);
+
+
+        order.setOrderNo(orderNo);
+        order.setPayType(1);
+        order.setPayStatus(1);
+        order.setCreateTime(LocalDateTime.now());
+        order.setCallbackContent(JSON.toJSONString(wxOrder));
+        order.setQrLink(wxOrder.getCodeUrl());
+
+        companyRechargeOrderMapper.insert(order);
+
+        return order;
+    }
+
+    @Override
+    public CompanyRechargeOrder queryOrder(String orderNo) {
+        return companyRechargeOrderMapper.selectByOrderNo(orderNo);
+    }
+
+
+}

+ 61 - 3
fs-service/src/main/java/com/fs/company/service/impl/CompanyRechargeServiceImpl.java

@@ -4,19 +4,27 @@ import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.company.constant.PaymentStatus;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyMoneyLogs;
+import com.fs.company.domain.CompanyRechargeOrder;
+import com.fs.company.dto.RechargeDTO;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
+import com.fs.company.mapper.CompanyRechargeOrderMapper;
+import com.fs.company.service.CompanyRechargeOrderService;
 import com.fs.company.vo.CompanyRechargeExportVO;
 import com.fs.company.vo.CompanyRechargeVO;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.company.mapper.CompanyRechargeMapper;
 import com.fs.company.domain.CompanyRecharge;
 import com.fs.company.service.ICompanyRechargeService;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -25,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
  * @author fs
  * @date 2021-10-04
  */
+@Slf4j
 @Service
 public class CompanyRechargeServiceImpl implements ICompanyRechargeService
 {
@@ -34,6 +43,8 @@ public class CompanyRechargeServiceImpl implements ICompanyRechargeService
     private CompanyMoneyLogsMapper moneyLogsMapper;
     @Autowired
     private CompanyMapper companyMapper;
+    @Autowired
+    private CompanyRechargeOrderService companyRechargeOrderService;
     /**
      * 查询充值
      *
@@ -120,13 +131,13 @@ public class CompanyRechargeServiceImpl implements ICompanyRechargeService
     }
 
     @Override
-    @Transactional
+    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
     public R payNotify(CompanyRecharge recharge) {
         //修改状态
         recharge.setPayTime(new Date());
         recharge.setStatus(1);
         companyRechargeMapper.updateCompanyRecharge(recharge);
-        Company company=companyMapper.selectCompanyById(recharge.getCompanyId());
+        Company company=companyMapper.selectCompanyByIdForUpdate(recharge.getCompanyId());
         company.setMoney(company.getMoney().add(recharge.getMoney()));
         //写入日志
         CompanyMoneyLogs log=new CompanyMoneyLogs();
@@ -134,7 +145,7 @@ public class CompanyRechargeServiceImpl implements ICompanyRechargeService
         log.setMoney(recharge.getMoney());
         log.setRemark("充值金额:"+recharge.getMoney()+"元");
         log.setCreateTime(new Date());
-        log.setLogsType(1);
+        log.setLogsType(3);
         log.setBalance(company.getMoney());
         moneyLogsMapper.insertCompanyMoneyLogs(log);
         //修改余额
@@ -144,6 +155,38 @@ public class CompanyRechargeServiceImpl implements ICompanyRechargeService
         return R.ok();
     }
 
+    @Autowired
+    private CompanyRechargeOrderMapper companyRechargeOrderMapper;
+
+    @Override
+    public synchronized R payNotify(String orderNo,String transactionId) {
+        CompanyRechargeOrder order = companyRechargeOrderMapper.selectByOrderNo(orderNo);
+
+        if(ObjectUtil.equal(order.getPayStatus(), PaymentStatus.SUCCESS.getCode())){
+            log.info("订单已支付!重复付款 {} {}", orderNo,transactionId);
+            R.ok();
+        }
+        //修改状态
+        order.setPayStatus(PaymentStatus.SUCCESS.getCode());
+        order.setTransactionId(transactionId);
+        companyRechargeOrderMapper.updateByOrderNo(order);
+
+        Company company=companyMapper.selectCompanyByIdForUpdate(order.getCompanyId());
+        //写入日志
+        CompanyMoneyLogs log=new CompanyMoneyLogs();
+        log.setCompanyId(order.getCompanyId());
+        log.setMoney(order.getPayAmount());
+        log.setRemark("充值金额:"+order.getPayAmount()+"元");
+        log.setCreateTime(new Date());
+        log.setLogsType(3);
+        log.setBalance(company.getMoney());
+        moneyLogsMapper.insertCompanyMoneyLogs(log);
+        //修改余额
+        company.setMoney(company.getMoney().add(order.getPayAmount()));
+        companyMapper.updateCompany(company);
+        return R.ok();
+    }
+
     @Override
     public BigDecimal selectCompanyRechargeMoney() {
         return companyRechargeMapper.selectCompanyRechargeMoney();
@@ -153,4 +196,19 @@ public class CompanyRechargeServiceImpl implements ICompanyRechargeService
     public List<CompanyRechargeExportVO> selectCompanyRechargeExportList(CompanyRecharge companyRecharge) {
         return companyRechargeMapper.selectCompanyRechargeExportList(companyRecharge);
     }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Throwable.class)
+    public CompanyRechargeOrder recharge(RechargeDTO dto) throws Exception {
+        CompanyRechargeOrder order = new CompanyRechargeOrder();
+        order.setPayAmount(dto.getAmount());
+        order.setCompanyId(dto.getCompanyId());
+        order.setUserId(dto.getUserId());
+        return companyRechargeOrderService.createOrder(order);
+    }
+
+    @Override
+    public CompanyRechargeOrder queryOrder(String orderNo) {
+        return companyRechargeOrderService.queryOrder(orderNo);
+    }
 }

+ 8 - 52
fs-service/src/main/java/com/fs/core/config/WxPayProperties.java

@@ -1,7 +1,9 @@
 package com.fs.core.config;
 
+import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
+@Data
 @ConfigurationProperties(prefix = "wx.pay")
 public class WxPayProperties {
   /**
@@ -19,6 +21,8 @@ public class WxPayProperties {
    */
   private String mchKey;
 
+  private String v3Key;
+
   /**
    * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
    */
@@ -36,59 +40,11 @@ public class WxPayProperties {
 
   private String notifyUrl;
 
-  public String getAppId() {
-    return appId;
-  }
-
-  public void setAppId(String appId) {
-    this.appId = appId;
-  }
-
-  public String getMchId() {
-    return mchId;
-  }
-
-  public void setMchId(String mchId) {
-    this.mchId = mchId;
-  }
-
-  public String getMchKey() {
-    return mchKey;
-  }
-
-  public void setMchKey(String mchKey) {
-    this.mchKey = mchKey;
-  }
-
-  public String getSubAppId() {
-    return subAppId;
-  }
-
-  public void setSubAppId(String subAppId) {
-    this.subAppId = subAppId;
-  }
-
-  public String getSubMchId() {
-    return subMchId;
-  }
-
-  public void setSubMchId(String subMchId) {
-    this.subMchId = subMchId;
-  }
-
-  public String getKeyPath() {
-    return keyPath;
-  }
+  private String privateKeyPath;
 
-  public void setKeyPath(String keyPath) {
-    this.keyPath = keyPath;
-  }
+  private String privateCertPath;
 
-  public String getNotifyUrl() {
-    return notifyUrl;
-  }
+  private String certSerialNo;
 
-  public void setNotifyUrl(String notifyUrl) {
-    this.notifyUrl = notifyUrl;
-  }
+  private String nativeNotifyUrl;
 }

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

@@ -39,6 +39,7 @@ public class CourseConfig implements Serializable {
     private String sidebarImageUrl;//侧边栏公共图
     private Integer delayStart;
     private Integer delayEnd;
+    private Integer isNegative;//是否为负数 0、不允许,1、允许
 
     /**
      * 小程序授权头像昵称方式(目前仅会员看课有效)

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

@@ -49,7 +49,7 @@ public class FsCourseRedPacketLog extends BaseEntity
     @Excel(name = "分享企微userid")
     private String qwUserId;
 
-    private Integer status;//状态 0 发送中  1  已发送   2
+    private Integer status;//状态 0 发送中  1  已发送 ,2、待发送
 
 
     private Long watchLogId;//观看记录 id

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

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

+ 2 - 5
fs-service/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java

@@ -140,9 +140,6 @@ 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>" +
@@ -231,8 +228,8 @@ public interface FsUserCourseMapper
     List<FsUserCourseListPVO> selectFsUserCourseListCompanyPVO(@Param("maps")FsUserCourseParam fsUserCourse);
 
 
-
-    List<OptionsVO> selectFsUserCourseAllList(@Param("userId") Long userId);
+    @Select("select course_id dict_value, course_name dict_label,img_url dict_imgUrl  from fs_user_course where is_del = 0 and is_private = 1 ")
+    List<OptionsVO> selectFsUserCourseAllList();
 
     @Select("select course_id dict_value, course_name dict_label,img_url dict_imgUrl  from fs_user_course where is_del = 0 and is_private = 1" +
             " and find_in_set(#{companyId},company_ids) ")

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

@@ -85,9 +85,6 @@ 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);

+ 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, Long userId);
+    String importData(List<FsCourseQuestionBankImportDTO> list, String nickName);
 
     /**
      * 根据ID查询题目

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

@@ -82,4 +82,5 @@ public interface IFsCourseRedPacketLogService
 
     R retryCourseRedPacketLog(Long[] logIds);
 
+    void sendRedPacketBf();
 }

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

@@ -85,7 +85,7 @@ public interface IFsUserCourseService
 
     List<FsUserCourseListUVO> selectFsUserCourseListUVO(FsUserCourseListUParam param);
 
-    List<OptionsVO> selectFsUserCourseAllList(Long userId);
+    List<OptionsVO> selectFsUserCourseAllList();
 
     List<FsUserCourseListPVO> selectFsUserCourseListPVO(FsUserCourse param);
 
@@ -123,7 +123,7 @@ public interface IFsUserCourseService
 
     String createUserImageQR(@NotNull(message = "链接不能为空") String realLink, String backgroundImagePath, InputStream inputStream, String png, @NotNull(message = "销售id不能为空") Long companyUserId) throws Exception;
 
-    int copyFsUserCourse(Long courseId, Long userId);
+    int copyFsUserCourse(Long courseId);
 
     List<FsUserCourseVideoAppletVO> selectFsUserCourseVideoApplet();
 

+ 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,Long userId);
+    void add(FsUserCourseTrainingCampDTO params);
     /**
      * 删除训练营
      * @param ids   ids

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

@@ -36,7 +36,6 @@ public interface IFsUserCourseVideoService
      * @return 课堂视频
      */
     public FsUserCourseVideo selectFsUserCourseVideoByVideoId(Long videoId);
-    public FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId,Long userId);
 
     /**
      * 查询课堂视频列表

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

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

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

@@ -5,6 +5,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
@@ -12,6 +13,7 @@ import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyMoneyLogs;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyMoneyLogsMapper;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.param.FsCourseRedPacketLogParam;
@@ -20,7 +22,10 @@ import com.fs.his.domain.FsUser;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.param.WxSendRedPacketParam;
 import com.fs.his.service.IFsStorePaymentService;
+import com.fs.system.service.ISysConfigService;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
@@ -37,10 +42,14 @@ import org.springframework.transaction.annotation.Transactional;
 @Service
 public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogService
 {
+    private static final Logger logger = LoggerFactory.getLogger(FsCourseRedPacketLogServiceImpl.class);
     @Autowired
     private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
     @Autowired
     private CompanyMapper companyMapper;
+
+    @Autowired
+    private ISysConfigService configService;
     /**
      * 查询短链课程看课记录
      *
@@ -236,4 +245,137 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
         return R.ok("成功:"+suc+" 失败:"+err);
     }
 
+    @Override
+    public void sendRedPacketBf() {
+        try {
+            logger.info("【红包发放】开始执行红包发放任务");
+
+            // 初始化查询对象
+            FsCourseRedPacketLog query = new FsCourseRedPacketLog();
+            query.setStatus(2); // 状态2表示待处理红包
+
+            // 获取红包配置
+            String json = configService.selectConfigByKey("course.config");
+            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+            logger.info("【红包发放】当前红包发放模式:{}", config.getRedPacketMode());
+
+            // 获取待处理红包列表
+            List<FsCourseRedPacketLog> pendingPackets = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogList(query);
+            if (pendingPackets == null || pendingPackets.isEmpty()) {
+                logger.info("【红包发放】没有待处理的红包记录");
+                return;
+            }
+
+            logger.info("【红包发放】共发现{}条待处理红包记录", pendingPackets.size());
+
+            // 处理每条红包记录
+            for (FsCourseRedPacketLog redPacket : pendingPackets) {
+                try {
+                    logger.info("【红包处理】开始处理红包记录ID:{},用户ID:{},金额:{}元",
+                            redPacket.getLogId(), redPacket.getUserId(), redPacket.getAmount());
+
+                    processRedPacket(redPacket, config);
+                } catch (Exception e) {
+                    logger.error("【红包处理】处理红包记录ID:{}时发生异常", redPacket.getLogId(), e);
+                    // 即使一条记录失败也继续处理下一条
+                }
+            }
+
+            logger.info("【红包发放】红包发放任务执行完成");
+        } catch (Exception e) {
+            logger.error("【红包发放】红包发放任务执行过程中发生未预期异常", e);
+        }
+    }
+
+    private void processRedPacket(FsCourseRedPacketLog redPacket, CourseConfig config) {
+        // 获取用户信息
+        FsUser user = fsUserMapper.selectFsUserByUserId(redPacket.getUserId());
+        if (user == null || user.getMpOpenId() == null) {
+            logger.error("【红包处理】错误:未找到用户ID:{}或用户缺少openId", redPacket.getUserId());
+            return;
+        }
+
+        logger.info("【红包处理】准备为用户{}发放红包,openId:{}", user.getUserId(), user.getMpOpenId());
+
+        // 准备红包参数
+        WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
+        packetParam.setOpenId(user.getMpOpenId());
+        packetParam.setAmount(redPacket.getAmount());
+        packetParam.setSource(2);
+        packetParam.setAppId(redPacket.getAppId());
+        packetParam.setRedPacketMode(config.getRedPacketMode());
+        packetParam.setCompanyId(redPacket.getCompanyId());
+
+        // 处理企业资金(使用悲观锁)
+        Company company = companyMapper.selectCompanyByIdForUpdate(redPacket.getCompanyId());
+        if (company == null) {
+            logger.error("【红包处理】错误:未找到企业ID:{}", redPacket.getCompanyId());
+            return;
+        }
+
+        BigDecimal remainingBalance = company.getMoney().subtract(redPacket.getAmount());
+        if (remainingBalance.compareTo(BigDecimal.ZERO) < 0) {
+            logger.warn("【红包处理】企业{}余额不足(当前余额:{}元,需要扣除:{}元)",
+                    company.getCompanyId(), company.getMoney(), redPacket.getAmount());
+            return;
+        }
+
+        logger.info("【红包处理】企业{}当前余额:{}元,发放后余额:{}元",
+                company.getCompanyId(), company.getMoney(), remainingBalance);
+
+        // 发送红包
+        R sendRedPacketResult = paymentService.sendRedPacket(packetParam);
+        if (sendRedPacketResult == null) {
+            logger.error("【红包处理】红包接口返回空结果");
+            return;
+        }
+
+        if (!sendRedPacketResult.get("code").equals(200)) {
+            logger.error("【红包处理】红包发放失败,错误码:{},错误信息:{}",
+                    sendRedPacketResult.get("code"), sendRedPacketResult.get("msg"));
+            return;
+        }
+
+        // 处理成功结果
+        logger.info("【红包处理】红包发放成功");
+
+        // 更新红包记录
+        if (sendRedPacketResult.get("isNew").equals(1)) {
+            TransferBillsResult transferBillsResult = (TransferBillsResult)sendRedPacketResult.get("data");
+            redPacket.setResult(JSON.toJSONString(sendRedPacketResult));
+            redPacket.setOutBatchNo(transferBillsResult.getOutBillNo());
+            logger.info("【红包处理】新批次红包,批次号:{}", transferBillsResult.getOutBillNo());
+        } else {
+            redPacket.setOutBatchNo(sendRedPacketResult.get("orderCode").toString());
+            logger.info("【红包处理】已有批次红包,订单号:{}", redPacket.getOutBatchNo());
+        }
+
+        fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(redPacket);
+
+        // 更新观看记录
+        FsCourseWatchLog watchLog = courseWatchLogMapper.selectFsCourseWatchLogByLogId(redPacket.getLogId());
+        if (watchLog != null) {
+            watchLog.setRewardType(config.getRewardType());
+            courseWatchLogMapper.updateFsCourseWatchLog(watchLog);
+            logger.info("【红包处理】更新观看记录{}的奖励类型为{}", watchLog.getLogId(), config.getRewardType());
+        }
+
+        // 更新企业余额
+        company.setMoney(remainingBalance);
+        companyMapper.updateCompany(company);
+
+        // 记录资金流水
+        CompanyMoneyLogs moneyLog = new CompanyMoneyLogs();
+        moneyLog.setCompanyId(company.getCompanyId());
+        moneyLog.setRemark("扣除红包金额");
+        moneyLog.setMoney(redPacket.getAmount().multiply(new BigDecimal(-1)));
+        moneyLog.setLogsType(15);
+        moneyLog.setBalance(company.getMoney());
+        moneyLog.setCreateTime(new Date());
+        moneyLogsMapper.insertCompanyMoneyLogs(moneyLog);
+
+        logger.info("【红包处理】企业资金流水记录成功,企业ID:{},变动金额:{}元",
+                company.getCompanyId(), moneyLog.getMoney());
+    }
+
 }

+ 3 - 5
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -277,8 +277,8 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
     }
 
     @Override
-    public List<OptionsVO> selectFsUserCourseAllList(Long userId) {
-        return fsUserCourseMapper.selectFsUserCourseAllList(userId);
+    public List<OptionsVO> selectFsUserCourseAllList() {
+        return fsUserCourseMapper.selectFsUserCourseAllList();
     }
 
 
@@ -664,11 +664,10 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
 
     @Override
     @Transactional(rollbackFor = Exception.class) // 显式声明事务
-    public int copyFsUserCourse(Long courseId, Long userId) {
+    public int copyFsUserCourse(Long courseId) {
         FsUserCourse fsUserCourse = fsUserCourseService.selectFsUserCourseByCourseId(courseId);
         if(fsUserCourse != null){
             fsUserCourse.setCourseId(null);
-            fsUserCourse.setUserId(userId);
             fsUserCourseService.insertFsUserCourse(fsUserCourse);
             Long newCourseId = fsUserCourse.getCourseId();
 
@@ -678,7 +677,6 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
 
             FsUserCourseVideo fsUserCourseVideo = new FsUserCourseVideo();
             fsUserCourseVideo.setCourseId(courseId);
-            fsUserCourseVideo.setUserId(userId);
             List<FsUserCourseVideo> list = fsUserCourseVideoService.selectFsUserCourseVideoListByCourseId(fsUserCourseVideo);
             for (FsUserCourseVideo courseVideo : list) {
                 courseVideo.setVideoId(null);

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

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

+ 70 - 27
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
@@ -214,28 +215,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         return fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
     }
 
-    @Override
-    public FsUserCourseVideoQVO selectFsUserCourseVideoByVideoIdVO(Long videoId,Long userId) {
-        FsUserCourseVideoQVO fsUserCourseVideoQVO=new FsUserCourseVideoQVO();
-        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoIdAndUserId(videoId,userId);
-
-        BeanCopyUtils.copy(courseVideo,fsUserCourseVideoQVO);
-        if (courseVideo.getRedPacketMoney()!=null){
-            fsUserCourseVideoQVO.setRedPacketMoney(courseVideo.getRedPacketMoney().toString());
-        }
-        if (StringUtils.isNotEmpty(courseVideo.getQuestionBankId())){
-            List<FsCourseQuestionBank> fsCourseQuestionBanks = courseQuestionBankMapper.selectFsCourseQuestionBankByIdVO(courseVideo.getQuestionBankId().split(","));
-            fsUserCourseVideoQVO.setQuestionBankList(fsCourseQuestionBanks);
-        }
-        //返回课程关联的拍商品
-        if(courseVideo.getIsProduct() != null && courseVideo.getIsProduct() == 1 && courseVideo.getProductId() != null){
-            FsCourseProduct courseProduct = courseProductMapper.selectFsCourseProductById(courseVideo.getProductId());
-            List<FsCourseProduct> courseProducts = Arrays.asList(courseProduct);
-            fsUserCourseVideoQVO.setCourseProducts(courseProducts);
-        }
-        return fsUserCourseVideoQVO;
-    }
-
     /**
      * 查询课堂视频列表
      *
@@ -902,14 +881,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (log.getRewardType() != null) {
             FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
             if(packetLog != null && packetLog.getStatus() == 1) {
-                return R.error("奖励已发放");
+                return R.error("已领取该课程奖励,不可重复领取!");
             }
             if(packetLog != null && packetLog.getStatus() == 0) {
                 if(StringUtils.isNotEmpty(packetLog.getResult())){
                     R r = JSON.parseObject(packetLog.getResult(), R.class);
                     return r;
                 } else {
-                    return R.error("奖励已发放");
+                    return R.error("操作频繁,请稍后再试!");
                 }
             }
             if(packetLog != null && packetLog.getStatus() == 2) {
@@ -950,14 +929,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if (log.getRewardType() != null) {
             FsCourseRedPacketLog fsCourseRedPacketLog = redPacketLogMapper.selectUserFsCourseRedPacketLog(param.getVideoId(), param.getUserId(),param.getPeriodId());
             if(fsCourseRedPacketLog != null && fsCourseRedPacketLog.getStatus() == 1) {
-                return R.error("奖励已发放");
+                return R.error("已领取该课程奖励,不可重复领取!");
             }
             if(fsCourseRedPacketLog != null && fsCourseRedPacketLog.getStatus() == 0) {
                 if(StringUtils.isNotEmpty(fsCourseRedPacketLog.getResult())){
                     R r = JSON.parseObject(fsCourseRedPacketLog.getResult(), R.class);
                     return r;
                 } else {
-                    return R.error();
+                    return R.error("操作频繁,请稍后再试!");
                 }
             }
         }
@@ -1185,6 +1164,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);
+        }
         //2025.6.19 红包金额为0的时候
         if (amount.compareTo(BigDecimal.ZERO)>0){
 
@@ -1197,13 +1179,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 redPacketLog.setCompanyId(param.getCompanyId());
                 redPacketLog.setUserId(param.getUserId());
                 redPacketLog.setVideoId(param.getVideoId());
-                redPacketLog.setStatus(2);
+                redPacketLog.setStatus(0);
                 redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
                 redPacketLog.setCompanyUserId(param.getCompanyUserId());
                 redPacketLog.setCreateTime(new Date());
                 redPacketLog.setAmount(amount);
                 redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
                 redPacketLog.setPeriodId(param.getPeriodId());
+                redPacketLog.setAppId(param.getAppId());
                 redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
                 return R.error("销售公司余额不足");
             }
@@ -1232,6 +1215,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
                 redPacketLog.setAmount(amount);
                 redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
                 redPacketLog.setPeriodId(param.getPeriodId());
+                redPacketLog.setAppId(param.getAppId());
                 redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
 
                 // 更新观看记录的奖励类型
@@ -1268,6 +1252,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             redPacketLog.setAmount(BigDecimal.ZERO);
             redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
             redPacketLog.setPeriodId(param.getPeriodId());
+            redPacketLog.setAppId(param.getAppId());
             redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
 
             // 更新观看记录的奖励类型
@@ -1280,6 +1265,64 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     }
 
+    /**
+     * 直接发送奖励
+     *
+     * @param config
+     * @param packetParam
+     * @param param
+     * @param amount
+     * @param log
+     * @return
+     */
+    private R processRedPacket(CourseConfig config, WxSendRedPacketParam packetParam, FsCourseSendRewardUParam param, BigDecimal amount, FsCourseWatchLog log) {
+        R sendRedPacket = paymentService.sendRedPacket(packetParam);
+
+        if (!sendRedPacket.get("code").equals(200)) {
+            return R.error("奖励发送失败,请联系客服");
+        }
+
+        createRedPacketLog(sendRedPacket, param, amount, log);
+        updateWatchLogRewardType(log, config);
+
+        return sendRedPacket;
+    }
+
+    private void createRedPacketLog(R sendRedPacket, FsCourseSendRewardUParam param, BigDecimal amount, FsCourseWatchLog log) {
+        FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
+
+        // Set common fields
+        redPacketLog.setCourseId(param.getCourseId());
+        redPacketLog.setCompanyId(param.getCompanyId());
+        redPacketLog.setUserId(param.getUserId());
+        redPacketLog.setVideoId(param.getVideoId());
+        redPacketLog.setStatus(0);
+        redPacketLog.setQwUserId(param.getQwUserId());
+        redPacketLog.setCompanyUserId(param.getCompanyUserId());
+        redPacketLog.setCreateTime(new Date());
+        redPacketLog.setAmount(amount);
+        redPacketLog.setWatchLogId(log != null ? log.getLogId() : null);
+        redPacketLog.setPeriodId(param.getPeriodId());
+        redPacketLog.setAppId(param.getAppId());
+
+        // Set batch number based on isNew flag
+        if (sendRedPacket.get("isNew").equals(1)) {
+            TransferBillsResult transferBillsResult = (TransferBillsResult) sendRedPacket.get("data");
+            redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
+            redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
+        } else {
+            redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
+        }
+
+        redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
+    }
+
+    private void updateWatchLogRewardType(FsCourseWatchLog log, CourseConfig config) {
+        if (log != null) {
+            log.setRewardType(config.getRewardType());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
+        }
+    }
     /**
      * 获取用户openId
      *

+ 12 - 0
fs-service/src/main/java/com/fs/statis/domain/FsStatisQwWatch.java

@@ -187,4 +187,16 @@ public class FsStatisQwWatch {
      */
     @Excel(name = "完课率")
     private BigDecimal finishedRate;
+
+    /**
+     * 流量数
+     */
+    @Excel(name = "流量数")
+    private Long trafficSum;
+
+    /**
+     * 注册数
+     */
+    @Excel(name = "注册数")
+    private Long regNum;
 }

+ 44 - 0
fs-service/src/main/java/com/fs/wx/utils/OrderUtils.java

@@ -0,0 +1,44 @@
+package com.fs.wx.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public class OrderUtils extends Thread {
+    private static long orderNum = 0L;
+    private static String date ;
+
+    public static void main(String[] args) throws InterruptedException {
+        for (int i = 0; i < 10000; i++) {
+            System.out.println(OrderUtils.getOrderNo());
+            Thread.sleep(1000);
+        }
+    }
+
+    /**
+     * 生成订单编号
+     * @return
+     */
+    public static synchronized String getOrderNo() {
+        String str = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        if(date==null||!date.equals(str)){
+            date = str;
+            orderNum  = 0L;
+        }
+        orderNum ++;
+        long orderNo = Long.parseLong((date)) * 10000;
+        orderNo += orderNum;
+        return orderNo+"";
+    }
+
+    public static synchronized String genUserCode() {
+        String year = new SimpleDateFormat("yy").format(new Date());
+        String day = String.format("%tj", new Date());
+        double random = Math.random() * 1000;
+        int intRandom = Double.valueOf(random).intValue();
+        String verifyCode = year + day + intRandom;
+        return verifyCode;
+    }
+
+
+}

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

@@ -79,7 +79,8 @@ cloud_host:
 headerImg:
   imgUrl: https://yztcourse-1325300895.cos.ap-guangzhou.myqcloud.com/yztcourse/20250523/e04871a98cc84be39a7f60c084698e21.jpg
 ipad:
-  ipadUrl: http://ipad.cdwjyyh.com
+  ipadUrl:
+  aiApi:
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:

+ 142 - 0
fs-service/src/main/resources/application-druid-kyt-test.yml

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

+ 3 - 0
fs-service/src/main/resources/application-druid-kyt.yml

@@ -137,3 +137,6 @@ rocketmq:
     group: test-group
     access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
     secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+openIM:
+  secret: op
+  userID: im

+ 12 - 0
fs-service/src/main/resources/application-druid-sxjz.yml

@@ -146,3 +146,15 @@ rocketmq:
         group: voice-group
         access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
         secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+
+# token配置
+token:
+    # 令牌自定义标识
+    header: Authorization
+    # 令牌密钥
+    secret: abcdefghijklmnopqrstuvwxyz
+    # 令牌有效期(默认30分钟)
+    expireTime: 180
+openIM:
+    secret: openIM123
+    userID: imAdmin

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

@@ -26,7 +26,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <where>
             <if test="title != null  and title != ''"> and title like concat('%', #{title}, '%') </if>
             <if test="sort != null "> and sort = #{sort}</if>
-            <if test="userId != null "> and user_id = #{userId}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="questionType != null "> and question_type = #{questionType}</if>
             <if test="questionSubType != null "> and question_sub_type = #{questionSubType}</if>
@@ -55,7 +54,6 @@ 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>
@@ -68,7 +66,6 @@ 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>
 
@@ -83,8 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         answer,
         create_by,
         question_type,
-        question_sub_type,
-        user_id
+        question_sub_type
         )
         VALUES
         <foreach collection="list" item="item" separator=",">
@@ -98,8 +94,7 @@ 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.userId, jdbcType=BIGINT}
+            #{item.questionSubType, jdbcType=VARCHAR}
             )
         </foreach>
     </insert>

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

@@ -38,6 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
             <if test="companyId != null "> and company_id = #{companyId}</if>
             <if test="amount != null "> and amount = #{amount}</if>
+            <if test="status != null "> and `status` = #{status}</if>
             <if test="qwUserId != null  and qwUserId != ''"> and qw_user_id = #{qwUserId}</if>
         </where>
     </select>

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

@@ -85,7 +85,6 @@ 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>
 
@@ -194,7 +193,6 @@ 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>
@@ -234,7 +232,6 @@ 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>
 
@@ -312,12 +309,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 <!--        ORDER BY-->
 <!--        c.course_id-->
 <!--    </select>-->
-
-    <select id="selectFsUserCourseAllList" resultType="com.fs.his.vo.OptionsVO">
-        select course_id dict_value, course_name dict_label,img_url dict_imgUrl  from fs_user_course
-        where is_del = 0 and is_private = 1
-        <if test="userId != null">
-            and user_id = #{userId}
-        </if>
-    </select>
 </mapper>

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

@@ -28,9 +28,6 @@
             <if test="params.userId != null and params.userId != ''">
                 and cu.user_id = #{params.userId}
             </if>
-            <if test="params.userId != null and params.userId != ''">
-                and ctc.user_id like concat('%',#{params.userId},'%')
-            </if>
         </where>
         group by ctc.training_camp_id, ctc.training_camp_name, ctc.order_number
         order by

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

@@ -35,7 +35,6 @@
         <result property="viewStartTime"    column="view_start_time"    />
         <result property="viewEndTime"    column="view_end_time"    />
         <result property="lastJoinTime"    column="last_join_time"    />
-        <result property="userId" column="user_id" />
         <result property="projectId"    column="project_id"    />
     </resultMap>
 
@@ -59,7 +58,6 @@
             <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>
 
@@ -100,7 +98,6 @@
             <if test="viewStartTime != null">view_start_time,</if>
             <if test="viewEndTime != null">view_end_time,</if>
             <if test="lastJoinTime != null">last_join_time,</if>
-            <if test="userId != null">user_id,</if>
             <if test="projectId != null">project_id,</if>
             <if test="isProduct != null">is_product,</if>
             <if test="productId != null">product_id,</if>
@@ -141,7 +138,6 @@
             <if test="productId != null">#{productId},</if>
             <if test="listingStartTime != null">#{listingStartTime},</if>
             <if test="listingEndTime != null">#{listingEndTime},</if>
-            <if test="userId != null">#{userId},</if>
             <if test="projectId != null">#{projectId},</if>
         </trim>
     </insert>
@@ -164,7 +160,6 @@
         file_size,
         file_key,
         is_transcode,
-        user_id,
         project_id
         )
         values
@@ -186,7 +181,6 @@
             #{item.fileSize},
             #{item.fileKey},
             #{item.isTranscode},
-            #{item.userId},
             #{item.projectId}
             )
         </foreach>
@@ -228,7 +222,6 @@
             <if test="productId != null">product_id = #{productId},</if>
             <if test="listingStartTime != null">listing_start_time = #{listingStartTime},</if>
             <if test="listingEndTime != null">listing_end_time = #{listingEndTime},</if>
-            <if test="userId != null">user_id = #{userId},</if>
             <if test="projectId != null">project_id = #{projectId},</if>
         </trim>
         where video_id = #{videoId}

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

@@ -18,9 +18,6 @@ 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>

+ 39 - 9
fs-service/src/main/resources/mapper/statis/FsStatisQwWatchMapper.xml

@@ -245,7 +245,9 @@
             ifnull(sum(remind_pending_num),0) as remind_pending_num,
             ifnull(sum(remind_processed_num),0) as remind_processed_num,
             (case when sum(send_num)>=sum(registered_num) then ROUND(SUM(registered_num) * 1.0 / SUM(send_num), 4) else 0 end) as reg_rate,
-            (case when sum(send_num)>=sum(completed_num) then ROUND(SUM(completed_num) * 1.0 / SUM(send_num), 4) else 0 end) as finished_rate
+            (case when sum(send_num)>=sum(completed_num) then ROUND(SUM(completed_num) * 1.0 / SUM(send_num), 4) else 0 end) as finished_rate,
+            ifnull(sum(traffic_sum,0)) as traffic_sum,
+            ifnull(sum(reg_num,0)) as reg_num
         from fs_statis_qw_watch
         <where>
             <if test="startDate != null and endDate != null">
@@ -288,7 +290,9 @@
         ifnull(sum(watch.remind_pending_num),0) as remind_pending_num,
         ifnull(sum(watch.remind_processed_num),0) as remind_processed_num,
         (case when sum(watch.send_num)>=sum(watch.registered_num) then ROUND(SUM(watch.registered_num) * 1.0 / SUM(watch.send_num), 4) else 0 end) as reg_rate,
-        (case when sum(watch.send_num)>=sum(watch.completed_num) then ROUND(SUM(watch.completed_num) * 1.0 / SUM(watch.send_num), 4) else 0 end) as finished_rate
+        (case when sum(watch.send_num)>=sum(watch.completed_num) then ROUND(SUM(watch.completed_num) * 1.0 / SUM(watch.send_num), 4) else 0 end) as finished_rate,
+        ifnull(sum(traffic_sum,0)) as traffic_sum,
+        ifnull(sum(reg_num,0)) as reg_num
         from fs_statis_qw_watch watch
         left join company_dept dept on watch.dept_id=dept.dept_id
         left join company_user cu on watch.company_user_id=cu.user_id
@@ -321,7 +325,7 @@
             #{item.deletedNum,jdbcType=BIGINT}, #{item.orderNum,jdbcType=BIGINT}, #{item.orderMoneyTotal,jdbcType=DECIMAL},
             #{item.redPackageMoneyTotal,jdbcType=DECIMAL}, #{item.callNum,jdbcType=BIGINT}, #{item.receivePassNum,jdbcType=BIGINT},
             #{item.receiveNotNum,jdbcType=BIGINT}, #{item.callTimeTotal,jdbcType=BIGINT}, #{item.remindPendingNum,jdbcType=BIGINT},
-            #{item.remindProcessedNum,jdbcType=BIGINT}
+            #{item.remindProcessedNum,jdbcType=BIGINT},#{item.trafficSum,jdbcType=BIGINT},#{item.regNum,jdbcType=BIGINT}
             )
         </foreach>
     </insert>
@@ -349,7 +353,9 @@
                 remind_pending_num,
                 remind_processed_num,
                 qw_repeat_num,
-                user_repeat_num
+                user_repeat_num,
+                traffic_sum,
+                reg_num
             )
             WITH extended_temp AS (
             -- 原始temp表数据
@@ -406,7 +412,9 @@
             IFNULL(qw_work.remind_pending_num, 0) as remind_pending_num,
             IFNULL(qw_work.remind_processed_num, 0) as remind_processed_num,
             IFNULL(contact.qw_repeat_num,0) as qw_repeat_num,
-            IFNULL(contact.user_repeat_num,0) as user_repeat_num
+            IFNULL(contact.user_repeat_num,0) as user_repeat_num,
+            IFNULL(traffic.traffic_sum,0) as traffic_sum,
+            IFNULL(fs_user.reg_num,0) as reg_num
             FROM extended_temp temp
             LEFT JOIN (
             SELECT
@@ -439,7 +447,7 @@
             AND contact.status IN (4, 5, 7)
             AND contact.update_time >= #{startTime}
             AND contact.update_time < #{endTime}
-            GROUP BY qw_user_id, company_user_id
+            GROUP BY company_user_id,qw_user_id
             ) contact ON contact.qw_user_id = temp.qw_user_id
             AND contact.company_user_id = temp.company_user_id
 
@@ -455,7 +463,7 @@
             AND company_user_id IS NOT NULL
             AND create_time >= #{startTime}
             AND create_time < #{endTime}
-            GROUP BY company_user_id
+            GROUP BY company_user_id,qw_user_id
             ) stats_order ON temp.company_user_id = stats_order.company_user_id
             AND temp.qw_user_id = '-1'
             -- 红包数
@@ -468,7 +476,7 @@
             WHERE status = 1
             AND create_time >= #{startTime}
             AND create_time < #{endTime}
-            GROUP BY company_user_id
+            GROUP BY company_user_id,qw_user_id
             ) redp ON temp.company_user_id = redp.company_user_id
             AND temp.qw_user_id = '-1'
             -- 通话统计(总拨打数(可以后面两项相加)、接通数、未接通数、通话时长)
@@ -498,7 +506,29 @@
             GROUP BY company_user_id, qw_user_id
             ) qw_work ON temp.company_user_id = qw_work.company_user_id
             AND temp.qw_user_id = qw_work.qw_user_id
-
+                -- 流量统计
+            LEFT JOIN (
+                select
+                    company_user_id,
+                    qw_user_id,
+                    SUM(internet_traffic) as traffic_sum
+                from fs_course_traffic_log
+                where create_time >= #{startTime}
+                  AND create_time < #{endTime}
+                GROUP BY company_user_id, qw_user_id
+            )traffic ON temp.company_user_id = traffic.company_user_id
+                AND temp.qw_user_id = traffic.qw_user_id
+                -- 注册人数
+            LEFT JOIN (
+                select company_user_id,
+                       qw_user_id,
+                       count(user_id) as reg_num
+                from fs_user
+                WHERE create_time >= #{startTime}
+                  AND create_time < #{endTime}
+                GROUP BY company_user_id, qw_user_id
+            ) fs_user ON temp.company_user_id = fs_user.company_user_id
+                AND temp.qw_user_id = fs_user.qw_user_id
         ]]>
     </insert>
 

+ 10 - 0
fs-service/src/main/resources/pay/alipay.properties

@@ -0,0 +1,10 @@
+alipay.appId=2021003175603885
+alipay.privateKey=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCQ6KdwrikzvXJOVJGqqD1wqNmnbatbkjguDhzkPYIVYX4A8lDEhcz0mQfJsnTAjebZMgSny8KqvK+8JnePwk+U25ZKxY/78dBmB1m4hxoDYuixULOpBlIU76H2e77KYV2ZUIbUKNrkcZ/fEh10+/u5msVE/67u389dQApIMAWPAjcRALWuJleUpfBSe6RwP/JtRY6C8mhnIXPpd2viEu8Lkxjs37HnWN/9KWfZIvdxrx/PjDu3DKi1kiSS+FWwGeQUwrYOk6yclWseI+A3dohwsvVzd/7X3OmmGph6S1Sv8Luoq7KlZ25uvlFiAYxV2fTyJ1gTRomuqzBG+4l/n9BjAgMBAAECggEAAdt5ifAxhwA+ntJmq5FMeE0xvPui3qGZJr33kNVY/X0qaEiy0FIGtnvfpa4r4OvwsYf6l0v9SsLwXbEAh08uRfIqkvrFRa1rxmMBu2O/6Zsy8FLgeqIiGzKXGNmtMFrfID/v+ngrlhH+wpUw23b/Wvmo3aGJVHZ56fAQMayr5ZFUw0F6FktB0lGQjLw2yS6nwy6GvsCA3KeclP3AQGPxVZC3uuw2oVDkqHBBeHk0L5XA3x8DgeJ73zsWlWRD7dPOrhjiLzFl9WdGQobP2TTNzVH3uolUtxkC4o9I8B6BdARqLDn2yqalF6MzzlOlKTo8/I+htQ8qxcudQzZ+2CjiQQKBgQDDYzrwnk0DPWDp2lThZ8gy/c4dX/RgIH+YndW9DYhDkTH6Bhb+bGKFWL4zods3RIEWZgQWzKTXzm7UhoN6QOu/0xl3l4OIyd9OjTaX9BTm2mT3IB7mHq+7trJgHldZiP325uZr1pH4hJ9FW/tOYKP5sA2fy1ka2+t/tKbjHVJzPQKBgQC93KICFYjWTHw6L/6t4jzyE1co0sOivfRf/ObKNzmv5Qe8RKr4f/vZBHHvuh9SOMd/ZLDKbqzEMJkB4iP/XjGk5SWARTWUVzY21hYBjYthjJ9ZmbrZM8Ys2M2N38edvFJn6fUeZFbCBNm7GbJIqdAgMhB+xnEkKwMGQyqTSgEMHwKBgQCoWxpwNpa5Uevt1LkKuDgi59rwKLwTEC2hvW5sRfrB7ZwYiaLKe22w5LSPHModJyPrvt+LHa50XWXWLkmfz8zTLvxkteMavIdz0e3WpPRVrp0M61p0gsB9iIDOnZY6ifX7Bx5IkUyZzPzH8Ofrsw3XmcFDjR4sLI8RLQIX9C4VKQKBgQCzNCbuVKkdrH+s5FQ8h8gCrWKdM6JYX3bjiu/DejDG5yRP/XhqqVJrWhi4rzKVBua2RbHgwGntm/kvn+VeSegNvgOReMHDzDVtuNB4ksM2Rea6SbHlBUtOVSxfdxMQvQoC7v7futFwu+dPBEgU8cNyQA71uhRckQR/yrHK6BTo/QKBgGyYgL97kQX1CR4LDXVMn2ebhIcadjVCKlZe2v1gtd9HkYh5zqJhtNsFO5HgBB+tW1/EFD+wHeZ+5LcYgNc6fU6gJEvnYG0ezUGfnrNg2oKW22oDE9h2tPap6BYIJboohiY0gq6pgu3wEAwCEwtRjYYNwr4ZDRM9Wq/RlgBalY5S
+alipay.publicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxq6z6GPljO9YCrOptYhWSXO5ts4phovkcVXHc2NBLBq8p1jS/pyQj5k3Oay0lRI3cE7Apl6b/nqMCa1sxg5P/muqNAr6S1wy4X/uvWZwMKK2Woe6OJqfY7DLiRqjpQ4Tp5GIgY5AI7D91hHbQHTRVzKz4SwCwNTHriVuzfXgqnoq6kaQn/EtP0edf1qqb5gdBcK4Z9SgZLLxXMXqiCfUcvkfgjEwDq0HIbX/DdrPvJ9WmoT0uIWTMWk3fx549wnmG0rCxwERldFVJ5Rvn4Q3PzHkt1YITmxigryPMyDfk+U5CHysJ8O2cBtlpNGBRYZyh0Ul+eCcA1zI0fWimZORfQIDAQAB
+alipay.appCertPath=C:/App/cert/alipay/appCertPublicKey_2021002106618710.crt
+alipay.aliPayCertPath=C:/App/cert/alipay/alipayCertPublicKey_RSA2.crt
+alipay.aliPayRootCertPath=C:/App/cert/alipay/alipayRootCert.crt
+alipay.serverUrl=https://openapi.alipay.com/gateway.do
+alipay.domain=https://api.yjf.runtzh.com
+alipay.returnDomain=http://alipay.yjf.runtzh.com
+

+ 8 - 0
fs-service/src/main/resources/pay/alipay1.properties

@@ -0,0 +1,8 @@
+alipay.appId=2021001183651266
+alipay.privateKey=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHxLTvAARsNy8Vx3UAD+N1xc0bME315mB+p7tuhGxqoGgOhFDQ4ozKs/HQ+lRXzzLSkKvZMQqK3GRP4mx4ziihZ8qLSzyxKC6yRVujMd4igq26/POERUlzbAl50SBWGDiVxMJBidtvq0EmoFYGzalix8gD3QhitQGeUl93k1omNDDFP7qQEGhUMA3BHVj4JTwMHT7s5EzZ/189d00OC3atYzF5mcswTYCEJY7WIPDCB9+1Hr63jYufTSlDYkZBwvObxQU7sLlj64gd2u/n/QydunXp1PwZN5aUnTE3MW0Gzx+MeIf7myB3DFfOqTP6mC/sXSVGnbO1Agnfohl6gEQpAgMBAAECggEBAIkV7oe3/lD4iYIrjpmNTazrIPYQbt9YyU0A83lCvFdrXhzgJclCPhV36HBc6HYdhKXEi3kO00o5NUkwevlnl7AzVmXCKpLznR/OwrS5qtMJ1AhmPwG8vkvLjrEelk8ebe4wyJFK9d+qqJnGG2KtzRgxOouUKYX66nJn2oVnA80EeVNJQ3PqMbT2Q6p/sm+BJVb54t9KoPyuXe6MqHr9fWiUoJ47bE/JgqQg9pSs9lHRvqWcCIBnUY+Y4ZuE1HsFWg+mtLt+qFktFO+3xbj0jhrbzqsVR/pjHq6wxumidA9yaSMEvRqECi7x6VTH7OquOYMNCZW5Fdw+KMg9mvrx+lECgYEA/IcvtH62bQxHg9uOuuNFFPGeyuhYJk950PDdWmBKXOIfLNm1PL6UcY8vSP4rWpk4VrXdt0bt9suME+zmXWwymFwESKl0Kmcy1c3hsFBKnJApfxbULzDUFXGbMd/0WqPBibx98iLxpdlHxREg/vcuOB+ZUIPI7px5dNkgL5JfR70CgYEAyoPS+ahUmr/57kaxt3TpsDDIotvVT+k3hD3MSmBZu2AXPcPFapqydWdBHHfhq1GnEN7QvfYQOgBRF3+l9WRuKBefmu8sLsPzHbLoVBBK594yBmBQmy6C+g83/zOqTxK57YLk9abtc9Y6ssXQGkR2/DRCYm1CtqQmB/fElKlPDt0CgYBnJYzNy+gVuKtJZ5fwLD6eZGb4+FhxJYtbVdcEQEp/j/kt56sIqcuWaubkiLUKp4UEnfp3DyjJ4rBPvzcFN9metA8n4tdJLqfr/tFNpC4lrxjUCW4X7HjkXWgHwjNcBoFaEjzbd3x+wrZ2/x0cJ7igQf/sjDe5hv5xRPLJm58BfQKBgF+iky4tDQ8rW7bnkaNmRblbwFQQZpLfOsVrfZ8eEyIGhdM4MXFfbqk8wqXUAzEpVTEFWCRtIEqTvbfQIypYbCDozwmWqxHGnXfH9ilErGsFJjCWqVovQ9EdAL+2wVWoLT95kfBkDTynzX6BJf5RmLMPZs4edOPVbtRScHYX4mrNAoGBAMVkGQuSIM4Mf/bMvEqPMc9GpYJ6tA6BqBsLY9yyXnArHaR9dGvKmN59+JmxM9sYCXunhtyLu83bkB2XtfIUGj8TYJxWUxvAwcx8JAE5qb6E5oStKbxb0hKh5CG59gqFlAVpcqMIwpeCDQhBin5AlMTgrmV8S6gTBp0efHTn9G4N
+alipay.publicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArqkO4WGHLHufhdMMOsckp964jUWNncwY9r4XB2HVEeHIDOcThp61/TJXGKxmQctAQ9CDNK1aP4SPWHd3rItN8HIX1Fo+oXsDkHrlRqh5p2DOdvmsaGbceyCT/OF4nX+km/WJ9TXBQ3SaI5h8xqESeX0srs0j7QjXafGQrprO2wlih84Ri2FbaDIJvlReZcJZLpxlYBKGXfepp1wvBEMmHH66JArWZ2w03zaFODW7vbEZZplKOZMijPE0V2SUsqwqqbPajKaO3cXf/pE9bzIGi9VLcpr0cWSkzdEUF0yQ1w/dxkdfMdgyurSb7CpuYU7/QEHWNJp5w5euGySDS1U4xQIDAQAB
+alipay.appCertPath=
+alipay.aliPayCertPath=
+alipay.aliPayRootCertPath=
+alipay.serverUrl=https://openapi.alipay.com/gateway.do
+alipay.domain=http://http://api.qinpeilian.com/

TEMPAT SAMPAH
fs-service/src/main/resources/pay/cert/apiclient_cert.p12


+ 26 - 0
fs-service/src/main/resources/pay/cert/apiclient_cert.pem

@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEazCCA9SgAwIBAgIDPfFVMA0GCSqGSIb3DQEBBQUAMIGKMQswCQYDVQQGEwJD
+TjESMBAGA1UECBMJR3Vhbmdkb25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UE
+ChMHVGVuY2VudDEMMAoGA1UECxMDV1hHMRMwEQYDVQQDEwpNbXBheW1jaENBMR8w
+HQYJKoZIhvcNAQkBFhBtbXBheW1jaEB0ZW5jZW50MB4XDTE2MDgyMjEwMDAyN1oX
+DTI2MDgyMDEwMDAyN1owgZsxCzAJBgNVBAYTAkNOMRIwEAYDVQQIEwlHdWFuZ2Rv
+bmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQKEwdUZW5jZW50MQ4wDAYDVQQL
+EwVNTVBheTEwMC4GA1UEAxQn5YyX5Lqs5b+r5a6i5pyN56eR5oqA5Y+R5bGV5pyJ
+6ZmQ5YWs5Y+4MREwDwYDVQQEEwgxMzk5MzgzMjCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAMRbFxBzC0GQ14Hxh4Uspdt3B7mQSAsa2hLvqWYsPYXbQ9Rh
+Jb/pdUOF9zwh4i9CTrWLqSazgs7Rqf7EEyhdT08KDQbF9uDRHW3m/XSGb8XyQKX0
+yu8yEUDH6SvUGQQ3U4DOOsHooa9jTIZeohAtwe9+GQX2WjRzjr3RlW2DIyTGwjYi
+QB5CU1uivt+tfEDW+wP4gjnWecShYPfeK1uIybinFzmy4tUGGuNl7N9H4IrMi2TT
+BpqMGbEukoDjzYv4h23MPuh6f1AHGpsI39BJJs8TjYeccMIrOqzXSv1bcRVsH+FZ
+4AkYhgeCt6MudedjGy5J9IEU957esxmXtSuDt10CAwEAAaOCAUYwggFCMAkGA1Ud
+EwQCMAAwLAYJYIZIAYb4QgENBB8WHSJDRVMtQ0EgR2VuZXJhdGUgQ2VydGlmaWNh
+dGUiMB0GA1UdDgQWBBTOrb+vqp/rqP6DZntwZEmzL+ickTCBvwYDVR0jBIG3MIG0
+gBQ+BSb2ImK0FVuIzWR+sNRip+WGdKGBkKSBjTCBijELMAkGA1UEBhMCQ04xEjAQ
+BgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNVBAoTB1Rl
+bmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEfMB0GCSqG
+SIb3DQEJARYQbW1wYXltY2hAdGVuY2VudIIJALtUlyu8AOhXMA4GA1UdDwEB/wQE
+AwIGwDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQUFAAOBgQBC
+n8MEDVIVlyC2jkRfy4UezLlbnGTkYb+Nb4oMZRvIjNTFzqQ+6SOPKEqlU0FOZwuI
+pr+pDG+H484PQjt6b8ftUOBuKKeaMDMauRz2jqXJkKWcDa4U/CJ+/CboolU4T0xO
+Lp+zNqa7epBvU3HQtX4MEzZEnI5auPVde9nsJbo2QA==
+-----END CERTIFICATE-----

+ 28 - 0
fs-service/src/main/resources/pay/cert/apiclient_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEWxcQcwtBkNeB
+8YeFLKXbdwe5kEgLGtoS76lmLD2F20PUYSW/6XVDhfc8IeIvQk61i6kms4LO0an+
+xBMoXU9PCg0Gxfbg0R1t5v10hm/F8kCl9MrvMhFAx+kr1BkEN1OAzjrB6KGvY0yG
+XqIQLcHvfhkF9lo0c4690ZVtgyMkxsI2IkAeQlNbor7frXxA1vsD+II51nnEoWD3
+3itbiMm4pxc5suLVBhrjZezfR+CKzItk0waajBmxLpKA482L+IdtzD7oen9QBxqb
+CN/QSSbPE42HnHDCKzqs10r9W3EVbB/hWeAJGIYHgrejLnXnYxsuSfSBFPee3rMZ
+l7Urg7ddAgMBAAECggEAZt2FhrOOOQoFLGj44xaRyRhhbqAcbdziU7tEFmekz2Qf
+87n1CcXnDbm33MOvd6yYCVmiAslWBL0n/nR/yMyhSLnuOxcoj3xdm37AVvQ6yAty
+PL6yNX8YNMTF7ZUOifvl/fuMIpuZYIV3yIj5A9rE149K0qnNdd73749FZfqmRZQD
+rwh4Xh8M+mj8CulpGsjwKVfUrCWsXaVh9pL7XNMYXBRnGdrCFOs7uPjAUcOZlXjx
+LboQqjmVbveeGJ2lptRjDu5y934T7msQPugss/aCZAbaNN1RklBGJ3FtxgRAQ8z5
+zKCaWzDFyXGWENY/+ZHai9pHK2QS0IPhb+qV/qiYzQKBgQDgaWNOqb14QwbwshFr
+C3Ib5s2XqhTFBTxrtJceWUZZiHDL3Z5ecSPSeBREpxLn/miVIXBc/zyGGF5E2SPB
+zPuj9xrtI8HlxETZG4NuUbgqfFdPUKwroAPMvhqM7ZaanYqRiVTkvmVHtuL4aFk3
+LCKuhjHiSkW2ZaKlgqAkdcGGAwKBgQDf/renwmIC7Lh6sJewsRKe3h3UhzG0XW8t
+HIbx7b5cqKRTrdkPeBLN4w64D37kEK9mmoLsYkZuHA2YJndDGyu6+R2tI69s3vyr
+8hfJBDK0WaVEps2BUQ5KXDrbquYVbBGA6Q7anpVhekXILKBQRxUd7UaRqTvCL04R
+bH7NZzN/HwKBgE5j4gG/f2T8HPeFbFo1NFYUyKp7CihMjO+etM8wJkfuRmCgeMrK
+wNWrhoD4z7zkfMnjVWnW6uB4sK1iIIB5R0nebrR5sii958LjPoUR3MBSkPku2AWh
+LtKdcY7bC6nU8GuoSlRhQeXMN/rIEKoaK79FNzWx9ioh1K/2MlSqIcDbAoGADBQi
+NyumOV4mfIc1RtPlmyeDGEjKB13aduZI6JbXYwu9AL4pLEpfSTbrPkWnpAi6TKAc
+Wz7ZaWqd2QyJ9dZrP0Pbs9Buz0IfAe6mFbLiQRNsdA1Cm6yRRrU+f0Xx7knLj9YB
+dQyEJaOAS9EMPAf5PYnj+krT7B686Peexti/0CUCgYB9uACIaTlN0XQvoXuFktv4
+4xqyOLCfTZW38e1UJ4bqyOJUP0EKfo/03j8Lp/vsZmCK2bIdudG+4rZbuiQXOe31
+cfGo7dQhCorOlrUig0CWwq8oXPbKmvOO7K+UGnK5e46BUbopxU1dTwhxAUA6hbcb
+mFh3iSvhn4JJG2ddomXY3A==
+-----END PRIVATE KEY-----

+ 18 - 0
fs-service/src/main/resources/pay/cert/证书使用说明.txt

@@ -0,0 +1,18 @@
+欢迎使用微信支付!
+附件中的三份文件(证书pkcs12格式、证书pem格式、证书密钥pem格式),为接口中强制要求时需携带的证书文件。
+证书属于敏感信息,请妥善保管不要泄露和被他人复制。
+不同开发语言下的证书格式不同,以下为说明指引:
+    证书pkcs12格式(apiclient_cert.p12)
+        包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份
+        部分安全性要求较高的API需要使用该证书来确认您的调用身份
+        windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
+    证书pem格式(apiclient_cert.pem)
+        从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制
+        部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+        您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
+    证书密钥pem格式(apiclient_key.pem)
+        从apiclient_cert.p12中导出密钥部分的文件,为pem格式
+        部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
+        您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem
+备注说明:  
+        由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书,  2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载 

+ 8 - 0
fs-service/src/main/resources/pay/wxpay.properties

@@ -0,0 +1,8 @@
+wxpay.appId=wxbe53e91d9ad11ca6
+wxpay.appSecret=58d70c9be43047ef3275339a3f4b5ee0
+wxpay.mchId=1581878681
+wxpay.partnerKey=8cab128997a3547c1363b0898b877f38
+wxpay.certPath=pay/cert/apiclient_cert.p12
+wxpay.domain= https://api.hospital.ifeiyu100.com
+
+

+ 9 - 0
fs-service/src/main/resources/pay/wxpay_v3.properties

@@ -0,0 +1,9 @@
+v3.appId=\u5E94\u7528\u7F16\u53F7
+v3.keyPath=key.pem
+v3.certPath=cert.pem
+v3.certP12Path=cert.p12
+v3.platformCertPath=wx_cert.pem
+v3.mchId=\u5FAE\u4FE1\u5546\u6237\u53F7
+v3.apiKey3= Api-v3 \u5BC6\u94A5
+v3.apiKey= Api \u5BC6\u94A5
+v3.domain=  http://qbhdat.natappfree.cc

+ 1 - 1
fs-user-app/src/main/java/com/fs/app/controller/IndexController.java

@@ -142,7 +142,7 @@ public class IndexController extends AppBaseController {
 
 	@ApiOperation("企业理念")
 	@GetMapping("/getConcept")
-	@springfox.documentation.annotations.Cacheable("getConcept")
+	@Cacheable("getConcept")
 	public R getConcept(HttpServletRequest request){
 		String json=configService.selectConfigByKey("store.concept");
 		ConceptConfig config = JSONUtil.toBean(json, ConceptConfig.class);

+ 9 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxPayController.java

@@ -2,6 +2,8 @@ package com.fs.app.controller;
 
 
 import cn.hutool.json.JSONUtil;
+import com.fs.company.service.ICompanyRechargeService;
+import com.fs.core.config.WxPayProperties;
 import com.fs.course.config.RedPacketConfig;
 import com.fs.course.domain.FsCourseRedPacketLog;
 import com.fs.course.service.IFsCourseProductOrderService;
@@ -26,6 +28,7 @@ import com.github.binarywang.wxpay.constant.WxPayConstants;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import com.github.binarywang.wxpay.util.SignUtils;
 import com.google.gson.Gson;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -41,6 +44,8 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
 
 @Api("微信支付接口")
 @RestController
@@ -76,7 +81,11 @@ public class WxPayController {
     @Autowired
     private IFsCourseProductOrderService courseProductOrderService;
 
+    @Autowired
+    ICompanyRechargeService rechargeService;
 
+    @Autowired
+    private WxPayProperties wxPayProperties;
     /**
      * 微信回调
      * 回调接口代码内部自动校验结果签名和业务代码