Kaynağa Gözat

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

yzx 2 hafta önce
ebeveyn
işleme
eb6277bfbe
94 değiştirilmiş dosya ile 1286 ekleme ve 283 silme
  1. 2 2
      fs-admin/src/main/resources/application.yml
  2. 0 1
      fs-common/pom.xml
  3. 2 2
      fs-common/src/main/java/com/fs/common/enums/BizResponseEnum.java
  4. 7 1
      fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java
  5. 0 3
      fs-company/src/main/java/com/fs/common/controller/CommonController.java
  6. 24 0
      fs-company/src/main/java/com/fs/company/controller/CompanyUserController.java
  7. 104 0
      fs-company/src/main/java/com/fs/company/controller/CompanyWxDialogController.java
  8. 120 0
      fs-company/src/main/java/com/fs/company/controller/CompanyWxUserGroupController.java
  9. 1 0
      fs-company/src/main/java/com/fs/core/config/SecurityConfig.java
  10. 0 18
      fs-company/src/main/java/com/fs/qw/vo/QwContactListVO.java
  11. 12 10
      fs-company/src/main/java/com/fs/store/controller/FsCityController.java
  12. 20 0
      fs-company/src/main/java/com/fs/users/controller/FsUserAddressController.java
  13. 5 0
      fs-company/src/main/java/com/fs/users/controller/FsUserController.java
  14. 4 1
      fs-qw-api-msg/pom.xml
  15. 16 3
      fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java
  16. 101 0
      fs-qw-api-msg/src/main/java/com/fs/app/socket/QwImSocket.java
  17. 22 0
      fs-qw-api-msg/src/main/java/com/fs/app/socket/configurator/QwImConfigurator.java
  18. 3 3
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataScopeAspect.java
  19. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataSourceAspect.java
  20. 5 5
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/LogAspect.java
  21. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/aspectj/RateLimiterAspect.java
  22. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ApplicationConfig.java
  23. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ArrayStringTypeHandler.java
  24. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/CaptchaConfig.java
  25. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/config/DataSourceConfig.java
  26. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/FastJson2JsonRedisSerializer.java
  27. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/FilterConfig.java
  28. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/KaptchaTextCreator.java
  29. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/MyBatisConfig.java
  30. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/RedisConfig.java
  31. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/config/ResourcesConfig.java
  32. 6 5
      fs-qw-api-msg/src/main/java/com/fs/core/config/SecurityConfig.java
  33. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ServerConfig.java
  34. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/SwaggerConfig.java
  35. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/ThreadPoolConfig.java
  36. 17 0
      fs-qw-api-msg/src/main/java/com/fs/core/config/WebSocketConfig.java
  37. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/config/properties/DruidProperties.java
  38. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSource.java
  39. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSourceContextHolder.java
  40. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/exception/GlobalExceptionHandler.java
  41. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/interceptor/RepeatSubmitInterceptor.java
  42. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/interceptor/impl/SameUrlDataInterceptor.java
  43. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/AsyncManager.java
  44. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/ShutdownManager.java
  45. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/manager/factory/AsyncFactory.java
  46. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/LoginBody.java
  47. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/LoginUser.java
  48. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/SecurityUtils.java
  49. 4 4
      fs-qw-api-msg/src/main/java/com/fs/core/security/filter/JwtAuthenticationTokenFilter.java
  50. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/security/handle/AuthenticationEntryPointImpl.java
  51. 5 5
      fs-qw-api-msg/src/main/java/com/fs/core/security/handle/LogoutSuccessHandlerImpl.java
  52. 4 4
      fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyLoginService.java
  53. 1 1
      fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyPermissionService.java
  54. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/PermissionService.java
  55. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/TokenService.java
  56. 2 2
      fs-qw-api-msg/src/main/java/com/fs/core/service/UserDetailsServiceImpl.java
  57. 1 1
      fs-qw-api-msg/src/main/resources/mybatis/mybatis-config.xml
  58. 10 0
      fs-service-system/src/main/java/com/fs/company/domain/CompanyUser.java
  59. 5 35
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
  60. 12 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java
  61. 35 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  62. 2 0
      fs-service-system/src/main/java/com/fs/course/config/CourseConfig.java
  63. 2 0
      fs-service-system/src/main/java/com/fs/course/domain/FsUserCoursePeriod.java
  64. 3 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  65. 55 33
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  66. 9 6
      fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java
  67. 35 8
      fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  68. 1 1
      fs-service-system/src/main/java/com/fs/qw/mapper/QwUserMapper.java
  69. 2 0
      fs-service-system/src/main/java/com/fs/qw/param/QwSessionParam.java
  70. 99 7
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java
  71. 1 1
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java
  72. 2 1
      fs-service-system/src/main/java/com/fs/qw/vo/QwContactListVO.java
  73. 3 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwMessageListVO.java
  74. 57 61
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java
  75. 1 1
      fs-service-system/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  76. 37 0
      fs-service-system/src/main/java/com/fs/store/dto/AddressInfoDTO.java
  77. 4 1
      fs-service-system/src/main/java/com/fs/store/service/IFsUserAddressService.java
  78. 7 1
      fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
  79. 65 4
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserAddressServiceImpl.java
  80. 45 2
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  81. 6 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java
  82. 4 0
      fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkUserId2VidDTO.java
  83. 2 2
      fs-service-system/src/main/resources/application-config-dev.yml
  84. 122 0
      fs-service-system/src/main/resources/application-config-fby.yml
  85. 0 0
      fs-service-system/src/main/resources/application-druid-fby.yml
  86. 20 0
      fs-service-system/src/main/resources/db/upgrade/20250516.sql
  87. 48 1
      fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml
  88. 4 0
      fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml
  89. 6 4
      fs-service-system/src/main/resources/mapper/store/FsUserCourseCountMapper.xml
  90. 9 0
      fs-user-app/src/main/java/com/fs/app/controller/CourseController.java
  91. 25 1
      fs-user-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java
  92. 12 4
      fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java
  93. 9 0
      fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java
  94. 3 2
      fs-user-app/src/main/resources/application.yml

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

@@ -5,5 +5,5 @@ server:
   port: 7011
 spring:
   profiles:
-    active: dev
-    include: common,config-dev
+    active: druid-fby
+    include: common,config-fby

+ 0 - 1
fs-common/pom.xml

@@ -122,7 +122,6 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <version>1.18.10</version>
         </dependency>
 
         <dependency>

+ 2 - 2
fs-common/src/main/java/com/fs/common/enums/BizResponseEnum.java

@@ -7,8 +7,8 @@ public enum BizResponseEnum {
     SUCCESS(200, "操作成功"),
     FAIL(500, "操作失败"),
     PARAM_ERROR(400, "参数错误"),
-    DATA_NOT_EXIST(1002, "数据不存在");
-
+    DATA_NOT_EXIST(1002, "数据不存在"),
+    WAIT_APPROVAL(505, "等待审核");
     private final Integer code;
     private final String msg;
 

+ 7 - 1
fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java

@@ -29,6 +29,11 @@ import com.fs.store.vo.h5.*;
 import com.fs.system.service.ISysConfigService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -37,6 +42,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
@@ -341,5 +348,4 @@ public class FsUserController extends AppBaseController {
         userCourseCountService.insertFsUserCourseCountTask();
     }
 
-
 }

+ 0 - 3
fs-company/src/main/java/com/fs/common/controller/CommonController.java

@@ -182,9 +182,6 @@ public class CommonController
     @PostMapping("/common/uploadOSS")
     public R uploadOSS(@RequestParam("file") MultipartFile file) throws Exception
     {
-//        String deviceId = "4eea1292408044beb49c02d3197871b0";
-//        qwMaterialService.insertQwMaterial(file,deviceId);
-//        return R.ok();
         if (file.isEmpty())
         {
             throw new OssException("上传文件不能为空");

+ 24 - 0
fs-company/src/main/java/com/fs/company/controller/CompanyUserController.java

@@ -8,6 +8,7 @@ import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.exception.file.OssException;
 import com.fs.common.utils.DomainUtil;
 import com.fs.common.utils.PatternUtils;
 import com.fs.common.utils.ServletUtils;
@@ -25,11 +26,14 @@ import com.fs.core.web.service.TokenService;
 import com.fs.course.config.CourseConfig;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.vo.QwUserVO;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Date;
 import java.util.List;
@@ -87,6 +91,14 @@ public class CompanyUserController extends BaseController
         List<CompanyUserQwListVO> list = companyUserService.selectCompanyUserQwListVO(user);
         return getDataTable(list);
     }
+
+    @PostMapping("/common/uploadOSS")
+    public R uploadOSS(@RequestParam("file") MultipartFile file,
+                       @RequestParam("userId") String userId) throws Exception
+    {
+        String url = companyUserService.uploadQrCode(file, userId);
+        return R.ok().put("url",url);
+    }
     @GetMapping("/getUserList")
     public R getUserList()
     {
@@ -348,4 +360,16 @@ public class CompanyUserController extends BaseController
         return companyUserService.updateCompanyUserAreaList(param);
     }
 
+    @Log(title = "设置是否需要单独注册会员", businessType = BusinessType.UPDATE)
+    @PutMapping("/setRegister")
+    public AjaxResult setIsRegisterMember(@RequestParam Boolean status, @RequestBody List<Long> userIds)
+    {
+        Boolean r = companyUserService.setIsRegisterMember(status, userIds);
+        if(r){
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("操作失败");
+        }
+    }
+
 }

+ 104 - 0
fs-company/src/main/java/com/fs/company/controller/CompanyWxDialogController.java

@@ -0,0 +1,104 @@
+package com.fs.company.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.CompanyWxDialog;
+import com.fs.company.service.ICompanyWxDialogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 添加微信话术Controller
+ * 
+ * @author fs
+ * @date 2024-12-06
+ */
+@RestController
+@RequestMapping("/company/wxDialog")
+public class CompanyWxDialogController extends BaseController
+{
+    @Autowired
+    private ICompanyWxDialogService companyWxDialogService;
+
+    /**
+     * 查询添加微信话术列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CompanyWxDialog companyWxDialog)
+    {
+        startPage();
+        List<CompanyWxDialog> list = companyWxDialogService.selectCompanyWxDialogList(companyWxDialog);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:list')")
+    @GetMapping("/listAll")
+    public R listAll(CompanyWxDialog companyWxDialog){
+        return R.ok().put("data", companyWxDialogService.selectCompanyWxDialogList(companyWxDialog));
+    }
+
+    /**
+     * 导出添加微信话术列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:export')")
+    @Log(title = "添加微信话术", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CompanyWxDialog companyWxDialog)
+    {
+        List<CompanyWxDialog> list = companyWxDialogService.selectCompanyWxDialogList(companyWxDialog);
+        ExcelUtil<CompanyWxDialog> util = new ExcelUtil<CompanyWxDialog>(CompanyWxDialog.class);
+        return util.exportExcel(list, "wxDialog");
+    }
+
+    /**
+     * 获取添加微信话术详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(companyWxDialogService.selectCompanyWxDialogById(id));
+    }
+
+    /**
+     * 新增添加微信话术
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:add')")
+    @Log(title = "添加微信话术", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CompanyWxDialog companyWxDialog)
+    {
+        return toAjax(companyWxDialogService.insertCompanyWxDialog(companyWxDialog));
+    }
+
+    /**
+     * 修改添加微信话术
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:edit')")
+    @Log(title = "添加微信话术", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CompanyWxDialog companyWxDialog)
+    {
+        return toAjax(companyWxDialogService.updateCompanyWxDialog(companyWxDialog));
+    }
+
+    /**
+     * 删除添加微信话术
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxDialog:remove')")
+    @Log(title = "添加微信话术", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(companyWxDialogService.deleteCompanyWxDialogByIds(ids));
+    }
+}

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

@@ -0,0 +1,120 @@
+package com.fs.company.controller;
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.core.security.LoginUser;
+import com.fs.core.web.service.TokenService;
+import com.fs.wxUser.domain.CompanyWxUserGroup;
+import com.fs.wxUser.service.ICompanyWxUserGroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 个微 分组Controller
+ *
+ * @author fs
+ * @date 2024-10-25
+ */
+@RestController
+@RequestMapping("/company/wxUserGroup")
+public class CompanyWxUserGroupController extends BaseController
+{
+    @Autowired
+    private ICompanyWxUserGroupService companyWxUserGroupService;
+    @Autowired
+    private TokenService tokenService;
+    /**
+     * 查询个微 分组列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CompanyWxUserGroup companyWxUserGroup)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyWxUserGroup.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<CompanyWxUserGroup> list = companyWxUserGroupService.selectCompanyWxUserGroupList(companyWxUserGroup);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出个微 分组列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:export')")
+    @Log(title = "个微 分组", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CompanyWxUserGroup companyWxUserGroup)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyWxUserGroup.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<CompanyWxUserGroup> list = companyWxUserGroupService.selectCompanyWxUserGroupList(companyWxUserGroup);
+        ExcelUtil<CompanyWxUserGroup> util = new ExcelUtil<CompanyWxUserGroup>(CompanyWxUserGroup.class);
+        return util.exportExcel(list, "个微 分组数据");
+    }
+
+    /**
+     * 获取个微 分组详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:query')")
+    @GetMapping(value = "/{groupId}")
+    public AjaxResult getInfo(@PathVariable("groupId") Long groupId)
+    {
+        return AjaxResult.success(companyWxUserGroupService.selectCompanyWxUserGroupByGroupId(groupId));
+    }
+
+    /**
+     * 新增个微 分组
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:add')")
+    @Log(title = "个微 分组", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CompanyWxUserGroup companyWxUserGroup)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyWxUserGroup.setCompanyId(loginUser.getCompany().getCompanyId());
+        return toAjax(companyWxUserGroupService.insertCompanyWxUserGroup(companyWxUserGroup));
+    }
+
+    /**
+     * 修改个微 分组
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:edit')")
+    @Log(title = "个微 分组", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CompanyWxUserGroup companyWxUserGroup)
+    {
+        return toAjax(companyWxUserGroupService.updateCompanyWxUserGroup(companyWxUserGroup));
+    }
+
+    /**
+     * 删除个微 分组
+     */
+    @PreAuthorize("@ss.hasPermi('company:wxUserGroup:remove')")
+    @Log(title = "个微 分组", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{groupIds}")
+    public AjaxResult remove(@PathVariable Long[] groupIds)
+    {
+        return toAjax(companyWxUserGroupService.deleteCompanyWxUserGroupByGroupIds(groupIds));
+    }
+
+
+    //查询个微分组-添加sop任务-个微-选择的分组(不要权限版)
+    @GetMapping("/sopList")
+    public TableDataInfo sopList(CompanyWxUserGroup companyWxUserGroup)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        companyWxUserGroup.setCompanyId(loginUser.getCompany().getCompanyId());
+        List<CompanyWxUserGroup> list = companyWxUserGroupService.selectCompanyWxUserGroupList(companyWxUserGroup);
+        return getDataTable(list);
+    }
+
+}

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

@@ -112,6 +112,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/common/uploadHuaWeiObs").anonymous()
                 .antMatchers("/common/qwUploadOSS").anonymous()
                 .antMatchers("/common/uploadWang").anonymous()
+                .antMatchers("/company/user/common/uploadOSS").anonymous()
                 .antMatchers("/common/upload").anonymous()
                 .antMatchers("/profile/**").anonymous()
                 .antMatchers("/common/download**").anonymous()

+ 0 - 18
fs-company/src/main/java/com/fs/qw/vo/QwContactListVO.java

@@ -1,18 +0,0 @@
-package com.fs.qw.vo;
-
-import lombok.Data;
-
-@Data
-public class QwContactListVO {
-    private Long id;
-    private String conversationId;
-    private String displayName;
-    private String avatar;
-    private String index;
-    private Boolean isGroup;
-    private Integer unread;
-    private Long roomId;
-    private Long lastSendTime;
-    private String lastContent;
-
-}

+ 12 - 10
fs-company/src/main/java/com/fs/store/controller/FsCityController.java

@@ -9,7 +9,9 @@ import com.fs.store.vo.CityVO;
 import com.google.common.collect.Lists;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.Cacheable;
 
 import javax.servlet.http.HttpServletRequest;
@@ -43,15 +45,15 @@ public class FsCityController extends BaseController
     @Cacheable("citys")
     public R getCitys(HttpServletRequest request){
         List<FsCity> list=fsCityService.selectFsCitys();
-//        List<CityVO> cityVOS = Lists.newArrayList();
-////        for (FsCity city : list){
-////            CityVO cityVO = new CityVO();
-////            cityVO.setValue(city.getCityId());
-////            cityVO.setLabel(city.getName());
-////            cityVO.setPid(city.getParentId());
-////            cityVOS.add(cityVO);
-////        }
-        return R.ok().put("data", list);
+        List<CityVO> cityVOS = Lists.newArrayList();
+        for (FsCity city : list){
+            CityVO cityVO = new CityVO();
+            cityVO.setValue(Long.parseLong(city.getCityId()));
+            cityVO.setLabel(city.getCityName());
+            cityVO.setPid(Long.parseLong(city.getParentId()));
+            cityVOS.add(cityVO);
+        }
+        return R.ok().put("data", CityTreeUtil.list2TreeConverter(cityVOS, 0));
 
     }
 }

+ 20 - 0
fs-company/src/main/java/com/fs/users/controller/FsUserAddressController.java

@@ -1,5 +1,6 @@
 package com.fs.users.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
@@ -8,6 +9,7 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.store.domain.FsUserAddress;
+import com.fs.store.dto.AddressInfoDTO;
 import com.fs.store.service.IFsUserAddressService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -95,4 +97,22 @@ public class FsUserAddressController extends BaseController
         List<FsUserAddress> list = fsUserAddressService.selectFsUserAddressList(fsUserAddress);
         return R.ok().put("data", list);
     }
+
+    @GetMapping(value = "/getAddress/{address}")
+    public AjaxResult getAddress(@PathVariable("address") String address)
+    {
+        String kdnAddress = fsUserAddressService.getKdnAddress(address);
+        AddressInfoDTO addressInfoDTO = JSON.parseObject(kdnAddress, AddressInfoDTO.class);
+        AddressInfoDTO.AddressData data = addressInfoDTO.getData();
+        String provinceName = data.getProvinceName();
+        if (!provinceName.contains("省") && !provinceName.contains("区")){
+            data.setProvinceName(data.getProvinceName()+"市");
+            if (data.getExpAreaName().contains("县")){
+                data.setCityName("县");
+            }else {
+                data.setCityName("市辖区");
+            }
+        }
+        return AjaxResult.success(addressInfoDTO);
+    }
 }

+ 5 - 0
fs-company/src/main/java/com/fs/users/controller/FsUserController.java

@@ -140,4 +140,9 @@ public class FsUserController extends BaseController
         Boolean r = fsUserService.disabledUser(ids, true);
         return ResponseResult.ok(r);
     }
+
+    @GetMapping("/getUserInfoBySessionId")
+    public R getUserInfoBySessionId(@RequestParam Long sessionId) {
+        return R.ok().put("data", fsUserService.getUserInfoBySessionId(sessionId));
+    }
 }

+ 4 - 1
fs-qw-api-msg/pom.xml

@@ -117,7 +117,10 @@
             <artifactId>vosk</artifactId>
             <version>0.3.32</version>
         </dependency>
-
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 16 - 3
fs-qw-api-msg/src/main/java/com/fs/app/controller/QwMsgController.java

@@ -1,11 +1,13 @@
 package com.fs.app.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.fs.app.socket.QwImSocket;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.fastGpt.service.AiHookService;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwUserVoiceLogService;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.wxwork.dto.*;
 import com.fs.wxwork.service.WxWorkService;
 import io.swagger.annotations.Api;
@@ -132,7 +134,7 @@ public class QwMsgController {
                 qwUserStatus(wxWorkMsgResp.getUuid(),0);
                 break;
             case 102000:
-
+                System.out.println(wxWorkMsgResp.getJson());
                 WxWorkMessageDTO wxWorkMessageDTO = JSON.parseObject(wxWorkMsgResp.getJson(), WxWorkMessageDTO.class);
                 if (wxWorkMessageDTO.getIs_room()!=0){
                     break;
@@ -163,13 +165,15 @@ public class QwMsgController {
                         aiHookService.qwHookNotifyAiReply(id,sender,content,wxWorkMsgResp.getUuid(),wxWorkMessageDTO.getMsgtype());
 
                         // 保存聊天消息
-                        aiHookService.saveQwMsg(id, sender, content, wxWorkMsgResp.getUuid(), 1);
+                        QwMessageListVO message = aiHookService.saveQwMsg(id, sender, content, wxWorkMsgResp.getUuid(), 1, wxWorkMsgResp.getJson());
+                        QwImSocket.broadcast(message);
                     }else {
                         System.out.println("销售发送");
                         aiHookService.qwHookNotifyAddMsg(id,receiver,content,wxWorkMsgResp.getUuid());
 
                         // 保存聊天消息
-                        aiHookService.saveQwMsg(id, receiver, content, wxWorkMsgResp.getUuid(), 2);
+                        QwMessageListVO message = aiHookService.saveQwMsg(id, receiver, content, wxWorkMsgResp.getUuid(), 2, wxWorkMsgResp.getJson());
+                        QwImSocket.broadcast(message);
                     }
 
                 }
@@ -210,6 +214,15 @@ public class QwMsgController {
 
                     qwUserVoiceLogService.addQuUserVoiceByIpadCallback(id,extId,recordType,totalSeconds,wxWorkMsgResp.getUuid());
                 }
+                // 图片消息
+                else if (wxWorkMessageDTO.getMsgtype() == 101){
+                    Long receiver = wxWorkMessageDTO.getReceiver();
+                    if (2000000000000000L - receiver > 0){
+                        System.out.println("客户发起");
+                    }else {
+                        System.out.println("销售发起");
+                    }
+                }
 
                 break;
 

+ 101 - 0
fs-qw-api-msg/src/main/java/com/fs/app/socket/QwImSocket.java

@@ -0,0 +1,101 @@
+package com.fs.app.socket;
+
+import com.alibaba.fastjson.JSON;
+import com.fs.app.socket.configurator.QwImConfigurator;
+import com.fs.qw.vo.QwMessageListVO;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+@ServerEndpoint(value = "/qwImSocket/{companyId}", configurator = QwImConfigurator.class)
+@Component
+public class QwImSocket {
+
+    private static final ConcurrentHashMap<Long, CopyOnWriteArraySet<Session>> companySessions = new ConcurrentHashMap<>();
+
+    /**
+     * 连接建立成功调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("companyId") Long companyId) {
+        // 将当前会话加入到会话池中
+        companySessions.computeIfAbsent(companyId, k -> new CopyOnWriteArraySet<>()).add(session);
+    }
+
+    /**
+     * 连接关闭调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     */
+    @OnClose
+    public void onClose(Session session, @PathParam("companyId") Long companyId) {
+        // 从会话池中移除当前会话
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
+        if (sessions != null) {
+            sessions.remove(session);
+            // 如果直播间没人了,可以移除该直播间
+            if (sessions.isEmpty()) {
+                companySessions.remove(companyId);
+            }
+        }
+    }
+
+    /**
+     * 发生错误时调用的方法
+     * @param session   连接会话
+     * @param companyId 公司ID
+     * @param error     错误对象
+     */
+    @OnError
+    public void onError(Session session, @PathParam("companyId") Long companyId, Throwable error) {
+        System.err.println("发生错误!会话ID: " + session.getId());
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(companyId);
+        if (sessions != null) {
+            sessions.remove(session);
+            // 如果直播间没人了,可以移除该直播间
+            if (sessions.isEmpty()) {
+                companySessions.remove(companyId);
+            }
+        }
+    }
+
+    /**
+     * 群发消息
+     * @param message   要发送的消息
+     */
+    public static void broadcast(QwMessageListVO message) {
+        if (Objects.isNull(message)) {
+            return;
+        }
+
+        String msg = JSON.toJSONString(message);
+        CopyOnWriteArraySet<Session> sessions = companySessions.get(message.getCompanyId());
+        if (sessions != null) {
+            for (Session session : sessions) {
+                if (session.isOpen()) {
+                    try {
+                        session.getBasicRemote().sendText(msg);
+                    } catch (IOException e) {
+                        System.err.println("发送消息给会话[" + session.getId() + "]失败: " + e.getMessage());
+                        // 移除无效会话
+                        sessions.remove(session);
+                    }
+                } else {
+                    sessions.remove(session); // 移除已关闭的会话
+                }
+            }
+        }
+    }
+
+}

+ 22 - 0
fs-qw-api-msg/src/main/java/com/fs/app/socket/configurator/QwImConfigurator.java

@@ -0,0 +1,22 @@
+package com.fs.app.socket.configurator;
+
+import com.fs.app.exception.FSException;
+
+import javax.websocket.HandshakeResponse;
+import javax.websocket.server.HandshakeRequest;
+import javax.websocket.server.ServerEndpointConfig;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class QwImConfigurator extends ServerEndpointConfig.Configurator {
+
+    @Override
+    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
+        Map<String, List<String>> parameterMap = request.getParameterMap();
+        List<String> token = parameterMap.get("token");
+        if (Objects.isNull(token)) {
+            throw new FSException("Unauthorized access to WebSocket endpoint.");
+        }
+    }
+}

+ 3 - 3
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/DataScopeAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataScopeAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.DataScope;
 import com.fs.common.core.domain.BaseEntity;
@@ -7,8 +7,8 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyRole;
 import com.fs.company.domain.CompanyUser;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.Signature;
 import org.aspectj.lang.annotation.Aspect;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/DataSourceAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/DataSourceAspect.java

@@ -1,8 +1,8 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.DataSource;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.datasource.DynamicDataSourceContextHolder;
+import com.fs.core.datasource.DynamicDataSourceContextHolder;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;

+ 5 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/LogAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/LogAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
@@ -9,10 +9,10 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.CompanyOperLog;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.Signature;
 import org.aspectj.lang.annotation.AfterReturning;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/aspectj/RateLimiterAspect.java → fs-qw-api-msg/src/main/java/com/fs/core/aspectj/RateLimiterAspect.java

@@ -1,4 +1,4 @@
-package com.fs.framework.aspectj;
+package com.fs.core.aspectj;
 
 import com.fs.common.annotation.RateLimiter;
 import com.fs.common.enums.LimitType;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ApplicationConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ApplicationConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ArrayStringTypeHandler.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ArrayStringTypeHandler.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import org.apache.ibatis.type.BaseTypeHandler;
 import org.apache.ibatis.type.JdbcType;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/CaptchaConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/CaptchaConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.google.code.kaptcha.impl.DefaultKaptcha;
 import com.google.code.kaptcha.util.Config;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/config/DataSourceConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/DataSourceConfig.java

@@ -1,10 +1,10 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
 import com.alibaba.druid.util.Utils;
 import com.fs.common.enums.DataSourceType;
-import com.fs.framework.datasource.DynamicDataSource;
+import com.fs.core.datasource.DynamicDataSource;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.ConfigurationProperties;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/FastJson2JsonRedisSerializer.java → fs-qw-api-msg/src/main/java/com/fs/core/config/FastJson2JsonRedisSerializer.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.parser.ParserConfig;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/FilterConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/FilterConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.filter.RepeatableFilter;
 import com.fs.common.filter.XssFilter;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/KaptchaTextCreator.java → fs-qw-api-msg/src/main/java/com/fs/core/config/KaptchaTextCreator.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.google.code.kaptcha.text.impl.DefaultTextCreator;
 

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/MyBatisConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/MyBatisConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import org.apache.ibatis.io.VFS;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/RedisConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/RedisConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/config/ResourcesConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ResourcesConfig.java

@@ -1,8 +1,8 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.config.FSConfig;
 import com.fs.common.constant.Constants;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
+import com.fs.core.interceptor.RepeatSubmitInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

+ 6 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/config/SecurityConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/SecurityConfig.java

@@ -1,9 +1,9 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 
-import com.fs.framework.security.filter.JwtAuthenticationTokenFilter;
-import com.fs.framework.security.handle.AuthenticationEntryPointImpl;
-import com.fs.framework.security.handle.LogoutSuccessHandlerImpl;
+import com.fs.core.security.filter.JwtAuthenticationTokenFilter;
+import com.fs.core.security.handle.AuthenticationEntryPointImpl;
+import com.fs.core.security.handle.LogoutSuccessHandlerImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpMethod;
@@ -106,7 +106,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                         "/**/*.html",
                         "/**/*.css",
                         "/**/*.js",
-                        "/profile/**"
+                        "/profile/**",
+                        "/qwImSocket/**"
                 ).permitAll()
 
                 .antMatchers("/**").anonymous()

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ServerConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ServerConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.utils.ServletUtils;
 import org.springframework.stereotype.Component;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/SwaggerConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/SwaggerConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.config.FSConfig;
 import io.swagger.annotations.ApiOperation;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/ThreadPoolConfig.java → fs-qw-api-msg/src/main/java/com/fs/core/config/ThreadPoolConfig.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config;
+package com.fs.core.config;
 
 import com.fs.common.utils.Threads;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;

+ 17 - 0
fs-qw-api-msg/src/main/java/com/fs/core/config/WebSocketConfig.java

@@ -0,0 +1,17 @@
+package com.fs.core.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+    /**
+     * ServerEndpointExporter 作用
+     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
+     */
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+}

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/config/properties/DruidProperties.java → fs-qw-api-msg/src/main/java/com/fs/core/config/properties/DruidProperties.java

@@ -1,4 +1,4 @@
-package com.fs.framework.config.properties;
+package com.fs.core.config.properties;
 
 import com.alibaba.druid.pool.DruidDataSource;
 import org.springframework.beans.factory.annotation.Value;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/datasource/DynamicDataSource.java → fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSource.java

@@ -1,4 +1,4 @@
-package com.fs.framework.datasource;
+package com.fs.core.datasource;
 
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java → fs-qw-api-msg/src/main/java/com/fs/core/datasource/DynamicDataSourceContextHolder.java

@@ -1,4 +1,4 @@
-package com.fs.framework.datasource;
+package com.fs.core.datasource;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/exception/GlobalExceptionHandler.java → fs-qw-api-msg/src/main/java/com/fs/core/exception/GlobalExceptionHandler.java

@@ -1,4 +1,4 @@
-package com.fs.framework.exception;
+package com.fs.core.exception;
 
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.domain.AjaxResult;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/interceptor/RepeatSubmitInterceptor.java → fs-qw-api-msg/src/main/java/com/fs/core/interceptor/RepeatSubmitInterceptor.java

@@ -1,4 +1,4 @@
-package com.fs.framework.interceptor;
+package com.fs.core.interceptor;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.RepeatSubmit;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/interceptor/impl/SameUrlDataInterceptor.java → fs-qw-api-msg/src/main/java/com/fs/core/interceptor/impl/SameUrlDataInterceptor.java

@@ -1,4 +1,4 @@
-package com.fs.framework.interceptor.impl;
+package com.fs.core.interceptor.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.constant.Constants;
@@ -6,7 +6,7 @@ import com.fs.common.core.redis.RedisCache;
 import com.fs.common.filter.RepeatedlyRequestWrapper;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.http.HttpHelper;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
+import com.fs.core.interceptor.RepeatSubmitInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/AsyncManager.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/AsyncManager.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager;
+package com.fs.core.manager;
 
 import com.fs.common.utils.Threads;
 import com.fs.common.utils.spring.SpringUtils;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/ShutdownManager.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/ShutdownManager.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager;
+package com.fs.core.manager;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/manager/factory/AsyncFactory.java → fs-qw-api-msg/src/main/java/com/fs/core/manager/factory/AsyncFactory.java

@@ -1,4 +1,4 @@
-package com.fs.framework.manager.factory;
+package com.fs.core.manager.factory;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.utils.LogUtils;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/LoginBody.java → fs-qw-api-msg/src/main/java/com/fs/core/security/LoginBody.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 /**
  * 用户登录对象

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/LoginUser.java → fs-qw-api-msg/src/main/java/com/fs/core/security/LoginUser.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fs.company.domain.Company;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/SecurityUtils.java → fs-qw-api-msg/src/main/java/com/fs/core/security/SecurityUtils.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security;
+package com.fs.core.security;
 
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.exception.CustomException;

+ 4 - 4
fs-qw-api-msg/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java → fs-qw-api-msg/src/main/java/com/fs/core/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,10 +1,10 @@
-package com.fs.framework.security.filter;
+package com.fs.core.security.filter;
 
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.security.SecurityUtils;
-import com.fs.framework.service.TokenService;
+import com.fs.core.security.LoginUser;
+import com.fs.core.security.SecurityUtils;
+import com.fs.core.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/security/handle/AuthenticationEntryPointImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/security/handle/AuthenticationEntryPointImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security.handle;
+package com.fs.core.security.handle;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.constant.HttpStatus;

+ 5 - 5
fs-qw-api-msg/src/main/java/com/fs/framework/security/handle/LogoutSuccessHandlerImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/security/handle/LogoutSuccessHandlerImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.security.handle;
+package com.fs.core.security.handle;
 
 import com.alibaba.fastjson.JSON;
 import com.fs.common.constant.Constants;
@@ -6,10 +6,10 @@ import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
+import com.fs.core.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.core.Authentication;

+ 4 - 4
fs-qw-api-msg/src/main/java/com/fs/framework/service/CompanyLoginService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyLoginService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCache;
@@ -7,9 +7,9 @@ import com.fs.common.exception.user.CaptchaException;
 import com.fs.common.exception.user.CaptchaExpireException;
 import com.fs.common.exception.user.UserPasswordNotMatchException;
 import com.fs.common.utils.MessageUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.manager.AsyncManager;
+import com.fs.core.manager.factory.AsyncFactory;
+import com.fs.core.security.LoginUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;

+ 1 - 1
fs-qw-api-msg/src/main/java/com/fs/framework/service/CompanyPermissionService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/CompanyPermissionService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyMenuService;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/PermissionService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/PermissionService.java

@@ -1,9 +1,9 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyRole;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/TokenService.java → fs-qw-api-msg/src/main/java/com/fs/core/service/TokenService.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCache;
@@ -7,7 +7,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.AddressUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.common.utils.uuid.IdUtils;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import eu.bitwalker.useragentutils.UserAgent;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;

+ 2 - 2
fs-qw-api-msg/src/main/java/com/fs/framework/service/UserDetailsServiceImpl.java → fs-qw-api-msg/src/main/java/com/fs/core/service/UserDetailsServiceImpl.java

@@ -1,4 +1,4 @@
-package com.fs.framework.service;
+package com.fs.core.service;
 
 
 import com.fs.common.enums.UserStatus;
@@ -8,7 +8,7 @@ import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.framework.security.LoginUser;
+import com.fs.core.security.LoginUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;

+ 1 - 1
fs-qw-api-msg/src/main/resources/mybatis/mybatis-config.xml

@@ -13,7 +13,7 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 	</settings>
 
 	<typeHandlers>
-		<typeHandler handler="com.fs.framework.config.ArrayStringTypeHandler"/>
+		<typeHandler handler="com.fs.core.config.ArrayStringTypeHandler"/>
 	</typeHandlers>
 
 </configuration>

+ 10 - 0
fs-service-system/src/main/java/com/fs/company/domain/CompanyUser.java

@@ -136,6 +136,9 @@ public class CompanyUser extends BaseEntity
     /** 微信小程序OPENID(如果有小程序授权) */
     private String  maOpenId;
 
+    /** 是否需要单独注册会员,1-是,0-否(用于个微销售分享看课) */
+    private Integer isNeedRegisterMember;
+
     public Integer getIsAudit() {
         return isAudit;
     }
@@ -473,4 +476,11 @@ public class CompanyUser extends BaseEntity
         this.maOpenId = maOpenId;
     }
 
+    public Integer getIsNeedRegisterMember() {
+        return isNeedRegisterMember;
+    }
+
+    public void setIsNeedRegisterMember(Integer isNeedRegisterMember) {
+        this.isNeedRegisterMember = isNeedRegisterMember;
+    }
 }

+ 5 - 35
fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java

@@ -186,41 +186,6 @@ public interface CompanyUserMapper
     @Select("select * from  qw_user  where corp_id=#{corpId} and company_id=#{companyId}")
     List<QwUserVO> selectCompanyQwUserList(@Param("corpId") String corpId,@Param("companyId")Long companyId);
 
-    @Select({"<script> " +
-            "select u.*, d.dept_name, d.leader from company_user u\n" +
-            "        left join company_dept d on u.dept_id = d.dept_id\n" +
-            "        where u.del_flag = '0'\n" +
-            "        <if test=\"userName != null and userName != ''\">\n" +
-            "            AND u.user_name like concat('%', #{userName}, '%')\n" +
-            "        </if>\n" +
-            "\n" +
-            "        <if test=\"nickName != null and nickName != ''\">\n" +
-            "            AND u.nick_name like concat( #{nickName}, '%')\n" +
-            "        </if>\n" +
-            "        <if test=\"companyId != null and companyId != ''\">\n" +
-            "            AND u.company_id = #{companyId}\n" +
-            "        </if>\n" +
-            "        <if test=\"status != null and status != ''\">\n" +
-            "            AND u.status = #{status}\n" +
-            "        </if>\n" +
-            "        <if test=\"qwStatus != null \">\n" +
-            "            AND u.qw_status = #{qwStatus} \n" +
-            "        </if>\n" +
-            "        <if test=\"phonenumber != null and phonenumber != ''\">\n" +
-            "            AND u.phonenumber like concat('%', #{phonenumber}, '%')\n" +
-            "        </if>\n" +
-            "        <if test=\"beginTime != null and beginTime != ''\"><!-- 开始时间检索 -->\n" +
-            "            AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')\n" +
-            "        </if>\n" +
-            "        <if test=\"endTime != null and endTime != ''\"><!-- 结束时间检索 -->\n" +
-            "            AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')\n" +
-            "        </if>\n" +
-            "        <if test=\"deptId != null and deptId != 0\">\n" +
-            "            AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{deptId}, ancestors) ))\n" +
-            "        </if>\n" +
-            "        <!-- 数据范围过滤 -->\n" +
-            "        ${params.dataScope}"+
-            "</script>"})
     List<CompanyUserQwListVO> selectCompanyUserQwListVO(CompanyUserQwParam user);
 
 
@@ -291,4 +256,9 @@ public interface CompanyUserMapper
     List<Long> selectUserAllCompanyUserId(@Param("companyUserId") Long companyUserId);
 
     String selectCompanyUserNameUserById(@Param("userId") Long userId);
+
+    void uploadQrCode(@Param("userId") String userId, @Param("url") String url);
+
+    int setIsRegisterMember(@Param("status") boolean status, @Param("userIds")List<Long> userIds);
+
 }

+ 12 - 0
fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -12,7 +12,9 @@ import com.fs.his.vo.CitysAreaVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -128,6 +130,7 @@ public interface ICompanyUserService {
 
     List<CompanyUserQwListVO> selectCompanyUserQwListVO(CompanyUserQwParam user);
 
+    String uploadQrCode(MultipartFile file,String userId) throws IOException;
     List<OptionsVO> selectCompanyUserBySalesman();
 
     List<CompanyQwUserByIdsVo> selectCompanyQwUserByIds(List<Long> qwUserIdList);
@@ -191,4 +194,13 @@ public interface ICompanyUserService {
      * @return  list
      */
     List<OptionsVO> selectCompanyUserListByMap(Map<String, Object> params);
+
+    /**
+     * 批量设置销售的会员是否需要单独注册
+     * @param status true-是,false-否
+     * @param userIds 销售ids
+     * @return
+     */
+    Boolean setIsRegisterMember(boolean status,  List<Long> userIds);
+
 }

+ 35 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.annotation.DataScope;
 import com.fs.common.core.domain.R;
+import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
+import com.fs.common.exception.file.OssException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.*;
@@ -23,10 +25,14 @@ import com.fs.qw.vo.QwUserVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.store.mapper.FsUserMapper;
 import com.fs.store.service.IFsCityService;
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -397,6 +403,25 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.selectCompanyUserQwListVO(user);
     }
 
+    @Override
+    public String uploadQrCode(MultipartFile file, String userId) throws IOException {
+        if (file.isEmpty())
+        {
+            throw new OssException("上传文件不能为空");
+        }
+        // 上传文件
+        String fileName = file.getOriginalFilename();
+        String suffix = fileName.substring(fileName.lastIndexOf("."));
+        CloudStorageService storage = OSSFactory.build();
+        String url = storage.uploadSuffix(file.getBytes(), suffix);
+
+        if(userId == null) {
+            throw new CustomException("上传二维码失败!userId 为空!");
+        }
+        companyUserMapper.uploadQrCode(userId,url);
+        return url;
+    }
+
     @Override
     public List<OptionsVO> selectCompanyUserBySalesman() {
 //        return companyUserMapper.selectCompanyUserBySalesman();
@@ -484,6 +509,16 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.selectCompanyUserListByMap(params);
     }
 
+    @Override
+    public Boolean setIsRegisterMember(boolean status, List<Long> userIds) {
+        try {
+           companyUserMapper.setIsRegisterMember(status, userIds);
+        } catch (RuntimeException e) {
+            throw new ServiceException("操作异常");
+        }
+        return true;
+    }
+
     /**
      * 批量审核用户
      * @param userIds 用户ID集合

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

@@ -27,6 +27,8 @@ public class CourseConfig implements Serializable {
     private BigDecimal moneyPri;//充值手续费百分比
     private BigDecimal redPackageMoney;//充值手续费百分比
     private List<DisabledTimeVo> disabledTimeList;//充值手续费百分比
+    private String companyUserQRCode;// 默认客服二维码图片
+    private String courseLogo;//课程Logo
 
     @Data
     public static class DisabledTimeVo{

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

@@ -99,4 +99,6 @@ public class FsUserCoursePeriod
     private List<Long> companyIdList;
 
     private Integer maxViewNum;
+
+    private String courseLogo;
 }

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

@@ -320,4 +320,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     Map<String, Object> selectSumByUserIdAndVideoId(@Param("userId") Long userId, @Param("videoId") Long videoId);
 
     void batchUpdateFsUserWatchLog(@Param("list") List<FsCourseWatchLog> logs);
+
+    @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and send_type = 1")
+    FsCourseWatchLog getCourseWatchLogByUser(@Param("userId") Long userId, @Param("videoId") Long videoId);
 }

+ 55 - 33
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -8,6 +8,7 @@ import com.fs.common.BeanCopyUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.enums.BizResponseEnum;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.date.DateUtil;
@@ -935,45 +936,54 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             return ResponseResult.fail(405,"当前销售不存在");
         }
 
-        //判断:1、如果没有绑定销售,就提示;
+        //判断:1、如果没有绑定销售,就返回给客服的微信图片;
         //2、如果只绑定了当前销售,需要添加看课记录(正常流程);
         //3、以上都不是,则标识重粉,需要加入关系表,并打上重粉标签
         if(fsUser.getCompanyUserId() == null) {
-            return ResponseResult.fail(503, "暂时未绑定销售,请联系管理员");
+            return ResponseResult.fail(BizResponseEnum.DATA_NOT_EXIST, getCompanyUserQRCode(companyUser));
         }
-        if(companyUser.getUserId().equals(fsUser.getCompanyUserId())){
-            //查询看课记录
-            FsCourseWatchLog log = new FsCourseWatchLog();
-            log.setUserId(param.getUserId());
-            log.setCompanyUserId(param.getCompanyUserId());
-            log.setVideoId(param.getVideoId());
-            List<FsCourseWatchLog> fsCourseWatchLogs = courseWatchLogMapper.selectFsCourseWatchLogList(log);
-
-            // 获取课程所属项目id
-            FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
-            Long courseProject = null;
-            if(fsUserCourse != null){
-                courseProject = fsUserCourse.getProject();
-            }
-            //如果存在,则更新
-            if (fsCourseWatchLogs != null && !fsCourseWatchLogs.isEmpty()){
-                FsCourseWatchLog updateLog = new FsCourseWatchLog();
-                updateLog.setPeriodId(param.getPeriodId());
-                updateLog.setProject(courseProject);
-                updateLog.setUpdateTime(new Date());
-                courseWatchLogMapper.updateFsCourseWatchLog(updateLog);
-            } else {
-                //如果是会员,则需要添加看课记录
-                FsCourseWatchLog fsCourseWatchLog = new FsCourseWatchLog();
-                BeanUtils.copyProperties(param, fsCourseWatchLog);
-                fsCourseWatchLog.setSendType(1);
-                fsCourseWatchLog.setDuration(0L);
-                fsCourseWatchLog.setCreateTime(new Date());
-                fsCourseWatchLog.setLogType(1);
-                fsCourseWatchLog.setProject(courseProject);
-                courseWatchLogMapper.insertFsCourseWatchLog(fsCourseWatchLog);
+
+        // 如果开启了黑名单审核,需要提示
+        if(fsUser.getStatus() == 0) {
+//            return ResponseResult.fail(505, "管理开启了会员审核,请等待审核");
+            return ResponseResult.fail(BizResponseEnum.WAIT_APPROVAL,getCompanyUserQRCode(companyUser));
+        }
+
+        //查询看课记录
+//        FsCourseWatchLog watchCourseVideo = courseWatchLogMapper.getWatchCourseVideoByFsUser(param.getUserId(), param.getVideoId(), param.getCompanyUserId());
+        FsCourseWatchLog watchCourseVideo = courseWatchLogMapper.getCourseWatchLogByUser(param.getUserId(), param.getVideoId());
+        // 获取课程所属项目id
+        FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
+        Long courseProject = null;
+        if(fsUserCourse != null){
+            courseProject = fsUserCourse.getProject();
+        }
+
+        //添加判断:该用户是否已经存在此课程的看课记录,并且看课记录的销售id不是传入的销售id
+        if(watchCourseVideo != null){
+            if(!watchCourseVideo.getCompanyUserId().equals(param.getCompanyUserId())) {
+                //提示
+                return ResponseResult.fail(504, "已看过其他销售分享的此课程,不能重复观看");
             }
+
+            FsCourseWatchLog updateLog = new FsCourseWatchLog();
+            updateLog.setPeriodId(param.getPeriodId());
+            updateLog.setProject(courseProject);
+            updateLog.setUpdateTime(new Date());
+            courseWatchLogMapper.updateFsCourseWatchLog(updateLog);
         } else {
+            FsCourseWatchLog fsCourseWatchLog = new FsCourseWatchLog();
+            BeanUtils.copyProperties(param, fsCourseWatchLog);
+            fsCourseWatchLog.setSendType(1);
+            fsCourseWatchLog.setDuration(0L);
+            fsCourseWatchLog.setCreateTime(new Date());
+            fsCourseWatchLog.setLogType(1);
+            fsCourseWatchLog.setProject(courseProject);
+            courseWatchLogMapper.insertFsCourseWatchLog(fsCourseWatchLog);
+        }
+
+        // 判断是否重粉
+        if(!companyUser.getUserId().equals(fsUser.getCompanyUserId())){
             FsUserCompanyUser fsUserCompanyUser = new FsUserCompanyUser();
             fsUserCompanyUser.setIsRepeatFans(1);
             fsUserCompanyUser.setUserId(param.getUserId());
@@ -995,6 +1005,18 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         return ResponseResult.ok(Boolean.TRUE);
     }
 
+    private String getCompanyUserQRCode(CompanyUser companyUser) {
+        String companyUserQRCode;
+        if(StringUtils.isNotEmpty(companyUser.getQrCodeWeixin())){
+             companyUserQRCode = companyUser.getQrCodeWeixin();
+        } else {
+            String json = configService.selectConfigByKey("course.config");
+            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+             companyUserQRCode = config.getCompanyUserQRCode();
+        }
+        return companyUserQRCode;
+    }
+
     @Override
     public ResponseResult<FsUserCourseVideoLinkDetailsVO> getLinkCourseVideoDetails(FsUserCourseVideoLinkParam param) {
 //        FsUserCoursePeriodDays periodDays = new FsUserCoursePeriodDays();

+ 9 - 6
fs-service-system/src/main/java/com/fs/fastGpt/service/AiHookService.java

@@ -1,6 +1,7 @@
 package com.fs.fastGpt.service;
 
 import com.fs.common.core.domain.R;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwHookApi.vo.QwHookVO;
 
 public interface AiHookService {
@@ -19,11 +20,13 @@ public interface AiHookService {
 
     /**
      * 保存企微聊天信息
-     * @param qwUserId  企微用户ID
-     * @param userId    用户ID
-     * @param content   聊天内容
-     * @param uuid      UUID
-     * @param sendType  发送者类型 1用户 2客服
+     *
+     * @param qwUserId 企微用户ID
+     * @param userId   用户ID
+     * @param content  聊天内容
+     * @param uuid     UUID
+     * @param sendType 发送者类型 1用户 2客服
+     * @param json     消息json
      */
-    void saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType);
+    QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json);
 }

+ 35 - 8
fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -28,6 +28,7 @@ import com.fs.fastgptApi.vo.AudioVO;
 import com.fs.qw.domain.*;
 import com.fs.qw.mapper.*;
 import com.fs.qw.service.*;
+import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwApi.param.QwSendMsgParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.qwHookApi.param.QwHookSendMsgParam;
@@ -1261,27 +1262,29 @@ public class AiHookServiceImpl implements AiHookService {
 
     /**
      * 保存企微聊天信息
-     * @param qwUserId  企微用户ID
-     * @param userId    用户ID
-     * @param content   聊天内容
-     * @param uuid      UUID
-     * @param sendType  发送者类型 1用户 2客服
+     *
+     * @param qwUserId 企微用户ID
+     * @param userId   用户ID
+     * @param content  聊天内容
+     * @param uuid     UUID
+     * @param sendType 发送者类型 1用户 2客服
+     * @param json     消息json
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType) {
+    public QwMessageListVO saveQwMsg(Long qwUserId, Long userId, String content, String uuid, int sendType, String json) {
         // 查询企微用户
         QwUser qwUser = qwUserService.selectQwUserById(qwUserId);
         if (Objects.isNull(qwUser)){
             log.warn("企微用户不存在 qwUserId: {}", qwUserId);
-            return;
+            return null;
         }
 
         // 查询外部联系人
         QwExternalContact qwExternalContact = getExternalContact(userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
         if (Objects.isNull(qwExternalContact)){
             log.warn("外部联系人不存在 userId: {}, uuid: {}, serverId: {}, corpId: {}, qwUserId: {}", userId, uuid, qwUser.getServerId(), qwUser.getCorpId(), qwUser.getQwUserId());
-            return;
+            return null;
         }
 
         // 查询会话
@@ -1316,6 +1319,7 @@ public class AiHookServiceImpl implements AiHookService {
         qwMsg.setCompanyId(qwUser.getCompanyId());
         qwMsg.setCompanyUserId(qwUser.getCompanyUserId());
         qwMsg.setMsgType(1);
+        qwMsg.setMsgJson(json);
         qwMsg.setStatus(0);
         qwMsg.setQwUserId(qwSession.getQwUserId());
         qwMsg.setQwExtId(qwSession.getQwExtId());
@@ -1324,6 +1328,29 @@ public class AiHookServiceImpl implements AiHookService {
         qwMsg.setCreateTime(new Date());
         qwMsgMapper.insertQwMsg(qwMsg);
         log.debug("保存企微聊天记录 msgId: {}", qwMsg.getMsgId());
+
+        // 组装返回消息结构
+        QwMessageListVO listVO = new QwMessageListVO();
+        QWFromUser qwFromUser = new QWFromUser();
+        if (sendType == 1) {
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwExtId()));
+            qwFromUser.setAvatar(qwMsg.getAvatar());
+            qwFromUser.setDisplayName(qwMsg.getNickName());
+        }else if(sendType == 2){
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwUserId()));
+            qwFromUser.setDisplayName(qwUser.getQwUserName());
+            qwFromUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20241231/22a765a96da247d1b83ea94fef438a41.png");
+        }
+
+        listVO.setCompanyId(qwUser.getCompanyId());
+        listVO.setType("text");
+        listVO.setStatus("succeed");
+        listVO.setFromUser(qwFromUser);
+        listVO.setSendTime(qwMsg.getCreateTime().getTime());
+        listVO.setId(qwMsg.getMsgId().toString());
+        listVO.setContent(qwMsg.getContent());
+        listVO.setToContactId(String.valueOf(qwSession.getSessionId()));
+        return listVO;
     }
 
     /**

+ 1 - 1
fs-service-system/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -41,7 +41,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
     @Select("select welcome_text,qw_user_name,qw_user_id from qw_user where id = #{id}")
     public QwUser selectQwUserByIdByWeComeText(@Param("id") Long id);
     @Select("select * from qw_user where qw_user_id = #{qwUserId} and corp_id = #{corpId} ")
-    public QwUser selectQwUserByIdByWeComeText(@Param("qwUserId") String qwUserId, @Param("corpId") String corpId);
+    public QwUser selectQwUserByIdByWeComeText2(@Param("qwUserId") String qwUserId, @Param("corpId") String corpId);
     /**
      * 根据companyUserId查询企微用户
      */

+ 2 - 0
fs-service-system/src/main/java/com/fs/qw/param/QwSessionParam.java

@@ -7,4 +7,6 @@ import lombok.Data;
 public class QwSessionParam extends BaseQueryParam {
     private String conversationId;
     private Long userId;//企微id
+    // 消息ID
+    private Long msgId;
 }

+ 99 - 7
fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java

@@ -2,12 +2,12 @@ package com.fs.qw.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.http.HttpRequest;
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.his.config.FsSysConfig;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.qw.Bean.MsgBean;
@@ -23,6 +23,8 @@ import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.QwContactListVO;
 import com.fs.qw.vo.QwMessageListVO;
 import com.fs.qwHookApi.vo.QwHookMsgVO;
+import com.fs.wxwork.dto.*;
+import com.fs.wxwork.service.WxWorkService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -50,6 +52,8 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
 
     @Autowired
     private ConfigUtil configUtil;
+    @Autowired
+    private WxWorkService wxWorkService;
 
     /**
      * 查询企微聊天记录
@@ -244,12 +248,96 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
 
     @Override
     public R sendMsg(QwMsgSendParam param) {
-        FsSysConfig config = configUtil.getSysConfig();
-        String domainName = config.getHookUrl();
-        HttpRequest.post(domainName+"/app/qwmsg/sendMsg")
-                .body(JSON.toJSONString(param),"application/json;charset=UTF-8")
-                .execute().body();
-        return R.ok();
+        if (StringUtils.isBlank(param.getContent())) {
+            return R.error("消息内容不能为空");
+        }
+
+        if (Objects.isNull(param.getSessionId())) {
+            return R.error("会话ID不能为空");
+        }
+
+        // 查询会话
+        QwSession qwSession = qwSessionMapper.selectQwSessionBySessionId(param.getSessionId());
+        if (Objects.isNull(qwSession)) {
+            return R.error("会话不存在");
+        }
+
+        // 外部联系人
+        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactById(Long.valueOf(qwSession.getQwExtId()));
+        if (Objects.isNull(qwExternalContact)) {
+            return R.error("联系人不存在");
+        }
+
+        // 企微用户
+        QwUser qwUser = qwUserMapper.selectQwUserById(Long.parseLong(qwSession.getQwUserId()));
+        if (Objects.isNull(qwUser)) {
+            return R.error("用户不存在");
+        }
+
+        Long serverId = qwUser.getServerId();
+        String uuid = qwUser.getUid();
+        String openId = qwExternalContact.getExternalUserId();
+        String sCorpId = qwUser.getCorpId();
+
+        WxWorkUserId2VidDTO params = new WxWorkUserId2VidDTO();
+        params.setOpenid(Collections.singletonList(openId));
+        params.setUuid(uuid);
+        params.setScorpid(sCorpId);
+        WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> listWxWorkResponseDTO = wxWorkService.UserId2Vid(params, serverId);
+
+        if (listWxWorkResponseDTO.getErrcode() != 0) {
+            return R.error(listWxWorkResponseDTO.getErrmsg());
+        }
+
+        // 发送消息
+        WxWorkSendTextMsgDTO textMsgDTO = new WxWorkSendTextMsgDTO();
+        textMsgDTO.setUuid(uuid);
+        textMsgDTO.setSend_userid(listWxWorkResponseDTO.getData().get(0).getUser_id());
+        textMsgDTO.setIsRoom(false);
+        textMsgDTO.setContent(param.getContent());
+        WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> msgRespDTOWxWorkResponseDTO = wxWorkService.SendTextMsg(textMsgDTO, serverId);
+
+        if (msgRespDTOWxWorkResponseDTO.getErrcode() != 0) {
+            return R.error(msgRespDTOWxWorkResponseDTO.getErrmsg());
+        }
+
+        String msg = msgRespDTOWxWorkResponseDTO.getErrmsg();
+        if ("ok".equals(msg)) {
+            // 消息保存本地数据库
+            QwMsg qwMsg = new QwMsg();
+            qwMsg.setContent(param.getContent());
+            qwMsg.setSessionId(qwSession.getSessionId());
+            qwMsg.setSendType(2);
+            qwMsg.setCompanyId(qwUser.getCompanyId());
+            qwMsg.setCompanyUserId(qwUser.getCompanyUserId());
+            qwMsg.setMsgType(1);
+            qwMsg.setMsgJson(JSONObject.toJSONString(textMsgDTO));
+            qwMsg.setStatus(0);
+            qwMsg.setQwUserId(qwSession.getQwUserId());
+            qwMsg.setQwExtId(qwSession.getQwExtId());
+            qwMsg.setAvatar(qwExternalContact.getAvatar());
+            qwMsg.setNickName(qwExternalContact.getRemark());
+            qwMsg.setCreateTime(new Date());
+            qwMsgMapper.insertQwMsg(qwMsg);
+
+            // 组装返回消息结构
+            QwMessageListVO listVO = new QwMessageListVO();
+            QWFromUser qwFromUser = new QWFromUser();
+            qwFromUser.setId(Long.parseLong(qwMsg.getQwUserId()));
+            qwFromUser.setDisplayName(qwUser.getQwUserName());
+            qwFromUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20241231/22a765a96da247d1b83ea94fef438a41.png");
+
+            listVO.setType("text");
+            listVO.setStatus("succeed");
+            listVO.setFromUser(qwFromUser);
+            listVO.setSendTime(qwMsg.getCreateTime().getTime());
+            listVO.setId(qwMsg.getMsgId().toString());
+            listVO.setContent(qwMsg.getContent());
+            listVO.setToContactId(String.valueOf(param.getSessionId()));
+            return R.ok().put("data", listVO);
+        } else {
+            return R.error(msg);
+        }
     }
 
     @Override
@@ -314,6 +402,7 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 qwContactListVOS.add(listVO);
                 break;
             }
+            listVO.setMsgId(qwMsgs.get(0).getMsgId());
             listVO.setLastContent(qwMsgs.get(0).getContent());
             listVO.setLastSendTime(qwMsgs.get(0).getCreateTime().getTime());
             listVO.setUnread(0);
@@ -327,6 +416,9 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
         LambdaQueryWrapper<QwMsg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.select(QwMsg.class, q -> !q.getColumn().equals("remark"));
         lambdaQueryWrapper.eq(QwMsg::getSessionId, param.getConversationId());
+        if (Objects.nonNull(param.getMsgId())) {
+            lambdaQueryWrapper.gt(QwMsg::getMsgId, param.getMsgId());
+        }
         lambdaQueryWrapper.orderByDesc(QwMsg::getMsgId);
         List<QwMsg> records = qwMsgMapper.selectList(lambdaQueryWrapper);
         return records;

+ 1 - 1
fs-service-system/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java

@@ -1008,7 +1008,7 @@ public class QwUserServiceImpl implements IQwUserService
             return R.ok("登录成功");
         }
         WxWorkSetCallbackUrlDTO wxWorkSetCallbackUrlDTO = new WxWorkSetCallbackUrlDTO();
-        wxWorkSetCallbackUrlDTO.setUrl("http://c38da856.natappfree.cc/msg/callback/"+serverId);
+        wxWorkSetCallbackUrlDTO.setUrl("http://1.14.207.209:8008/msg/callback/"+serverId);
         wxWorkSetCallbackUrlDTO.setUuid(data.getUuid());
         wxWorkService.SetCallbackUrl(wxWorkSetCallbackUrlDTO,serverId);
 

+ 2 - 1
fs-service-system/src/main/java/com/fs/qw/vo/QwContactListVO.java

@@ -14,5 +14,6 @@ public class QwContactListVO {
     private Long roomId;
     private Long lastSendTime;
     private String lastContent;
-
+    // 消息ID
+    private Long msgId;
 }

+ 3 - 0
fs-service-system/src/main/java/com/fs/qw/vo/QwMessageListVO.java

@@ -1,5 +1,6 @@
 package com.fs.qw.vo;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.fs.qw.domain.QWFromUser;
 import com.fs.qw.domain.QwMsg;
 import lombok.Data;
@@ -19,6 +20,8 @@ public class QwMessageListVO {
     private Integer duration; //时长
     private String toContactId;
     private QWFromUser fromUser;
+    @JSONField(serialize = false)
+    private Long companyId;
 
     //获取fromUser
     public  QWFromUser getQwFromUser(Long senderId,QwMsg qwMsg){

+ 57 - 61
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -55,8 +55,7 @@ import java.util.stream.Collectors;
  */
 @Service
 @AllArgsConstructor
-public class QwSopTempServiceImpl implements IQwSopTempService
-{
+public class QwSopTempServiceImpl implements IQwSopTempService {
     private final QwSopTempMapper qwSopTempMapper;
     private final FastGptChatReplaceWordsMapper fastGptChatReplaceWordsMapper;
     private final IQwSopTempRulesService qwSopTempRulesService;
@@ -76,10 +75,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return sop模板
      */
     @Override
-    public QwSopTemp selectQwSopTempById(String id){
+    public QwSopTemp selectQwSopTempById(String id) {
 //        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
         QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
-        if(qwSopTemp == null) return null;
+        if (qwSopTemp == null) return null;
         List<QwSopTempDay> qwSopTempDays = qwSopTempDayService.listByTempId(id);
         qwSopTemp.setList(qwSopTempDays);
 //        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByTempId(id);
@@ -107,8 +106,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return sop模板
      */
     @Override
-    public List<QwSopTemp> selectQwSopTempList(QwSopTemp qwSopTemp)
-    {
+    public List<QwSopTemp> selectQwSopTempList(QwSopTemp qwSopTemp) {
         return qwSopTempMapper.selectQwSopTempList(qwSopTemp);
     }
 
@@ -119,7 +117,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int insertQwSopTemp(QwSopTemp qwSopTemp){
+    public int insertQwSopTemp(QwSopTemp qwSopTemp) {
         qwSopTemp.setId(UUID.randomUUID().toString());
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         qwSopTemp.setCreateTime(sdf.format(new Date()));
@@ -145,7 +143,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int updateQwSopTemp(QwSopTemp qwSopTemp){
+    public int updateQwSopTemp(QwSopTemp qwSopTemp) {
         return qwSopTempMapper.updateQwSopTemp(qwSopTemp);
     }
 
@@ -156,8 +154,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempByIds(String[] ids)
-    {
+    public int deleteQwSopTempByIds(String[] ids) {
         return qwSopTempMapper.deleteQwSopTempByIds(ids);
     }
 
@@ -183,8 +180,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempById(String id)
-    {
+    public int deleteQwSopTempById(String id) {
         return qwSopTempMapper.deleteQwSopTempById(id);
     }
 
@@ -213,11 +209,11 @@ public class QwSopTempServiceImpl implements IQwSopTempService
             day.setSorts(day.getDayNum());
             day.setList(new ArrayList<>());
             List<String> timeList = new ArrayList<>();
-            if(temp.getTimeList() != null){
+            if (temp.getTimeList() != null) {
                 timeList = JSON.parseArray(JSON.toJSONString(temp.getTimeList()), String.class);
             }
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
-            if(e.getViewStartTime() == null){
+            if (e.getViewStartTime() == null) {
                 e.setViewStartTime(LocalTime.of(9, 0));
             }
             timeList.add(0, e.getViewStartTime().format(formatter));
@@ -234,11 +230,11 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                 rules.setVideoId(e.getVideoId());
                 rules.setSorts(sorts.getAndIncrement());
                 // 设置消息类型
-                if(rules.getSorts() == 0){
+                if (rules.getSorts() == 0) {
                     rules.setCourseType(0);
-                }else if(rules.getSorts() == 1){
+                } else if (rules.getSorts() == 1) {
                     rules.setCourseType(1);
-                }else{
+                } else {
                     rules.setCourseType(4);
                 }
                 QwSopTempContent content = new QwSopTempContent();
@@ -270,15 +266,14 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
         List<Long> videoIdList = PubFun.listToNewList(ruleList, QwSopTempRules::getVideoId);
         Map<Long, Optional<BigDecimal>> redMap;
-        if(!videoIdList.isEmpty()){
+        if (!videoIdList.isEmpty()) {
             List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByCompanyIdAndVideoIds(temp.getCompanyId(), videoIdList);
             redMap = redPackageList.stream().collect(Collectors.groupingBy(FsUserCourseVideoRedPackage::getVideoId, Collectors.mapping(FsUserCourseVideoRedPackage::getRedPacketMoney, Collectors.reducing((e1, e2) -> e1))));
-        }else{
+        } else {
             redMap = new HashMap<>();
         }
-
-        List<FsUserCourseVideoRedPackage> redPackage = ruleList.stream().filter(e -> e.getVideoId() != null).map(e -> {
-            FsUserCourseVideoRedPackage red = new FsUserCourseVideoRedPackage();
+        FsUserCourseVideoRedPackage red = new FsUserCourseVideoRedPackage();
+        List<FsUserCourseVideoRedPackage> redPackage = ruleList.stream().filter(e -> e.getVideoId() != null && e.getSorts() == 0).map(e -> {
             red.setCompanyId(temp.getCompanyId());
             red.setVideoId(e.getVideoId());
             red.setRedPacketMoney(redMap.getOrDefault(e.getVideoId(), Optional.of(courseConfig.getRedPackageMoney())).orElse(BigDecimal.ZERO));
@@ -292,15 +287,15 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     @Override
     public List<QwSopTempRedPackageVo> redList(String id) {
         List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(id);
-        if(CollectionUtils.isEmpty(dayList)){
+        if (CollectionUtils.isEmpty(dayList)) {
             return Collections.emptyList();
         }
         List<QwSopTempRules> rules = dayList.stream()
-                .filter(e->e!= null && e.getList()!=null)
+                .filter(e -> e != null && e.getList() != null)
                 .flatMap(e -> e.getList().stream())
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
-        if(rules.isEmpty()){
+        if (rules.isEmpty()) {
             return Collections.emptyList();
         }
         List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByRuleIds(PubFun.listToNewList(rules, QwSopTempRules::getId));
@@ -309,19 +304,19 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         Map<Long, FsUserCourseVideo> videoMap = PubFun.listToMapByGroupObject(videoList, FsUserCourseVideo::getVideoId);
         return rules.stream()
                 .filter(e -> e.getVideoId() != null && redMap.containsKey(e.getVideoId()) && videoMap.containsKey(e.getVideoId())).map(e -> {
-            FsUserCourseVideoRedPackage red = redMap.get(e.getVideoId());
-            FsUserCourseVideo video = videoMap.get(e.getVideoId());
-            QwSopTempRedPackageVo vo = new QwSopTempRedPackageVo();
-            vo.setId(red.getId());
-            vo.setRuleId(e.getId());
-            vo.setName(e.getName());
-            vo.setVideoId(e.getVideoId());
-            vo.setVideoName(video.getTitle());
-            vo.setCompanyId(red.getCompanyId());
-            vo.setRedPacketMoney(red.getRedPacketMoney());
-            vo.setDataType(red.getDataType());
-            return vo;
-        }).collect(Collectors.toList());
+                    FsUserCourseVideoRedPackage red = redMap.get(e.getVideoId());
+                    FsUserCourseVideo video = videoMap.get(e.getVideoId());
+                    QwSopTempRedPackageVo vo = new QwSopTempRedPackageVo();
+                    vo.setId(red.getId());
+                    vo.setRuleId(e.getId());
+                    vo.setName(e.getName());
+                    vo.setVideoId(e.getVideoId());
+                    vo.setVideoName(video.getTitle());
+                    vo.setCompanyId(red.getCompanyId());
+                    vo.setRedPacketMoney(red.getRedPacketMoney());
+                    vo.setDataType(red.getDataType());
+                    return vo;
+                }).collect(Collectors.toList());
     }
 
     @Override
@@ -344,7 +339,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("course.config");
         CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
         List<CourseConfig.DisabledTimeVo> disabledTimeList = courseConfig.getDisabledTimeList();
-        if(disabledTimeList == null){
+        if (disabledTimeList == null) {
             return Collections.emptyList();
         }
         return TimeCalculator.calculateAvailableTimes(disabledTimeList);
@@ -355,7 +350,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     public int update(QwSopTemp qwSopTemp) {
         QwSopTemp temp = qwSopTempMapper.selectById(qwSopTemp.getId());
         int i = qwSopTempMapper.updateById(qwSopTemp);
-        if(!Objects.equals(temp.getGap(), qwSopTemp.getGap())){
+        if (!Objects.equals(temp.getGap(), qwSopTemp.getGap())) {
             // 重新排序
             reorder(qwSopTemp.getId());
         }
@@ -367,14 +362,14 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         List<QwSopTempRules> list = day.getList();
         List<QwSopTempContent> collect = list.stream().flatMap(e -> e.getSettingList().stream()).collect(Collectors.toList());
         List<QwSopTempContent> voiceList = collect.stream().filter(e -> e.getContentType() == 7).collect(Collectors.toList());
-        if(!voiceList.isEmpty()){
+        if (!voiceList.isEmpty()) {
 //            day.setVoice(1);
         }
         qwSopTempDayService.saveOrUpdate(day);
         qwSopTempRulesService.removeByDayId(day.getId());
         qwSopTempContentService.removeByDayId(day.getId());
 
-        list.forEach(item-> item.setDayId(day.getId()));
+        list.forEach(item -> item.setDayId(day.getId()));
         processAndReplaceContent(list);
         QwSopTempRules rules = list.get(0);
         String tempId = rules.getTempId();
@@ -392,19 +387,19 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         reorder(day.getTempId());
         Map<String, Object> map = new HashMap<>();
         map.put("id", day.getId());
-        if(!voiceList.isEmpty()){
+        if (!voiceList.isEmpty()) {
             rocketMQTemplate.syncSend("voice-generation", JSON.toJSONString(VoiceVo.builder().type(0).id(day.getId().toString()).build()));
         }
 
         return map;
     }
 
-    private void processAndReplaceContent(List<QwSopTempRules> tempSettings){
+    private void processAndReplaceContent(List<QwSopTempRules> tempSettings) {
         List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
         //循环天
-        tempSettings.forEach(settingList->{
+        tempSettings.forEach(settingList -> {
             //循环单日
-            settingList.getSettingList().forEach(item->{
+            settingList.getSettingList().forEach(item -> {
                 JSONObject obj = JSON.parseObject(item.getContent());
                 List<String> list = Arrays.asList("linkTitle", "linkDescribe", "desc", "nickname", "value");
                 list.stream().filter(obj::containsKey).forEach(key -> {
@@ -417,25 +412,26 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
     @Override
     public void delRules(Long id) {
-        if(id == null) return;
+        if (id == null) return;
         QwSopTempDay day = qwSopTempDayService.info(id);
-        if(day == null) return;
+        if (day == null) return;
         qwSopTempDayService.removeById(day.getId());
         qwSopTempContentService.removeByDayId(day.getId());
         reorder(day.getTempId());
     }
+
     @Override
     public QwSopTempDay selectRulesInfo(Long id) {
         QwSopTempDay day = qwSopTempDayService.info(id);
         List<QwSopTempRules> rulesList = qwSopTempRulesService.listByDayId(id);
-        if(CollectionUtils.isNotEmpty(rulesList)){
+        if (CollectionUtils.isNotEmpty(rulesList)) {
             List<QwSopTempContent> contentList = qwSopTempContentService.listByRulesIds(PubFun.listToNewList(rulesList, QwSopTempRules::getId));
             Map<Long, List<QwSopTempContent>> contentMap = PubFun.listToMapByGroupList(contentList, QwSopTempContent::getRulesId);
             rulesList.forEach(e -> {
                 List<QwSopTempContent> contents = contentMap.get(e.getId());
-                if(CollectionUtils.isNotEmpty(contents)){
+                if (CollectionUtils.isNotEmpty(contents)) {
                     e.setSetting(contents.stream()
-                            .filter(c-> c!=null && StringUtils.isNotBlank(c.getContent()))
+                            .filter(c -> c != null && StringUtils.isNotBlank(c.getContent()))
                             .map(c -> JSON.parseObject(c.getContent())).collect(Collectors.toList()));
                 }
             });
@@ -447,7 +443,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     @Override
     public List<QwSopTemp> selectQwSopTempListNew(QwSopTemp qwSopTemp) {
         List<QwSopTemp> list = qwSopTempMapper.selectQwSopTempListNew(qwSopTemp);
-        if(qwSopTemp.isCuoser()){
+        if (qwSopTemp.isCuoser()) {
             List<QwSopTempRules> rulesList = qwSopTempRulesService.selectByTemplateIds(PubFun.listToNewList(list, QwSopTemp::getId));
             rulesList.sort(Comparator.comparing(
                     e -> {
@@ -476,18 +472,18 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         qwSopTemp.setId(newId);
         qwSopTempMapper.insertQwSopTemp(qwSopTemp);
         List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(oldId);
-        if(dayList.isEmpty()) return;
+        if (dayList.isEmpty()) return;
         List<QwSopTempRules> ruleList = dayList.stream().filter(e -> e.getList() != null).flatMap(e -> e.getList().stream()).collect(Collectors.toList());
-        if(ruleList.isEmpty()) return;
+        if (ruleList.isEmpty()) return;
         List<FsUserCourseVideoRedPackage> redList = fsUserCourseVideoRedPackageService.selectByRuleIds(PubFun.listToNewList(ruleList, QwSopTempRules::getId));
         Map<Long, FsUserCourseVideoRedPackage> redMap = PubFun.listToMapByGroupObject(redList, FsUserCourseVideoRedPackage::getRuleId);
         dayList.forEach(day -> {
             day.setTempId(newId);
-            if(day.getList() != null && !day.getList().isEmpty()){
+            if (day.getList() != null && !day.getList().isEmpty()) {
                 day.getList().forEach(e -> {
                     e.setRed(redMap.get(e.getId()));
                     e.setTempId(newId);
-                    if(e.getSettingList() != null && !e.getSettingList().isEmpty()){
+                    if (e.getSettingList() != null && !e.getSettingList().isEmpty()) {
                         e.getSettingList().forEach(item -> {
                             item.setTempId(newId);
                         });
@@ -503,9 +499,9 @@ public class QwSopTempServiceImpl implements IQwSopTempService
             item.setRulesId(e.getId());
             item.setDayId(e.getDayId());
         }));
-        qwSopTempContentService.insertBatch(collect.stream().flatMap(e ->e.getSettingList().stream()).collect(Collectors.toList()));
+        qwSopTempContentService.insertBatch(collect.stream().flatMap(e -> e.getSettingList().stream()).collect(Collectors.toList()));
         List<FsUserCourseVideoRedPackage> redSaveList = collect.stream().filter(e -> e.getRed() != null).peek(e -> e.getRed().setRuleId(e.getId())).map(QwSopTempRules::getRed).collect(Collectors.toList());
-        if(!redSaveList.isEmpty()){
+        if (!redSaveList.isEmpty()) {
             fsUserCourseVideoRedPackageService.batchSaveCompanyRedPackage(redSaveList);
         }
     }
@@ -521,7 +517,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     public void sortDay(List<SortDayVo> list) {
         Collection<QwSopTempDay> days = qwSopTempDayService.listByIds(PubFun.listToNewList(list, SortDayVo::getId));
         Map<Long, Integer> dayMap = list.stream().collect(Collectors.toMap(SortDayVo::getId, SortDayVo::getDayNum));
-        if(days.stream().anyMatch(e -> !dayMap.containsKey(e.getId()))){
+        if (days.stream().anyMatch(e -> !dayMap.containsKey(e.getId()))) {
             throw new BaseException("数据错误!");
         }
         days.forEach(day -> day.setDayNum(dayMap.get(day.getId())));
@@ -535,10 +531,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
 
     @DataSource(DataSourceType.SOP)
-    private void reorder(String tempId){
+    private void reorder(String tempId) {
         QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(tempId);
         List<QwSopTempDay> days = qwSopTempDayService.listByTempId(tempId);
-        if(days.isEmpty()) return;
+        if (days.isEmpty()) return;
         for (int i = 0; i < days.size(); i++) {
             QwSopTempDay entity = days.get(i);
             entity.setSorts(i);

+ 1 - 1
fs-service-system/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -381,7 +381,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         if(param.getFilterMode() != null && param.getFilterMode() == 2 && param.getChatIds() != null && param.getChatIds().length > 0){
             List<QwGroupChat> groupList = qwGroupChatMapper.selectQwGroupChatByChatIds(param.getChatIds());
             sopLogsList = groupList.stream().map(groupChat -> {
-                QwUser qwUser = qwUserMapper.selectQwUserByIdByWeComeText(groupChat.getOwner(), groupChat.getCorpId());
+                QwUser qwUser = qwUserMapper.selectQwUserByIdByWeComeText2(groupChat.getOwner(), groupChat.getCorpId());
                 QwSopLogs sopLogs = new QwSopLogs();
 
                 sopLogs.setQwUserid(qwUser.getQwUserId());

+ 37 - 0
fs-service-system/src/main/java/com/fs/store/dto/AddressInfoDTO.java

@@ -0,0 +1,37 @@
+package com.fs.store.dto;
+
+import lombok.Data;
+
+@Data
+public class AddressInfoDTO {
+
+    private String EBusinessID;
+
+    private AddressData Data;
+
+    private boolean Success;
+
+    private String Reason;
+
+
+    private String ResultCode;
+    @Data
+    public  class AddressData {
+
+        private String ProvinceName;
+
+        private String StreetName;
+
+        private String Address;
+
+        private String CityName;
+
+        private String ExpAreaName;
+
+        private String Mobile;
+
+        private String Name;
+
+    }
+
+}

+ 4 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsUserAddressService.java

@@ -1,8 +1,9 @@
 package com.fs.store.service;
 
-import java.util.List;
 import com.fs.store.domain.FsUserAddress;
 
+import java.util.List;
+
 /**
  * 用户地址Service接口
  * 
@@ -64,4 +65,6 @@ public interface IFsUserAddressService
     Integer selectFsUserAddressCountsByUserId(long userId);
 
     Integer delAllAddress(Long userId);
+
+    String getKdnAddress(String address);
 }

+ 7 - 1
fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java

@@ -20,7 +20,6 @@ import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
 import com.fs.store.vo.h5.*;
-import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -252,4 +251,11 @@ public interface IFsUserService
      * @param param
      */
     void setRepeatFansTag(FsUserCourseBeMemberParam param);
+
+    /**
+     * 根据会话sessionId查询用户信息
+     * @param sessionId sessionId
+     * @return  fsUser
+     */
+    FsUser getUserInfoBySessionId(Long sessionId);
 }

+ 65 - 4
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserAddressServiceImpl.java

@@ -1,12 +1,22 @@
 package com.fs.store.service.impl;
 
-import java.util.List;
+import cn.hutool.http.HttpUtil;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import com.fs.store.mapper.FsUserAddressMapper;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.utils.ConfigUtil;
 import com.fs.store.domain.FsUserAddress;
+import com.fs.store.mapper.FsUserAddressMapper;
 import com.fs.store.service.IFsUserAddressService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Base64Utils;
+
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 用户地址Service业务层处理
@@ -19,6 +29,8 @@ public class FsUserAddressServiceImpl implements IFsUserAddressService
 {
     @Autowired
     private FsUserAddressMapper fsUserAddressMapper;
+    @Autowired
+    private ConfigUtil ConfigUtil;
 
     /**
      * 查询用户地址
@@ -110,4 +122,53 @@ public class FsUserAddressServiceImpl implements IFsUserAddressService
     public Integer delAllAddress(Long userId) {
         return fsUserAddressMapper.delAllAddress(userId);
     }
+
+    @Override
+    public String getKdnAddress(String address) {
+        String   requestData = "{'Content':'" + address + "'}";
+        Map<String, Object> params = new HashMap<>();
+        FsSysConfig sysConfig = ConfigUtil.getSysConfig();
+        try {
+            params.put("RequestData", URLEncoder.encode(requestData, "UTF-8"));
+            params.put("EBusinessID",sysConfig.getKdnId().trim());
+            params.put("RequestType", "6001");
+            String dataSign = encrypt(requestData, sysConfig.getKdnKeyId().trim(), "UTF-8");
+            params.put("DataSign", URLEncoder.encode(dataSign, "UTF-8"));
+            params.put("DataType", "2");
+            String result = HttpUtil.post(sysConfig.getKdnAddressUrl().trim(), params);
+
+            return result;
+        } catch (Exception e) {
+            throw  new CustomException(e.getMessage());
+        }
+    }
+
+    private String encrypt(String content, String keyValue, String charset) {
+        if (keyValue != null) {
+            content = content + keyValue;
+        }
+        byte[] src;
+        try {
+            src = MD5(content, charset).getBytes(charset);
+            return Base64Utils.encodeToString(src);
+        } catch (Exception e) {
+        }
+
+        return null;
+    }
+
+    private String MD5(String str, String charset) throws Exception {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        md.update(str.getBytes(charset));
+        byte[] result = md.digest();
+        StringBuilder sb = new StringBuilder(32);
+        for (int i = 0; i < result.length; i++) {
+            int val = result[i] & 0xff;
+            if (val <= 0xf) {
+                sb.append("0");
+            }
+            sb.append(Integer.toHexString(val));
+        }
+        return sb.toString().toLowerCase();
+    }
 }

+ 45 - 2
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -2,12 +2,15 @@ package com.fs.store.service.impl;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.HttpStatus;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.cache.ICompanyTagCacheService;
@@ -16,7 +19,6 @@ import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyTag;
 import com.fs.company.domain.CompanyTagUser;
 import com.fs.company.domain.CompanyUser;
-import com.fs.company.dto.CompanyIdAndUserDTO;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyTagMapper;
 import com.fs.company.mapper.CompanyTagUserMapper;
@@ -31,6 +33,10 @@ import com.fs.course.vo.newfs.FsCourseAnalysisVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.cache.IQwExternalContactCacheService;
+import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.domain.QwSession;
+import com.fs.qw.mapper.QwExternalContactMapper;
+import com.fs.qw.mapper.QwSessionMapper;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.store.domain.*;
@@ -52,7 +58,6 @@ import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
 import com.fs.store.vo.h5.*;
-import com.github.pagehelper.PageInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.http.util.Asserts;
@@ -126,6 +131,10 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Autowired
     CompanyTagMapper companyTagMapper;
+    @Autowired
+    private QwSessionMapper qwSessionMapper;
+    @Autowired
+    private QwExternalContactMapper qwExternalContactMapper;
 
     /**
      * 查询用户
@@ -899,6 +908,40 @@ public class FsUserServiceImpl implements IFsUserService
         }
     }
 
+    /**
+     * 根据会话sessionId查询用户信息
+     * @param sessionId sessionId
+     * @return  fsUser
+     */
+    @Override
+    public FsUser getUserInfoBySessionId(Long sessionId) {
+        Wrapper<QwSession> qwSessionWrapper = Wrappers.<QwSession>lambdaQuery()
+        .select(QwSession.class, q -> !q.getColumn().equals("remark"))
+        .eq(QwSession::getSessionId, sessionId);
+        QwSession qwSession = qwSessionMapper.selectOne(qwSessionWrapper);
+        if (Objects.isNull(qwSession)) {
+            log.warn("企微会话不存在 sessionId:{}", sessionId);
+            throw new CustomException("会话不存在");
+        }
+
+        Wrapper<QwExternalContact> qwExternalContactWrapper = Wrappers.<QwExternalContact>lambdaQuery()
+        .select(QwExternalContact.class, q -> !q.getColumn().equals("remark"))
+        .eq(QwExternalContact::getId, qwSession.getQwExtId());
+        QwExternalContact qwExternalContact = qwExternalContactMapper.selectOne(qwExternalContactWrapper);
+        if (Objects.isNull(qwExternalContact)) {
+            log.warn("企微会话对应外部联系人不存在 qwExtId: {}", qwSession.getQwExtId());
+            throw new CustomException("外部联系人不存在");
+        }
+
+        FsUser fsUser = fsUserMapper.selectFsUserById(qwExternalContact.getFsUserId());
+        if (Objects.isNull(fsUser)) {
+            fsUser = new FsUser();
+            fsUser.setAvatar(qwExternalContact.getAvatar());
+            fsUser.setNickname(qwExternalContact.getName());
+        }
+        return fsUser;
+    }
+
     // 判断是否绑定了销售
     private static FsUserCompanyUser getFsUserCompanyUser(FsUserCourseBeMemberParam param, FsUser fsUser) {
         FsUserCompanyUser fsUserCompanyUser = new FsUserCompanyUser();

+ 6 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkMessageDTO.java

@@ -20,4 +20,10 @@ public class WxWorkMessageDTO {
     private Integer msgtype;         // 对应 "msgtype": 2 (消息类型 0 和 2文本消息)
     private String recordwording;    //通话时长
     private Integer recordtype;         //通话5
+
+    // 图片
+    private String file_id;
+    private Integer file_size;
+    private String aes_key;
+    private String openim_cdn_authkey;
 }

+ 4 - 0
fs-service-system/src/main/java/com/fs/wxwork/dto/WxWorkUserId2VidDTO.java

@@ -6,8 +6,12 @@ import java.util.List;
 
 @Data
 public class WxWorkUserId2VidDTO {
+    // qw_user uid
     private String uuid;
+    // qw_user corp_id
     private String scorpid;
+    //
     private String corpid;
+    // qw_external_contact external_user_id
     private List<String> openid;
 }

+ 2 - 2
fs-service-system/src/main/resources/application-config-dev.yml

@@ -99,8 +99,8 @@ wx:
       port: 6379
       timeout: 2000
     configs:
-      - appId: wx961fadab9bcb792b # 第一个公众号的appid  //公众号名称:云联
-        secret: eddde2a1d4ca0c6c443a67e542b6864c
+      - appId: wx93ce67750e3cfba3 # 第一个公众号的appid  //公众号名称:云联
+        secret: 659fafaace3ca1c4df1bffac173a9bd7
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
 jpush:

+ 122 - 0
fs-service-system/src/main/resources/application-config-fby.yml

@@ -0,0 +1,122 @@
+#配置
+fsConfig:
+  #快递鸟
+  kdnId: 1762981
+  kdnKeyId: 024e89b1-25c7-4725-8a3c-1bf1ca3ddcab
+  kdnUrl: http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx
+  kdnSubscribeUrl: https://api.kdniao.com/api/dist
+  kdnAddressUrl: https://api.kdniao.com/api/dist
+  #ERP配置
+  erpOpen: 1
+  erpAppKey: 108123
+  erpSessionKey: 9caae15474cb443ea22235e7bb86016b
+  erpSecret: 96f774dbd60847b59a16f92fd963a0c8
+  erpUrl: http://v2.api.guanyierp.com/rest/erp_open
+  erpShopCode: test
+  #ERP-hc
+  erpWdAppKey: beiliyou2-test
+  erpWdAppsecret: 6ec212f06
+  erpWdSid: apidevnew2
+  erpWdShopCode: beiliyou2-test
+  erpWdBaseUrl: https://api.wangdian.cn/openapi2/
+  erpWarehouseCode: beiliyou2-test
+  #金博ERP
+  kingbosan: 陕西中康
+  kingbosSecret: 12CA1038CE8A45D1BA325898A3F2F029
+  kingbosUrl: http://zkyf888.gnway.cc:53868/?an=陕西中康&do=k9save&timestep=&sign=&corgid=zy01
+  corgid: zy01
+  cwarehouseCode: "CK01"
+  cwarehouseName: "合格仓"
+  #第三方支付配置
+  payOpen: 1
+  payPartnerId: 22051909542647100020
+  payKey: f256bd35aa36115d729537e1a1e01b92
+  payGateWayUrl: https://openapi.t2bank.cn/gateway.html
+  payNotifyUrl: https://api.yjf.runtzh.com/app/pay/payNotify
+  refundNotifyUrl: https://api.yjf.runtzh.com/app/pay/refundNotify
+  # 腾讯云IM
+  sdkAppId: 1400693126
+  sdkAppKey: 9afa6e63db943293680e37b3ba032e52cdb238112750806e82e58e9240604b70
+  # 处方接口Test
+  #  prescribeUrl: https://yixian-new-test.yixianmedical.com/platform-shenfang/nethosp/webservice/jsonapi
+  #  actId:  uporder
+  #  appId: 1646204278
+  #  manuId:  3981112bfcc64bf68f7744ffec7e3ca7
+  #  callbackUrl:  https://api.hospital.ifeiyu100.com/app/prescribe/presribeNotify
+  # 处方接口g
+  prescribeUrl: https://app3.nxk520.com/platform-shenfang/nethosp/webservice/jsonapi
+  actId: uporder
+  appId: 1661496555
+  manuId: 0212af1e742b41b09089afeec98f8276
+  callbackUrl: https://api.yjf.runtzh.com/app/prescribe/presribeNotify
+logging:
+  level:
+    org.springframework.web: INFO
+    com.github.binarywang.demo.wx.cp: DEBUG
+    me.chanjar.weixin: DEBUG
+wx:
+  cp:
+    corpId: wwb2a1055fb6c9a7c2
+    appConfigs:
+      - agentId: 1000002
+        secret: bhj3402rPCT0YGcosffyTO3eUMs1G2MFHMspXVBNf-c
+        token: PPKOdAlCoMO
+        aesKey: PKvaxtpSv8NGpfTDm7VUHIK8Wok2ESyYX24qpXJAdMP
+  miniapp:
+    configs:
+      - appid: wx11a2ce7c2bbc4521   #倍力优会员商城
+        secret: d680dc8ff20258b158c9355f8b7769ae
+        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+        aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
+        msgDataFormat: JSON
+
+      ##  云联融智优选小程序,暂时使用
+      #      - appid: wxd70f99287830cb51   #云联融智优选(暂时用于测试销售app)
+      #        secret: 6e2684b3d48e6363018d4eedb8dae3e5
+      #        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+      #        aesKey:
+      #        msgDataFormat: JSON
+
+      - appid: wxb9b453d37c5fad45   #福本源小程序
+        secret: 45ee94e8c48edbafdcca2131a5e9d48d
+        token: Ncbnd7lJvkripVOpyTFAna6NAWCxCrvC
+        aesKey:
+        msgDataFormat: JSON
+
+  pay:
+    appId: wx11a2ce7c2bbc4521 #微信公众号或者小程序等的appid
+    mchId: 1703311381 #微信支付商户号
+    mchKey: FotTIbIzn4AisMW7de712LJQIazSqqAl #微信支付商户密钥
+    v3Key: y5Eo99q93qzdQRAs6E2BDKIF7f3EnS3G
+    subAppId:  #服务商模式下的子商户公众账号ID
+    subMchId:  #服务商模式下的子商户号
+    keyPath: c:\\Tools\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    notifyUrl:  https://userapp.bly.ylrztop.com/app/wxpay/wxPayNotify
+  mp:
+    useRedis: false
+    redisConfig:
+      host: 127.0.0.1
+      port: 6379
+      timeout: 2000
+    configs:
+      - appId: wx961fadab9bcb792b # 第一个公众号的appid  //公众号名称:云联
+        secret: eddde2a1d4ca0c6c443a67e542b6864c
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+jpush:
+  appKey: cc9a0120a3e4270c9cba340d
+  masterSecret: cfc2575d3cd7470d584c990c
+  liveTime: 1000
+  apnsProduction: true
+aifabu:  #爱链接
+  appKey: 7b471be905ab17e00f3b858c6710dd117601d008
+
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: fby-1323137866
+  app_id: 1323137866
+  region: chongqing
+  proxy: fby
+cloud_host:
+  company_name: 福本源

+ 0 - 0
fs-admin/src/main/resources/application-druid-fby.yml → fs-service-system/src/main/resources/application-druid-fby.yml


+ 20 - 0
fs-service-system/src/main/resources/db/upgrade/20250516.sql

@@ -0,0 +1,20 @@
+DROP PROCEDURE IF EXISTS add_tb_column;
+DELIMITER $$
+CREATE PROCEDURE add_tb_column()
+BEGIN
+		DECLARE  CurrentDatabase VARCHAR(100);
+SELECT DATABASE() INTO CurrentDatabase;
+
+-- company_user 表添加 is_need_register_member 字段
+IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS  WHERE TABLE_SCHEMA=CurrentDatabase
+            AND TABLE_NAME='company_user'
+            AND COLUMN_NAME='is_need_register_member' )
+		THEN
+alter table company_user add column is_need_register_member tinyint(1)  DEFAULT 0 COMMENT '是否需要单独注册会员,1-是,0-否(用于个微销售分享看课)';
+END IF;
+
+END;
+
+CALL add_tb_column;
+
+DROP PROCEDURE IF EXISTS add_tb_column;

+ 48 - 1
fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml

@@ -39,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="domain"    column="domain"    />
         <result property="isAudit"    column="is_audit"    />
         <result property="addressId"    column="address_id"    />
+        <result property="isNeedRegisterMember"    column="is_need_register_member"    />
         <association property="dept"    column="dept_id" javaType="CompanyDept" resultMap="deptResult" />
         <collection  property="roles"   javaType="java.util.List"        resultMap="RoleResult" />
 
@@ -275,7 +276,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <sql id="selectUserVo">
         select u.user_id,u.company_id,u.qw_user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time,u.id_card, u.remark,u.user_type,u.open_id,u.qr_code_weixin,u.qr_code_wecom,u.jpush_id,u.domain,u.is_audit,u.address_id,
         d.dept_id, d.parent_id, d.dept_name, d.order_num, d.leader, d.status as dept_status,
-        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
+        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status,
+        u.is_need_register_member
         from company_user u
 		    left join company_dept d on u.dept_id = d.dept_id
 		    left join company_user_role ur on u.user_id = ur.user_id
@@ -429,6 +431,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{id}
         </foreach>
     </update>
+    <update id="uploadQrCode">
+        update company_user set qr_code_weixin=#{url} where user_id=${userId}
+    </update>
 
     <select id="selectAllCompanyUserAndSelf" resultType="CompanyUser">
         SELECT
@@ -463,5 +468,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectCompanyUserNameUserById" resultType="java.lang.String">
         select concat(nick_name,'_',user_name) from company_user where user_id=${userId} limit 1
     </select>
+    <select id="selectCompanyUserQwListVO" resultType="com.fs.company.vo.CompanyUserQwListVO">
+        select u.*, d.dept_name, d.leader from company_user u
+        left join company_dept d on u.dept_id = d.dept_id
+        where u.del_flag = '0'
+        <if test="userName != null and userName != ''">
+            AND u.user_name like concat(#{userName}, '%')
+        </if>
+        <if test="nickName != null and nickName != ''">
+            AND u.nick_name like concat( #{nickName}, '%')
+        </if>
+        <if test="companyId != null and companyId != ''">
+            AND u.company_id = #{companyId}
+        </if>
+        <if test="status != null and status != ''">
+            AND u.status = #{status}
+        </if>
+        <if test="qwStatus != null ">
+            AND u.qw_status = #{qwStatus}
+        </if>
+        <if test="phonenumber != null and phonenumber != ''">
+            AND u.phonenumber like concat(#{phonenumber}, '%')
+        </if>
+        <if test="beginTime != null and beginTime != ''"><!-- 开始时间检索 -->
+            AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{beginTime},'%y%m%d')
+        </if>
+        <if test="endTime != null and endTime != ''"><!-- 结束时间检索 -->
+            AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{endTime},'%y%m%d')
+        </if>
+        <if test="deptId != null and deptId != 0">
+            AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{deptId}, ancestors) ))
+        </if>
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+
+    <update id="setIsRegisterMember" parameterType="Long">
+        update company_user
+        set is_need_register_member = #{status} where user_id in
+        <foreach item="userId" collection="userIds" open="(" separator="," close=")">
+            #{userId}
+        </foreach>
+    </update>
 
 </mapper>

+ 4 - 0
fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml

@@ -18,6 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="periodStartingTime"    column="period_starting_time"    />
         <result property="periodEndTime"    column="period_end_time"    />
         <result property="maxViewNum"    column="max_view_num"    />
+        <result property="courseLogo"    column="course_logo"    />
     </resultMap>
 
     <sql id="selectFsUserCoursePeriodVo">
@@ -103,6 +104,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="viewEndTime != null">view_end_time,</if>
             <if test="lastJoinTime != null">last_join_time,</if>
             <if test="maxViewNum != null">max_view_num,</if>
+            <if test="courseLogo != null">course_logo,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="periodId != null">#{periodId},</if>
@@ -122,6 +124,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="viewEndTime != null">#{viewEndTime},</if>
             <if test="lastJoinTime != null">#{lastJoinTime},</if>
             <if test="maxViewNum != null">#{maxViewNum},</if>
+            <if test="courseLogo != null">#{courseLogo},</if>
          </trim>
     </insert>
 
@@ -144,6 +147,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="viewEndTime != null">view_end_time = #{viewEndTime},</if>
             <if test="lastJoinTime != null">last_join_time = #{lastJoinTime},</if>
             <if test="maxViewNum != null">max_view_num = #{maxViewNum},</if>
+            <if test="courseLogo != null and courseLogo !=''">course_logo = #{courseLogo},</if>
         </trim>
         where period_id = #{periodId}
     </update>

+ 6 - 4
fs-service-system/src/main/resources/mapper/store/FsUserCourseCountMapper.xml

@@ -163,12 +163,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             max( CASE WHEN fwl.log_type = 2 THEN fwl.last_heartbeat_time END ) AS completeWatchDate,
             count( CASE WHEN fwl.log_type = 2 THEN fwl.log_id END ) AS completeWatchCount,
             count( CASE WHEN fwl.log_type != 3 THEN fwl.log_id END ) AS watch_times,
-            NOW() AS create_time,
+            DATE_FORMAT(fwl.create_time,'%Y-%m-%d 00:00:00') AS createTime,
             NOW() AS updateTime,
-            curdate() AS create_date
+            DATE_FORMAT(fwl.create_time,'%Y-%m-%d') AS create_date
         FROM
-            ( SELECT fs_course_watch_log.user_id, Max( fs_course_watch_log.last_heartbeat_time ) AS last_heartbeat_time, log_type FROM fs_course_watch_log GROUP BY fs_course_watch_log.user_id ) a
-                INNER JOIN fs_course_watch_log fwl ON fwl.user_id = a.user_id
+            ( SELECT fs_course_watch_log.user_id, Max( fs_course_watch_log.last_heartbeat_time ) AS last_heartbeat_time, log_type
+              FROM fs_course_watch_log where fs_course_watch_log.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND fs_course_watch_log.create_time &lt; CURDATE() GROUP BY fs_course_watch_log.user_id ) a
+                INNER JOIN fs_course_watch_log fwl ON fwl.user_id = a.user_id AND fwl.send_type = 1
+            where fwl.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND fwl.create_time &lt; CURDATE()
         GROUP BY
             fwl.user_id
     </select>

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

@@ -74,6 +74,8 @@ public class CourseController extends  AppBaseController{
     private IFsCourseWatchLogService courseWatchLogService;
     @Autowired
     private CachingOperationNameGenerator cachingOperationNameGenerator;
+    @Autowired
+    private IFsUserCoursePeriodService coursePeriodService;
 
 
     @Cacheable(value="getCourseCate" )
@@ -360,6 +362,13 @@ public class CourseController extends  AppBaseController{
         Long duration = 0L;
         long tipsTime = 0L;
         int isFinish = 0;
+        //课程logo
+        if (param.getPeriodId()!=null){
+            FsUserCoursePeriod fsUserCoursePeriod = coursePeriodService.selectFsUserCoursePeriodById(param.getPeriodId());
+            if (fsUserCoursePeriod!=null){
+                config.setCourseLogo(fsUserCoursePeriod.getCourseLogo());
+            }
+        }
         if (param.getLinkType()!=null&&param.getLinkType()==1){
             return R.ok().put("course",course).put("questions",questionVOList).put("config",config).put("playDuration",duration).put("tipsTime",tipsTime);
         }

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

@@ -12,8 +12,10 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.IpUtil;
 import com.fs.common.utils.ServletUtils;
+import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyDeptService;
+import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.store.domain.FsUser;
 import com.fs.store.service.IFsUserService;
@@ -57,9 +59,13 @@ public class WxCompanyUserController extends AppBaseController {
     @Autowired
     private IFsUserService userService;
 
+    @Autowired
+    ICompanyService companyService;
+
     @ApiOperation("小程序-授权登录")
     @PostMapping("/loginByMa")
     public R login(@RequestBody LoginMaWxParam param) {
+        log.info("=====================进入小程序授权登录, 入参: {}", param);
         if (StringUtils.isBlank(param.getCode())) {
             return R.error("code不存在");
         }
@@ -126,6 +132,16 @@ public class WxCompanyUserController extends AppBaseController {
 //                companyUserMp.setLoginIp(ip);
 //                companyUserService.updateUserProfile(companyUser);
 //            }
+
+            // 特殊(需求设计:需要根据公司是否开启黑名单来设置会员初始化的状态)
+            Company company = null;
+            if(param.getCompanyId() != null){
+                company = companyService.selectCompanyById(param.getCompanyId());
+            }
+
+            // 根据销售后台设置的  是否需要单独注册会员 来判断是否需要设置销售的值
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
+
             String ip = IpUtil.getRequestIp();
             if (user == null) {
                 user = userService.selectFsUserByMaOpenId(session.getOpenid());
@@ -140,17 +156,25 @@ public class WxCompanyUserController extends AppBaseController {
                     userMap.setNickname(userInfo.getNickName() != null ? userInfo.getNickName() : "微信用户");
                     userMap.setAvatar(userInfo.getAvatarUrl() != null ? userInfo.getAvatarUrl() : null);
                     userMap.setPhone(phoneNoInfo.getPhoneNumber());
+                    if(companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1){
+                        user.setCompanyId(param.getCompanyId());
+                        user.setCompanyUserId(param.getCompanyUserId());
+                    }
                     userService.updateFsUser(userMap);
                 } else {
                     //新增
                     user = new FsUser();
                     user.setNickname(userInfo.getNickName() != null ? userInfo.getNickName() : "微信用户");
                     user.setAvatar(userInfo.getAvatarUrl() != null ? userInfo.getAvatarUrl() : null);
-                    user.setStatus(1);
+                    user.setStatus((company != null ? company.getFsUserIsDefaultBlack() : 0) == 1 ? 0 : 1);
                     user.setMaOpenId(session.getOpenid());
                     user.setUnionId(session.getUnionid());
                     user.setCreateTime(new Date());
                     user.setPhone(phoneNoInfo.getPhoneNumber());
+                    if(companyUser.getIsNeedRegisterMember() != null && companyUser.getIsNeedRegisterMember() != 1){
+                        user.setCompanyId(param.getCompanyId());
+                        user.setCompanyUserId(param.getCompanyUserId());
+                    }
                     userService.insertFsUser(user);
                 }
             } else {

+ 12 - 4
fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java

@@ -6,7 +6,9 @@ import com.fs.app.utils.JwtUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
+import com.fs.company.service.ICompanyUserService;
 import com.fs.course.mapper.FsCourseSopLogsMapper;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
@@ -56,6 +58,8 @@ public class WxH5MpController {
     QwExternalContactMapper qwExternalContactMapper;
     @Autowired
     ICompanyService companyService;
+    @Autowired
+    ICompanyUserService companyUserService;
 
 
     @ApiOperation("课程分享链接公众号登录")
@@ -66,12 +70,14 @@ public class WxH5MpController {
             WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(param.getCode());
             WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, null);
             //1、特殊(需求设计:需要根据公司是否开启黑名单来设置会员初始化的状态)
-            //2、获取公司信息
             Company company = null;
             if(param.getCompanyId() != null){
                 company = companyService.selectCompanyById(param.getCompanyId());
             }
-            FsUser user = userService.selectFsUserByMpOpenId(wxMpUser.getOpenid());
+            // 根据销售后台设置的  是否需要单独注册会员 来判断是否需要设置销售的值
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getCompanyUserId());
+
+        FsUser user = userService.selectFsUserByMpOpenId(wxMpUser.getOpenid());
             if (user != null) {
                 //修改
                 FsUser userMap = new FsUser();
@@ -90,8 +96,10 @@ public class WxH5MpController {
                 user.setMpOpenId(wxMpUser.getOpenid());
                 user.setUnionId(wxMpUser.getUnionId());
                 user.setCreateTime(new Date());
-                user.setCompanyId(param.getCompanyId());
-                user.setCompanyUserId(param.getCompanyUserId());
+                if(companyUser.getIsNeedRegisterMember() != 1){
+                    user.setCompanyId(param.getCompanyId());
+                    user.setCompanyUserId(param.getCompanyUserId());
+                }
                 userService.insertFsUser(user);
             }
             log.error("用户信息user: {}, 用户id: {}", user, user.getUserId());

+ 9 - 0
fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 @Data
@@ -19,6 +20,14 @@ public class LoginMaWxParam implements Serializable {
     @ApiModelProperty(value = "小程序加密算法的初始向量")
     private String iv;
 
+    @NotNull(message = "公司id不能为空")
+    @ApiModelProperty(value = "公司id")
+    private Long companyId;
+
+    @NotNull(message = "销售id不能为空")
+    @ApiModelProperty(value = "销售id")
+    private Long companyUserId;
+
 //    @ApiModelProperty(value = "公司id,如果不是第一位销售,都需要传")
 //    private Long companyId;
 

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

@@ -6,5 +6,6 @@ server:
 
 spring:
   profiles:
-    active: dev
-    include: common,config-dev
+    active: druid-fby
+    include: common,config-fby
+