فهرست منبع

益善源开启 项目归属-企微会员转移

三七 5 روز پیش
والد
کامیت
3a2ea770db
31فایلهای تغییر یافته به همراه1639 افزوده شده و 27 حذف شده
  1. 13 0
      fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java
  2. 70 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  3. 98 0
      fs-admin/src/main/java/com/fs/qw/controller/FsUserAdminByQwController.java
  4. 99 0
      fs-admin/src/main/java/com/fs/qw/controller/FsUserCompanyUserQwController.java
  5. 105 0
      fs-admin/src/main/java/com/fs/transfer/CustomerTransferApprovalQwController.java
  6. 11 0
      fs-company/src/main/java/com/fs/company/controller/company/CompanyUserController.java
  7. 144 0
      fs-company/src/main/java/com/fs/company/controller/qw/FsUserAdminByQwController.java
  8. 9 6
      fs-company/src/main/java/com/fs/company/controller/qw/FsUserCompanyUserQwController.java
  9. 111 0
      fs-company/src/main/java/com/fs/transfer/CustomerTransferApprovalQwController.java
  10. 77 0
      fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java
  11. 1 0
      fs-service/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
  12. 2 0
      fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java
  13. 28 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  14. 3 0
      fs-service/src/main/java/com/fs/company/vo/CompanyUserQwListVO.java
  15. 3 0
      fs-service/src/main/java/com/fs/course/domain/FsUserCompanyUserQw.java
  16. 19 9
      fs-service/src/main/java/com/fs/course/mapper/FsUserCompanyUserQwMapper.java
  17. 13 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCompanyUserQwService.java
  18. 28 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyUserQwServiceImpl.java
  19. 4 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  20. 3 0
      fs-service/src/main/java/com/fs/his/service/IFsUserService.java
  21. 74 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  22. 99 0
      fs-service/src/main/java/com/fs/qw/domain/CustomerTransferApprovalQw.java
  23. 63 0
      fs-service/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalQwMapper.java
  24. 0 2
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  25. 46 0
      fs-service/src/main/java/com/fs/qw/param/FsUserCompanyUserQwParam.java
  26. 63 0
      fs-service/src/main/java/com/fs/qw/service/ICustomerTransferApprovalQwService.java
  27. 152 0
      fs-service/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalQwServiceImpl.java
  28. 45 0
      fs-service/src/main/java/com/fs/qw/vo/FsUserCompanyUserQwVO.java
  29. 9 10
      fs-service/src/main/resources/mapper/course/FsUserCompanyUserQwMapper.xml
  30. 126 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  31. 121 0
      fs-service/src/main/resources/mapper/qw/CustomerTransferApprovalQwMapper.xml

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

@@ -150,6 +150,19 @@ public class CompanyUserController extends BaseController
     {
         return toAjax(companyUserService.changeCompanyUser(users, companyUserId, companyId));
     }
+
+    /**
+     * 更换会员归属销售-企微的
+     * @return
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyUser:change')")
+    @Log(title = "更换会员归属-企微", businessType = BusinessType.OTHER)
+    @PostMapping("/changeCompanyUserQw")
+    public AjaxResult changeCompanyUserQw(@RequestBody List<UserProjectDTO> users, @RequestParam Long companyUserId, @RequestParam Long companyId)
+    {
+        return toAjax(companyUserService.changeCompanyUserQw(users, companyUserId, companyId));
+    }
+
     /**
      * 根据登录的用户公司获取所有的销售
      * @return

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

@@ -15,6 +15,7 @@ import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.course.dto.BatchSendCourseDTO;
 import com.fs.course.param.FsCourseLinkCreateParam;
+import com.fs.course.service.IFsUserCompanyUserQwService;
 import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.course.service.IFsUserCourseService;
 import com.fs.his.domain.FsUserAddress;
@@ -82,6 +83,8 @@ public class FsUserController extends BaseController
     private IFsUserIntegralLogsService userIntegralLogsService;
     @Autowired
     private IFsUserCompanyUserService userCompanyUserService;
+    @Autowired
+    private IFsUserCompanyUserQwService userCompanyUserQwService;
 
     @Autowired
     private SqlSessionFactory sqlSessionFactory;
@@ -166,6 +169,34 @@ public class FsUserController extends BaseController
         return getDataTable(list);
     }
 
+    @PreAuthorize("@ss.hasPermi('his:userQw:list')")
+    @GetMapping("/listProjectByQw")
+    public TableDataInfo listProjectByQw(FsUser fsUser)
+    {
+        startPage();
+        if(StringUtils.isNotEmpty(fsUser.getPhone())){
+            fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        }
+        List<FsUserVO> list = fsUserService.selectFsUserVOListByProjectByQw(fsUser);
+        boolean checkPhone = isCheckPhone();
+        for (FsUserVO fsUserVO : list) {
+            if(fsUserVO.getPhone() != null&&fsUserVO.getPhone()!=""){
+                if (!checkPhone){
+                    if (fsUserVO.getPhone().length()>11){
+                        fsUserVO.setPhone(decryptPhoneMk(fsUserVO.getPhone()));
+                    }else {
+                        fsUserVO.setPhone(fsUserVO.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                    }
+                } else {
+                    if (fsUserVO.getPhone().length()>11) {
+                        fsUserVO.setPhone(decryptPhone(fsUserVO.getPhone()));
+                    }
+                }
+            }
+        }
+        return getDataTable(list);
+    }
+
     @PreAuthorize("@ss.hasPermi('his:user:export')")
     @GetMapping("/exportListProject")
     public AjaxResult exportListProject(FsUser fsUser)
@@ -194,6 +225,34 @@ public class FsUserController extends BaseController
         return util.exportExcel(list, "项目会员数据");
     }
 
+    @PreAuthorize("@ss.hasPermi('his:user:exportQw')")
+    @GetMapping("/exportListProjectQw")
+    public AjaxResult exportListProjectQw(FsUser fsUser)
+    {
+        if(StringUtils.isNotEmpty(fsUser.getPhone())){
+            fsUser.setPhone(encryptPhone(fsUser.getPhone()));
+        }
+        List<FsUserVO> list = fsUserService.selectFsUserVOListByProjectByQw(fsUser);
+        boolean checkPhone = isCheckPhone();
+        for (FsUserVO fsUserVO : list) {
+            if(fsUserVO.getPhone() != null&&fsUserVO.getPhone()!=""){
+                if (!checkPhone){
+                    if (fsUserVO.getPhone().length()>11){
+                        fsUserVO.setPhone(decryptPhoneMk(fsUserVO.getPhone()));
+                    }else {
+                        fsUserVO.setPhone(fsUserVO.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                    }
+                } else {
+                    if (fsUserVO.getPhone().length()>11) {
+                        fsUserVO.setPhone(decryptPhone(fsUserVO.getPhone()));
+                    }
+                }
+            }
+        }
+        ExcelUtil<FsUserVO> util = new ExcelUtil<FsUserVO>(FsUserVO.class);
+        return util.exportExcel(list, "项目会员数据");
+    }
+
     /**
      * 导出用户列表
      */
@@ -301,6 +360,17 @@ public class FsUserController extends BaseController
         return toAjax(userCompanyUserService.deleteFsUserCompanyUserById(id));
     }
 
+    /**
+     * 删除微信用户和销售关系信息-企微
+     */
+    @PreAuthorize("@ss.hasPermi('his:userCompanyUserQw:remove')")
+    @Log(title = "微信用户和销售关系-企微", businessType = BusinessType.DELETE)
+    @DeleteMapping("/deleteQw/{id}")
+    public AjaxResult deleteQw(@PathVariable Long id)
+    {
+        return toAjax(userCompanyUserQwService.deleteFsUserCompanyUserQwById(id));
+    }
+
     /**
      * 查询用户
      */

+ 98 - 0
fs-admin/src/main/java/com/fs/qw/controller/FsUserAdminByQwController.java

@@ -0,0 +1,98 @@
+package com.fs.qw.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;
+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.ServletUtils;
+import com.fs.company.cache.ICompanyUserCacheService;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import com.fs.his.utils.PhoneUtil;
+import com.fs.im.service.OpenIMService;
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.dto.FsUserTransferParamDTO;
+import com.fs.qw.service.ICustomerTransferApprovalQwService;
+import com.fs.qw.service.ICustomerTransferApprovalService;
+import com.fs.store.param.h5.FsUserPageListParam;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+@Api(tags = "企微会员管理接口")
+@RestController
+@Slf4j
+@RequestMapping("/qw/fsUserByQw")
+@AllArgsConstructor
+public class FsUserAdminByQwController extends BaseController {
+
+    @Autowired
+    private IFsUserService fsUserService;
+
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
+
+    @Autowired
+    private ICustomerTransferApprovalQwService transferApprovalQwService;
+
+    @Autowired
+    private IFsUserCourseService fsUserCourseService;
+
+    @Autowired
+    private OpenIMService openIMService;
+
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:list')")
+    @PostMapping("/list")
+    @ApiOperation("会员列表(与移动端使用的相同查询)")
+    public TableDataInfo pageList(@RequestBody FsUserPageListParam param) {
+
+
+        if(param.getPhone()!=null && !"".equals(param.getPhone())){
+            param.setPhone(PhoneUtil.encryptPhone(param.getPhone()));
+        }
+        return fsUserService.selectFsUserPageListNewQw(param);
+    }
+
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:myList')")
+    @PostMapping("/myList")
+    @ApiOperation("我的会员列表(与移动端使用的相同查询)")
+    public TableDataInfo pageMyList(@RequestBody FsUserPageListParam param) {
+
+        if(param.getCompanyUserId() == null) {
+            throw new IllegalArgumentException("当前销售不存在!");
+        }
+        return fsUserService.selectFsUserPageListNew(param);
+    }
+
+    /**
+     * 获取用户详细信息
+     */
+    @GetMapping(value = "/{userId}")
+    public AjaxResult getInfo(@PathVariable("userId") Long userId)
+    {
+        return AjaxResult.success(fsUserService.selectFsUserPageListVOByUserIdQw(userId));
+    }
+
+    /**
+     * 修改用户
+     */
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:edit')")
+    @Log(title = "用户", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsUser fsUser)
+    {
+        return toAjax(fsUserService.updateFsUser(fsUser));
+    }
+
+
+}

+ 99 - 0
fs-admin/src/main/java/com/fs/qw/controller/FsUserCompanyUserQwController.java

@@ -0,0 +1,99 @@
+package com.fs.qw.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.poi.ExcelUtil;
+import com.fs.course.domain.FsUserCompanyUserQw;
+import com.fs.course.service.IFsUserCompanyUserQwService;
+import com.fs.qw.param.FsUserCompanyUserQwParam;
+import com.fs.qw.vo.FsUserCompanyUserQwVO;
+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 2025-10-23
+ */
+@RestController
+@RequestMapping("/qw/fsUserCompanyUserQw")
+public class FsUserCompanyUserQwController extends BaseController
+{
+    @Autowired
+    private IFsUserCompanyUserQwService fsUserCompanyUserQwService;
+
+    /**
+     * 查询微信用户和销售关系-企业微信自动的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsUserCompanyUserQwParam userQwParam)
+    {
+        startPage();
+        List<FsUserCompanyUserQwVO> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwListVO(userQwParam);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出微信用户和销售关系-企业微信自动的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:export')")
+    @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsUserCompanyUserQwParam userQwParam)
+    {
+        List<FsUserCompanyUserQwVO> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwListVO(userQwParam);
+        ExcelUtil<FsUserCompanyUserQwVO> util = new ExcelUtil<FsUserCompanyUserQwVO>(FsUserCompanyUserQwVO.class);
+        return util.exportExcel(list, "微信用户和销售关系-企业微信自动的数据");
+    }
+
+    /**
+     * 获取微信用户和销售关系-企业微信自动的详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsUserCompanyUserQwService.selectFsUserCompanyUserQwById(id));
+    }
+
+    /**
+     * 新增微信用户和销售关系-企业微信自动的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:add')")
+    @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsUserCompanyUserQw fsUserCompanyUserQw)
+    {
+        return toAjax(fsUserCompanyUserQwService.insertFsUserCompanyUserQw(fsUserCompanyUserQw));
+    }
+
+    /**
+     * 修改微信用户和销售关系-企业微信自动的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:edit') || @ss.hasPermi('qw:fsUserCompanyUserQw:myEdit')")
+    @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsUserCompanyUserQw fsUserCompanyUserQw)
+    {
+        return toAjax(fsUserCompanyUserQwService.updateFsUserCompanyUserQw(fsUserCompanyUserQw));
+    }
+
+    /**
+     * 删除微信用户和销售关系-企业微信自动的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:remove')")
+    @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsUserCompanyUserQwService.deleteFsUserCompanyUserQwByIds(ids));
+    }
+}

+ 105 - 0
fs-admin/src/main/java/com/fs/transfer/CustomerTransferApprovalQwController.java

@@ -0,0 +1,105 @@
+package com.fs.transfer;
+
+
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.framework.web.service.TokenService;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+import com.fs.qw.service.ICustomerTransferApprovalQwService;
+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 2025-10-24
+ */
+@RestController
+@RequestMapping("qw/system/approval")
+public class CustomerTransferApprovalQwController extends BaseController
+{
+    @Autowired
+    private ICustomerTransferApprovalQwService customerTransferApprovalQwService;
+
+    @Autowired
+    private TokenService tokenService;
+    /**
+     * 查询客户转移审批-企微的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        customerTransferApprovalQw.setInitiatorUserId(loginUser.getUser().getUserId());
+        List<CustomerTransferApprovalQw> list = customerTransferApprovalQwService.selectCustomerTransferApprovalQwList(customerTransferApprovalQw);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出客户转移审批-企微的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:export')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        List<CustomerTransferApprovalQw> list = customerTransferApprovalQwService.selectCustomerTransferApprovalQwList(customerTransferApprovalQw);
+        ExcelUtil<CustomerTransferApprovalQw> util = new ExcelUtil<CustomerTransferApprovalQw>(CustomerTransferApprovalQw.class);
+        return util.exportExcel(list, "客户转移审批-企微的数据");
+    }
+
+    /**
+     * 获取客户转移审批-企微的详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(customerTransferApprovalQwService.selectCustomerTransferApprovalQwById(id));
+    }
+
+    /**
+     * 新增客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:add')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return toAjax(customerTransferApprovalQwService.insertCustomerTransferApprovalQw(customerTransferApprovalQw));
+    }
+
+    /**
+     * 修改客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:edit') || @ss.hasPermi('qw:approval:revoke')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return toAjax(customerTransferApprovalQwService.updateCustomerTransferApprovalQw(customerTransferApprovalQw));
+    }
+
+    /**
+     * 删除客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:remove')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(customerTransferApprovalQwService.deleteCustomerTransferApprovalQwByIds(ids));
+    }
+}

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

@@ -539,6 +539,17 @@ public class CompanyUserController extends BaseController
             return AjaxResult.error("操作失败");
         }
     }
+
+    @Log(title = "是否允许客户能在其他销售那里能看", businessType = BusinessType.UPDATE)
+    @PutMapping("/allowedEveryoneView")
+    public AjaxResult allowedEveryoneView(@RequestParam Integer status, @RequestBody List<Long> userIds) {
+        Boolean r = companyUserService.isAllowedEveryoneView(status, userIds);
+        if (r) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("操作失败");
+        }
+    }
     @PostMapping("/common/uploadOSS")
     public R uploadOSS(@RequestParam("file") MultipartFile file,
                        @RequestParam("userId") String userId) throws Exception {

+ 144 - 0
fs-company/src/main/java/com/fs/company/controller/qw/FsUserAdminByQwController.java

@@ -0,0 +1,144 @@
+package com.fs.company.controller.qw;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.core.JsonProcessingException;
+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.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.company.cache.ICompanyUserCacheService;
+import com.fs.course.dto.BatchSendCourseDTO;
+import com.fs.course.param.FsCourseLinkCreateParam;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
+import com.fs.his.utils.PhoneUtil;
+import com.fs.im.dto.OpenImResponseDTO;
+import com.fs.im.service.OpenIMService;
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+import com.fs.qw.dto.FsUserTransferParamDTO;
+import com.fs.qw.service.ICustomerTransferApprovalQwService;
+import com.fs.qw.service.ICustomerTransferApprovalService;
+import com.fs.store.param.h5.FsUserPageListParam;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+import static com.fs.his.utils.PhoneUtil.encryptPhone;
+
+@Api(tags = "企微会员管理接口")
+@RestController
+@Slf4j
+@RequestMapping("/qw/fsUserByQw")
+@AllArgsConstructor
+public class FsUserAdminByQwController extends BaseController {
+
+    @Autowired
+    private IFsUserService fsUserService;
+
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ICustomerTransferApprovalQwService transferApprovalQwService;
+
+    @Autowired
+    private IFsUserCourseService fsUserCourseService;
+
+    @Autowired
+    private OpenIMService openIMService;
+
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:list')")
+    @PostMapping("/list")
+    @ApiOperation("会员列表(与移动端使用的相同查询)")
+    public TableDataInfo pageList(@RequestBody FsUserPageListParam param) {
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        if(param.getPhone()!=null && !"".equals(param.getPhone())){
+            param.setPhone(PhoneUtil.encryptPhone(param.getPhone()));
+        }
+        return fsUserService.selectFsUserPageListNewQw(param);
+    }
+
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:myList')")
+    @PostMapping("/myList")
+    @ApiOperation("我的会员列表(与移动端使用的相同查询)")
+    public TableDataInfo pageMyList(@RequestBody FsUserPageListParam param) {
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        param.setCompanyUserId(String.valueOf(loginUser.getUser().getUserId()));
+        param.setIsAdmin(loginUser.getUser().isAdmin());
+
+        if(param.getCompanyUserId() == null) {
+            throw new IllegalArgumentException("当前销售不存在!");
+        }
+        return fsUserService.selectFsUserPageListNew(param);
+    }
+
+    /**
+     * 转移
+     * @param param
+     */
+    @PostMapping("/transfer")
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:transfer')")
+    public R transfer(@RequestBody FsUserTransferParamDTO param){
+        log.info("客户转移: {}",param);
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setSourceCompanyUserId(loginUser.getUser().getUserId());
+        CustomerTransferApprovalQw transferApprovalQw = new CustomerTransferApprovalQw();
+        transferApprovalQw.setCorpId(String.valueOf(loginUser.getCompany().getCompanyId()));
+        transferApprovalQw.setCustomerIds(JSON.toJSONString(param.getUserIds()));
+        transferApprovalQw.setOriginalUserId(param.getSourceCompanyUserId());
+        transferApprovalQw.setTargetUserId(param.getTargetCompanyUserId());
+        transferApprovalQw.setInitiatorUserId(param.getSourceCompanyUserId());
+        transferApprovalQw.setContent(param.getContent());
+        transferApprovalQw.setCreatedAt(new Date());
+        transferApprovalQw.setUpdatedAt(new Date());
+        transferApprovalQw.setApprovalStatus(0);
+        transferApprovalQw.setTransferType(2);
+        transferApprovalQwService.insertCustomerTransferApprovalQw(transferApprovalQw);
+        return R.ok("转移申请已经提交,等待转移成功!");
+    }
+
+    /**
+     * 获取用户详细信息
+     */
+    @GetMapping(value = "/{userId}")
+    public AjaxResult getInfo(@PathVariable("userId") Long userId)
+    {
+        return AjaxResult.success(fsUserService.selectFsUserPageListVOByUserIdQw(userId));
+    }
+
+    /**
+     * 修改用户
+     */
+    @PreAuthorize("@ss.hasPermi('user:fsUserQw:edit')")
+    @Log(title = "用户", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsUser fsUser)
+    {
+        return toAjax(fsUserService.updateFsUser(fsUser));
+    }
+
+
+}

+ 9 - 6
fs-company/src/main/java/com/fs/company/controller/qw/FsUserCompanyUserQwController.java

@@ -1,6 +1,9 @@
 package com.fs.company.controller.qw;
 
 import java.util.List;
+
+import com.fs.qw.param.FsUserCompanyUserQwParam;
+import com.fs.qw.vo.FsUserCompanyUserQwVO;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -38,10 +41,10 @@ public class FsUserCompanyUserQwController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:list')")
     @GetMapping("/list")
-    public TableDataInfo list(FsUserCompanyUserQw fsUserCompanyUserQw)
+    public TableDataInfo list(FsUserCompanyUserQwParam userQwParam)
     {
         startPage();
-        List<FsUserCompanyUserQw> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwList(fsUserCompanyUserQw);
+        List<FsUserCompanyUserQwVO> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwListVO(userQwParam);
         return getDataTable(list);
     }
 
@@ -51,10 +54,10 @@ public class FsUserCompanyUserQwController extends BaseController
     @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:export')")
     @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
-    public AjaxResult export(FsUserCompanyUserQw fsUserCompanyUserQw)
+    public AjaxResult export(FsUserCompanyUserQwParam userQwParam)
     {
-        List<FsUserCompanyUserQw> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwList(fsUserCompanyUserQw);
-        ExcelUtil<FsUserCompanyUserQw> util = new ExcelUtil<FsUserCompanyUserQw>(FsUserCompanyUserQw.class);
+        List<FsUserCompanyUserQwVO> list = fsUserCompanyUserQwService.selectFsUserCompanyUserQwListVO(userQwParam);
+        ExcelUtil<FsUserCompanyUserQwVO> util = new ExcelUtil<FsUserCompanyUserQwVO>(FsUserCompanyUserQwVO.class);
         return util.exportExcel(list, "微信用户和销售关系-企业微信自动的数据");
     }
 
@@ -82,7 +85,7 @@ public class FsUserCompanyUserQwController extends BaseController
     /**
      * 修改微信用户和销售关系-企业微信自动的
      */
-    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:edit')")
+    @PreAuthorize("@ss.hasPermi('qw:fsUserCompanyUserQw:edit') || @ss.hasPermi('qw:fsUserCompanyUserQw:myEdit')")
     @Log(title = "微信用户和销售关系-企业微信自动的", businessType = BusinessType.UPDATE)
     @PutMapping
     public AjaxResult edit(@RequestBody FsUserCompanyUserQw fsUserCompanyUserQw)

+ 111 - 0
fs-company/src/main/java/com/fs/transfer/CustomerTransferApprovalQwController.java

@@ -0,0 +1,111 @@
+package com.fs.transfer;
+
+import java.util.List;
+
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.framework.security.LoginUser;
+import com.fs.framework.service.TokenService;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+import com.fs.qw.service.ICustomerTransferApprovalQwService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 客户转移审批-企微的Controller
+ *
+ * @author fs
+ * @date 2025-10-24
+ */
+@RestController
+@RequestMapping("qw/system/approval")
+public class CustomerTransferApprovalQwController extends BaseController
+{
+    @Autowired
+    private ICustomerTransferApprovalQwService customerTransferApprovalQwService;
+
+    @Autowired
+    private TokenService tokenService;
+    /**
+     * 查询客户转移审批-企微的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        customerTransferApprovalQw.setInitiatorUserId(loginUser.getUser().getUserId());
+        List<CustomerTransferApprovalQw> list = customerTransferApprovalQwService.selectCustomerTransferApprovalQwList(customerTransferApprovalQw);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出客户转移审批-企微的列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:export')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        List<CustomerTransferApprovalQw> list = customerTransferApprovalQwService.selectCustomerTransferApprovalQwList(customerTransferApprovalQw);
+        ExcelUtil<CustomerTransferApprovalQw> util = new ExcelUtil<CustomerTransferApprovalQw>(CustomerTransferApprovalQw.class);
+        return util.exportExcel(list, "客户转移审批-企微的数据");
+    }
+
+    /**
+     * 获取客户转移审批-企微的详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(customerTransferApprovalQwService.selectCustomerTransferApprovalQwById(id));
+    }
+
+    /**
+     * 新增客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:add')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return toAjax(customerTransferApprovalQwService.insertCustomerTransferApprovalQw(customerTransferApprovalQw));
+    }
+
+    /**
+     * 修改客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:edit') || @ss.hasPermi('qw:approval:revoke')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return toAjax(customerTransferApprovalQwService.updateCustomerTransferApprovalQw(customerTransferApprovalQw));
+    }
+
+    /**
+     * 删除客户转移审批-企微的
+     */
+    @PreAuthorize("@ss.hasPermi('qw:approval:remove')")
+    @Log(title = "客户转移审批-企微的", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(customerTransferApprovalQwService.deleteCustomerTransferApprovalQwByIds(ids));
+    }
+}

+ 77 - 0
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -8,10 +8,17 @@ import com.fs.app.taskService.SopLogsTaskService;
 import com.fs.app.taskService.SopWxLogsService;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyUserMapper;
+import com.fs.course.domain.FsUserCompanyUserQw;
+import com.fs.course.domain.FsUserCourse;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.course.mapper.FsUserCourseMapper;
+import com.fs.course.param.FsUserCourseVideoAddKfUParam;
 import com.fs.course.param.newfs.FsUserCourseAddCompanyUserParam;
 import com.fs.course.service.*;
 import com.fs.his.domain.FsUser;
+import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.service.IFsInquiryOrderService;
 import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.qw.domain.QwCompany;
@@ -39,6 +46,7 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 
 @Api("公共接口")
 @RestController
@@ -109,6 +117,75 @@ public class CommonController {
     @Autowired
     private IFsCourseLinkService iFsCourseLinkService;
 
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
+
+    @Autowired
+    private FsUserCourseMapper fsUserCourseMapper;
+
+
+    @Autowired
+    private IFsUserCompanyUserQwService userCompanyUserQwService;
+
+    @Autowired
+    private FsUserMapper fsUserMapper;
+
+    /**
+     * 发官方通连
+     */
+    @GetMapping("/Relationship")
+    public R Relationship() throws Exception {
+
+        FsUserCourseVideoAddKfUParam param=new FsUserCourseVideoAddKfUParam();
+        param.setQwUserId("34391");
+        param.setVideoId(336L);
+        param.setUserId(84L);
+        param.setCorpId("ww74ad121092304bd8");
+        param.setCompanyUserId(687L);
+        param.setCompanyId(1L);
+        param.setCourseId(23L);
+        param.setQwExternalId(221749L);
+
+
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
+
+        try {
+            // 判断该销售是否存在
+            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getCompanyUserId());
+            if (companyUser == null) {
+                return R.error(405, "当前客服不存在");
+            }
+
+            if (companyUser.getIsAllowedEveryoneView()!=null && companyUser.getIsAllowedEveryoneView() == 2) {
+                // 获取课程所属项目id
+                FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
+                Long courseProject = fsUserCourse.getProject();
+                if (Objects.isNull(courseProject)) {
+                    return R.error(504, "课程配置错误,项目归属为空,课程ID: " + param.getCourseId());
+                }
+
+                // 查询【用户-项目】关系
+                FsUserCompanyUserQw userCompanyUserQw = userCompanyUserQwService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject);
+
+                // 添加逻辑:如果存在fs_user表数据,但是又不存在fs_user_company_user表,则表示给他绑上(看客户更喜欢哪个销售)
+                if (Objects.isNull(userCompanyUserQw)) {
+                    userCompanyUserQw = userCompanyUserQwService.bindRelationship(param.getUserId(), courseProject, companyUser.getCompanyId(), companyUser.getUserId(), 1);
+                }
+
+                // 逻辑调整:如果客户已经绑定了销售,直接提示,
+                if (!param.getCompanyUserId().equals(userCompanyUserQw.getCompanyUserId())) {
+                    return R.error(500, "该用户(" + fsUser.getUserId() + ")已成为其他客服会员,请在相应客服上观看");
+                }
+            }
+
+        }catch (Exception e){
+            return null;
+        }
+
+        return R.ok();
+    }
+
+
     /**
     * 发官方通连
     */

+ 1 - 0
fs-service/src/main/java/com/fs/company/mapper/CompanyUserMapper.java

@@ -304,6 +304,7 @@ public interface CompanyUserMapper
     String selectCompanyUserNameByIds(@Param("companyUserIds")String companyUserIds);
 
     int updateAllowedAllRegister(@Param("status") boolean status, @Param("userIds")List<Long> userIds);
+    int updateAllowedEveryoneView(@Param("statusNum") Integer statusNum, @Param("userIds")List<Long> userIds);
 
     List<QwIpadTotalVo> selectCompanyByIpadStatus(@Param("dateTime") String dateTime);
 

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

@@ -183,6 +183,7 @@ public interface ICompanyUserService {
      * @return
      */
     int changeCompanyUser(List<UserProjectDTO> users, Long companyUserId, Long companyId);
+    int changeCompanyUserQw(List<UserProjectDTO> users, Long companyUserId, Long companyId);
 
     /**
      * 查询销售选项列表
@@ -224,6 +225,7 @@ public interface ICompanyUserService {
      * @return true/false
      */
     Boolean isAllowedAllRegister(boolean status,  List<Long> userIds);
+    Boolean isAllowedEveryoneView(Integer status,  List<Long> userIds);
 
     List<QwIpadTotalVo> selectCompanyByIpadStatus(String dateTime);
 

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

@@ -25,6 +25,7 @@ import com.fs.company.param.CompanyUserQwParam;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.company.vo.*;
+import com.fs.course.service.IFsUserCompanyUserQwService;
 import com.fs.course.service.IFsUserCompanyUserService;
 import com.fs.his.mapper.FsUserMapper;
 import com.fs.his.service.IFsCityService;
@@ -99,9 +100,13 @@ public class CompanyUserServiceImpl implements ICompanyUserService
 
     @Autowired
     private FsUserMapper fsUserMapper;
+
     @Autowired
     private IFsUserCompanyUserService userCompanyUserService;
 
+    @Autowired
+    private IFsUserCompanyUserQwService userCompanyUserQwService;
+
     @Autowired
     private ICompanyUserService companyUserService;
 
@@ -799,6 +804,19 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return 1;
     }
 
+    @Override
+    public int changeCompanyUserQw(List<UserProjectDTO> users, Long companyUserId, Long companyId) {
+
+        CompanyUser toUser = companyUserMapper.selectCompanyUserById(companyUserId);
+        if (Objects.isNull(toUser)) {
+            throw new ServiceException("需要更换归属的销售不存在");
+        }
+        for (UserProjectDTO u : users) {
+            userCompanyUserQwService.changeRelationship(u.getUserId(), u.getProjectId(), toUser.getCompanyId(), toUser.getUserId());
+        }
+        return 1;
+    }
+
     /**
      * 查询销售选项列表
      * @param params    参数
@@ -924,6 +942,16 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return true;
     }
 
+    @Override
+    public Boolean isAllowedEveryoneView(Integer status, List<Long> userIds) {
+        try {
+            companyUserMapper.updateAllowedEveryoneView(status, userIds);
+        } catch (RuntimeException e) {
+            throw new ServiceException("操作异常");
+        }
+        return true;
+    }
+
     @Override
     public List<QwIpadTotalVo> selectCompanyByIpadStatus(String dateTime) {
         return companyUserMapper.selectCompanyByIpadStatus(dateTime);

+ 3 - 0
fs-service/src/main/java/com/fs/company/vo/CompanyUserQwListVO.java

@@ -128,6 +128,9 @@ public class CompanyUserQwListVO extends BaseEntity {
     /** 是否允许所有方式注册会员,1-是,0-否,默认1(用于个微注册会员) */
     private Integer isAllowedAllRegister;
 
+    /** 是否允许客户能在其他销售那里能看,1-是,2-否,默认1(用于企业微信客户和销售之间的关系) */
+    private Integer isAllowedEveryoneView;
+
     /** 医生id */
     private Long doctorId;
 

+ 3 - 0
fs-service/src/main/java/com/fs/course/domain/FsUserCompanyUserQw.java

@@ -56,6 +56,9 @@ public class FsUserCompanyUserQw {
     @Excel(name = "状态 0小黑屋 1正常 2拉黑")
     private Integer status;
 
+    @Excel(name = "备注")
+    private String remark;
+
     /**
      * 创建时间
      */

+ 19 - 9
fs-service/src/main/java/com/fs/course/mapper/FsUserCompanyUserQwMapper.java

@@ -3,17 +3,20 @@ package com.fs.course.mapper;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsUserCompanyUserQw;
+import com.fs.qw.param.FsUserCompanyUserQwParam;
+import com.fs.qw.vo.FsUserCompanyUserQwVO;
+import org.apache.ibatis.annotations.Select;
 
 /**
  * 微信用户和销售关系-企业微信自动的Mapper接口
- * 
+ *
  * @author fs
  * @date 2025-10-23
  */
 public interface FsUserCompanyUserQwMapper extends BaseMapper<FsUserCompanyUserQw>{
     /**
      * 查询微信用户和销售关系-企业微信自动的
-     * 
+     *
      * @param id 微信用户和销售关系-企业微信自动的主键
      * @return 微信用户和销售关系-企业微信自动的
      */
@@ -21,15 +24,22 @@ public interface FsUserCompanyUserQwMapper extends BaseMapper<FsUserCompanyUserQ
 
     /**
      * 查询微信用户和销售关系-企业微信自动的列表
-     * 
-     * @param fsUserCompanyUserQw 微信用户和销售关系-企业微信自动的
+     *
+     * @param userQwParam 微信用户和销售关系-企业微信自动的
      * @return 微信用户和销售关系-企业微信自动的集合
      */
-    List<FsUserCompanyUserQw> selectFsUserCompanyUserQwList(FsUserCompanyUserQw fsUserCompanyUserQw);
+    List<FsUserCompanyUserQw> selectFsUserCompanyUserQwList(FsUserCompanyUserQw userQwParam);
+
+    @Select("<script> " +
+            "select cuq.id, cuq.user_id, cuq.project_id, cuq.create_time, cuq.remark, cu.nick_name as companyUserName  " +
+            "from fs_user_company_user_qw cuq " +
+            "left join  company_user cu on cuq.company_user_id=cu.user_id " +
+            "</script> ")
+    List<FsUserCompanyUserQwVO> selectFsUserCompanyUserQwListVO(FsUserCompanyUserQwParam userQwParam);
 
     /**
      * 新增微信用户和销售关系-企业微信自动的
-     * 
+     *
      * @param fsUserCompanyUserQw 微信用户和销售关系-企业微信自动的
      * @return 结果
      */
@@ -37,7 +47,7 @@ public interface FsUserCompanyUserQwMapper extends BaseMapper<FsUserCompanyUserQ
 
     /**
      * 修改微信用户和销售关系-企业微信自动的
-     * 
+     *
      * @param fsUserCompanyUserQw 微信用户和销售关系-企业微信自动的
      * @return 结果
      */
@@ -45,7 +55,7 @@ public interface FsUserCompanyUserQwMapper extends BaseMapper<FsUserCompanyUserQ
 
     /**
      * 删除微信用户和销售关系-企业微信自动的
-     * 
+     *
      * @param id 微信用户和销售关系-企业微信自动的主键
      * @return 结果
      */
@@ -53,7 +63,7 @@ public interface FsUserCompanyUserQwMapper extends BaseMapper<FsUserCompanyUserQ
 
     /**
      * 批量删除微信用户和销售关系-企业微信自动的
-     * 
+     *
      * @param ids 需要删除的数据主键集合
      * @return 结果
      */

+ 13 - 0
fs-service/src/main/java/com/fs/course/service/IFsUserCompanyUserQwService.java

@@ -4,6 +4,8 @@ import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.course.domain.FsUserCompanyUser;
 import com.fs.course.domain.FsUserCompanyUserQw;
+import com.fs.qw.param.FsUserCompanyUserQwParam;
+import com.fs.qw.vo.FsUserCompanyUserQwVO;
 
 /**
  * 微信用户和销售关系-企业微信自动的Service接口
@@ -40,6 +42,7 @@ public interface IFsUserCompanyUserQwService extends IService<FsUserCompanyUserQ
      * @return 微信用户和销售关系-企业微信自动的集合
      */
     List<FsUserCompanyUserQw> selectFsUserCompanyUserQwList(FsUserCompanyUserQw fsUserCompanyUserQw);
+    List<FsUserCompanyUserQwVO> selectFsUserCompanyUserQwListVO(FsUserCompanyUserQwParam userQwParam);
 
     /**
      * 新增微信用户和销售关系-企业微信自动的
@@ -57,6 +60,16 @@ public interface IFsUserCompanyUserQwService extends IService<FsUserCompanyUserQ
      */
     int updateFsUserCompanyUserQw(FsUserCompanyUserQw fsUserCompanyUserQw);
 
+
+    /**
+     * 修改会员-项目-销售关系
+     * @param userId        会员ID
+     * @param projectId     项目ID
+     * @param companyId     公司ID
+     * @param companyUserId 销售ID
+     */
+    void changeRelationship(Long userId, Long projectId, Long companyId, Long companyUserId);
+
     /**
      * 批量删除微信用户和销售关系-企业微信自动的
      *

+ 28 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCompanyUserQwServiceImpl.java

@@ -1,13 +1,17 @@
 package com.fs.course.service.impl;
 
 import java.time.LocalDateTime;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.utils.DateUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.course.domain.FsUserCompanyUser;
+import com.fs.qw.param.FsUserCompanyUserQwParam;
+import com.fs.qw.vo.FsUserCompanyUserQwVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.fs.course.mapper.FsUserCompanyUserQwMapper;
@@ -23,6 +27,10 @@ import com.fs.course.service.IFsUserCompanyUserQwService;
 @Service
 public class FsUserCompanyUserQwServiceImpl extends ServiceImpl<FsUserCompanyUserQwMapper, FsUserCompanyUserQw> implements IFsUserCompanyUserQwService {
 
+
+    @Autowired
+    private FsUserCompanyUserQwMapper fsUserCompanyUserQwMapper;
+
     /**
      * 查询微信用户和销售关系-企业微信自动的
      *
@@ -67,6 +75,12 @@ public class FsUserCompanyUserQwServiceImpl extends ServiceImpl<FsUserCompanyUse
     public List<FsUserCompanyUserQw> selectFsUserCompanyUserQwList(FsUserCompanyUserQw fsUserCompanyUserQw)
     {
         return baseMapper.selectFsUserCompanyUserQwList(fsUserCompanyUserQw);
+
+    }
+
+    @Override
+    public List<FsUserCompanyUserQwVO> selectFsUserCompanyUserQwListVO(FsUserCompanyUserQwParam userQwParam) {
+        return fsUserCompanyUserQwMapper.selectFsUserCompanyUserQwListVO(userQwParam);
     }
 
     /**
@@ -95,6 +109,20 @@ public class FsUserCompanyUserQwServiceImpl extends ServiceImpl<FsUserCompanyUse
         return baseMapper.updateFsUserCompanyUserQw(fsUserCompanyUserQw);
     }
 
+    @Override
+    public void changeRelationship(Long userId, Long projectId, Long companyId, Long companyUserId) {
+        LambdaQueryWrapper<FsUserCompanyUserQw> queryWrapper = Wrappers.<FsUserCompanyUserQw>lambdaQuery()
+                .eq(FsUserCompanyUserQw::getUserId, userId)
+                .eq(FsUserCompanyUserQw::getProjectId, projectId)
+                .last("limit 1");
+        FsUserCompanyUserQw userCompanyUserQw = getOne(queryWrapper);
+        if (Objects.nonNull(userCompanyUserQw)) {
+            userCompanyUserQw.setCompanyId(companyId);
+            userCompanyUserQw.setCompanyUserId(companyUserId);
+            updateById(userCompanyUserQw);
+        }
+    }
+
     /**
      * 批量删除微信用户和销售关系-企业微信自动的
      *

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

@@ -269,6 +269,7 @@ public interface FsUserMapper
     void transferCompanyUser(FsUserTransferParamDTO param);
 
     List<FsUserPageListVO> selectFsUserPageListNew(FsUserPageListParam param);
+    List<FsUserPageListVO> selectFsUserPageListNewQw(FsUserPageListParam param);
 
     Long selectFsUserPageListCount(FsUserPageListParam param);
 
@@ -349,8 +350,11 @@ public interface FsUserMapper
 
     @Select("select * from fs_user where user_id=#{userId} for update")
     FsUser selectFsUserByIdForUpdate(Long userId);
+
     List<FsUserVO> selectFsUserVOListByProject(@Param("maps") FsUser fsUser);
 
+    List<FsUserVO> selectFsUserVOListByProjectByQw(@Param("maps") FsUser fsUser);
+
     FsUserAndCompanyAndDoctorVo selectCompanyAndDoctor(@Param("userId")Long userId);
 
     List<FsUser> selectUserNameByIds(@Param("userIds") String userIds);

+ 3 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserService.java

@@ -153,6 +153,7 @@ public interface IFsUserService
     void transfer(FsUserTransferParamDTO transferParam);
 
     TableDataInfo selectFsUserPageListNew(FsUserPageListParam param);
+    TableDataInfo selectFsUserPageListNewQw(FsUserPageListParam param);
 
     Long selectFsUserCount(FsUserPageListParam param);
     Long selectFsUserCount(int type,Long companyI,Long companyUserId);
@@ -186,6 +187,7 @@ public interface IFsUserService
     ResponseResult<Boolean> becomeMember(@Valid FsUserCourseBeMemberParam param);
 
     FsUserPageListVO selectFsUserPageListVOByUserId(Long userId);
+    FsUserPageListVO selectFsUserPageListVOByUserIdQw(Long userId);
 
     /**
      * 查询项目会员数据
@@ -194,6 +196,7 @@ public interface IFsUserService
      * @return
      */
     List<FsUserVO> selectFsUserVOListByProject(FsUser fsUser);
+    List<FsUserVO> selectFsUserVOListByProjectByQw(FsUser fsUser);
 
     FsUserAndCompanyAndDoctorVo selectCompanyAndDoctor(Long userId);
 

+ 74 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -760,6 +760,62 @@ public class FsUserServiceImpl implements IFsUserService {
         return rspData;
     }
 
+    @Override
+    public TableDataInfo selectFsUserPageListNewQw(FsUserPageListParam param) {
+
+        // 找出下级销售
+        String companyUserId = param.getCompanyUserId();
+        if (StringUtils.isNotBlank(companyUserId)) {
+            Long companyUser = Long.parseLong(companyUserId);
+            Set<Long> userIds = companyUserCacheService.selectUserAllCompanyUserId(companyUser);
+            if (userIds != null || userIds.size() <= 1) {
+                if (param.getIsAdmin() != null && param.getIsAdmin()) {
+                    List<CompanyUser> companyUsers = companyUserMapper.selectCompanyUserByCompanyId(param.getCompanyId());
+                    userIds = companyUsers.stream().map(CompanyUser::getUserId).collect(Collectors.toSet());
+                }
+            }
+            param.setCompanyUserIds(userIds);
+        }
+
+        List<FsUserPageListVO> fsUserPageListNewQw = fsUserMapper.selectFsUserPageListNewQw(param);
+
+        for (FsUserPageListVO item : fsUserPageListNewQw) {
+            if (item.getCompanyUserId() != null) {
+                String companyUserName = companyUserCacheService.selectCompanyUserNameUserById(item.getCompanyUserId());
+                if (companyUserName != null) {
+                    item.setCompanyUserNickName(companyUserName);
+                }
+            }
+            if (item.getPhone() != null) {
+                item.setPhone(ParseUtils.parsePhone(item.getPhone()));
+            }
+            if (item.getStatus() != null) {
+                String userStatus = DictUtils.getDictLabel("user_status", String.valueOf(item.getStatus()));
+                if (StringUtils.isNotBlank(userStatus)) {
+                    item.setStatusText(userStatus);
+                }
+            }
+
+            // 解密
+            if (item.getPhone() != null && item.getPhone() != "") {
+                if (item.getPhone().length() > 11) {
+                    item.setPhone(decryptPhoneMk(item.getPhone()));
+                } else {
+                    item.setPhone(item.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
+                }
+            }
+
+        }
+
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(HttpStatus.SUCCESS);
+        rspData.setMsg("查询成功");
+        rspData.setRows(fsUserPageListNewQw);
+
+        rspData.setTotal(this.selectFsUserCount(param));
+        return rspData;
+    }
+
     @Override
     public Long selectFsUserCount(FsUserPageListParam param) {
         return fsUserMapper.selectFsUserPageListCount(param);
@@ -1136,6 +1192,19 @@ public class FsUserServiceImpl implements IFsUserService {
         return item;
     }
 
+    @Override
+    public FsUserPageListVO selectFsUserPageListVOByUserIdQw(Long userId) {
+        FsUser fsUser = fsUserMapper.selectFsUserByUserId(userId);
+        FsUserPageListVO item = new FsUserPageListVO();
+        BeanUtils.copyProperties(fsUser, item);
+        item.setNickname(fsUser.getNickName());
+
+        if (item.getPhone() != null) {
+            item.setPhone(ParseUtils.parsePhone(item.getPhone()));
+        }
+        return item;
+    }
+
     @Override
     @Transactional
     public void addMoney(FsStoreOrderScrm order) {
@@ -1175,6 +1244,11 @@ public class FsUserServiceImpl implements IFsUserService {
         return fsUserMapper.selectFsUserVOListByProject(fsUser);
     }
 
+    @Override
+    public List<FsUserVO> selectFsUserVOListByProjectByQw(FsUser fsUser) {
+        return fsUserMapper.selectFsUserVOListByProjectByQw(fsUser);
+    }
+
     @Override
     public FsUserAndCompanyAndDoctorVo selectCompanyAndDoctor(Long userId) {
         return fsUserMapper.selectCompanyAndDoctor(userId);

+ 99 - 0
fs-service/src/main/java/com/fs/qw/domain/CustomerTransferApprovalQw.java

@@ -0,0 +1,99 @@
+package com.fs.qw.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import com.fs.qw.vo.TransferCustomDTO;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 客户转移审批对象 customer_transfer_approval
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerTransferApprovalQw extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 唯一主键 ID */
+    private Long id;
+
+    /** 企业 ID */
+    @Excel(name = "企业 ID")
+    private String corpId;
+    private String companyName;
+
+    /** 转移类型: 1=离职继承, 2=在职转接 */
+    @Excel(name = "转移类型: 1=离职继承, 2=在职转接")
+    private Integer transferType;
+    private String transferTypeText;
+
+    /** 客户 ID 列表 (JSON 数组字符串或逗号分隔) */
+    @Excel(name = "客户 ID 列表 (JSON 数组字符串或逗号分隔)")
+    private String customerIds;
+    private List<TransferCustomDTO> customerList;
+
+    /** 原负责人用户 ID (离职继承时为离职人员ID,在职转接时为转出人员ID) */
+    @Excel(name = "原负责人用户 ID (离职继承时为离职人员ID,在职转接时为转出人员ID)")
+    private Long originalUserId;
+    private String originalUserName;
+
+    /** 目标接收销售用户 ID */
+    @Excel(name = "目标接收销售用户 ID")
+    private Long targetUserId;
+    private String targetUserName;
+
+    /** 发起此转移请求的用户 ID */
+    @Excel(name = "发起此转移请求的用户 ID")
+    private Long initiatorUserId;
+    private String initiatorUserName;
+
+    /**
+     * 转移前数据
+     */
+    private String transferBefore;
+
+    /** 转移提示内容/原因 */
+    @Excel(name = "转移提示内容/原因")
+    private String content;
+
+    /** 审批状态: 0=待审批, 1=审批通过, 2=审批驳回, 3=已撤销 */
+    @Excel(name = "审批状态: 0=待审批, 1=审批通过, 2=审批驳回, 3=已撤销")
+    private Integer approvalStatus;
+    private String approvalStatusText;
+
+    /** 审批人用户 ID */
+    @Excel(name = "审批人用户 ID")
+    private Long approverUserId;
+
+    /** 审批意见/备注 */
+    @Excel(name = "审批意见/备注")
+    private String approvalRemark;
+
+    /** 审批处理时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "审批处理时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date processedAt;
+
+    /** 记录创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "记录创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createdAt;
+
+    /** 记录最后更新时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "记录最后更新时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date updatedAt;
+
+}

+ 63 - 0
fs-service/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalQwMapper.java

@@ -0,0 +1,63 @@
+package com.fs.qw.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+
+import java.util.List;
+
+/**
+ * 客户转移审批-企微的Mapper接口
+ *
+ * @author fs
+ * @date 2025-10-24
+ */
+public interface CustomerTransferApprovalQwMapper extends BaseMapper<CustomerTransferApprovalQw> {
+    /**
+     * 查询客户转移审批-企微的
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 客户转移审批-企微的
+     */
+    CustomerTransferApprovalQw selectCustomerTransferApprovalQwById(Long id);
+
+    /**
+     * 查询客户转移审批-企微的列表
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 客户转移审批-企微的集合
+     */
+    List<CustomerTransferApprovalQw> selectCustomerTransferApprovalQwList(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 新增客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    int insertCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 修改客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    int updateCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 删除客户转移审批-企微的
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 结果
+     */
+    int deleteCustomerTransferApprovalQwById(Long id);
+
+    /**
+     * 批量删除客户转移审批-企微的
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteCustomerTransferApprovalQwByIds(Long[] ids);
+}

+ 0 - 2
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -259,7 +259,6 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
             "            <if test=\"customerId != null \"> and ec.customer_id = #{customerId}</if>\n" +
             "            <if test=\"status != null \"> and ec.status = #{status}</if>\n" +
             "            <if test=\"stageStatus != null \"> and ec.stage_status = #{stageStatus}</if>\n" +
-            "            <if test=\"userRepeat != null \"> and ec.user_repeat = #{userRepeat}</if>\n" +
             "            <if test=\"transferStatus != null \"> and ec.transfer_status = #{transferStatus}</if>\n" +
             "            <if test=\"qwUserId != null \"> and ec.qw_user_id = #{qwUserId}</if>\n" +
             "            <if test=\"level != null \"> and ec.level = #{level}</if>\n" +
@@ -321,7 +320,6 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
             "            <if test=\"customerId != null \"> and ec.customer_id = #{customerId}</if>\n" +
             "            <if test=\"status != null \"> and ec.status = #{status}</if>\n" +
             "            <if test=\"stageStatus != null \"> and ec.stage_status = #{stageStatus}</if>\n" +
-            "            <if test=\"userRepeat != null \"> and ec.user_repeat = #{userRepeat}</if>\n" +
             "            <if test=\"transferStatus != null \"> and ec.transfer_status = #{transferStatus}</if>\n" +
             "            <if test=\"qwUserId != null \"> and ec.qw_user_id = #{qwUserId}</if>\n" +
             "            <if test=\"level != null \"> and ec.level = #{level}</if>\n" +

+ 46 - 0
fs-service/src/main/java/com/fs/qw/param/FsUserCompanyUserQwParam.java

@@ -0,0 +1,46 @@
+package com.fs.qw.param;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class FsUserCompanyUserQwParam {
+
+
+    /** id */
+    private Long id;
+
+    /** 用户id(关联fs_user表user_id) */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    @Excel(name = "会员昵称")
+    private String nickname;
+
+    /** 销售id */
+    @Excel(name = "销售id")
+    private Long companyUserId;
+
+    /** 销售名称 */
+    @Excel(name = "销售名称")
+    private String companyUserName;
+
+    /** 公司ID */
+    @Excel(name = "公司ID")
+    private Long companyId;
+
+    /** 课程项目ID */
+    @Excel(name = "课程项目ID")
+    private Long projectId;
+
+    @Excel(name = "课程项目名称")
+    private String projectName;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+}

+ 63 - 0
fs-service/src/main/java/com/fs/qw/service/ICustomerTransferApprovalQwService.java

@@ -0,0 +1,63 @@
+package com.fs.qw.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+
+import java.util.List;
+
+/**
+ * 客户转移审批-企微的Service接口
+ *
+ * @author fs
+ * @date 2025-10-24
+ */
+public interface ICustomerTransferApprovalQwService extends IService<CustomerTransferApprovalQw> {
+    /**
+     * 查询客户转移审批-企微的
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 客户转移审批-企微的
+     */
+    CustomerTransferApprovalQw selectCustomerTransferApprovalQwById(Long id);
+
+    /**
+     * 查询客户转移审批-企微的列表
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 客户转移审批-企微的集合
+     */
+    List<CustomerTransferApprovalQw> selectCustomerTransferApprovalQwList(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 新增客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    int insertCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 修改客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    int updateCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw);
+
+    /**
+     * 批量删除客户转移审批-企微的
+     *
+     * @param ids 需要删除的客户转移审批-企微的主键集合
+     * @return 结果
+     */
+    int deleteCustomerTransferApprovalQwByIds(Long[] ids);
+
+    /**
+     * 删除客户转移审批-企微的信息
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 结果
+     */
+    int deleteCustomerTransferApprovalQwById(Long id);
+}

+ 152 - 0
fs-service/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalQwServiceImpl.java

@@ -0,0 +1,152 @@
+package com.fs.qw.service.impl;
+
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.DictUtils;
+import com.fs.company.cache.ICompanyCacheService;
+import com.fs.company.cache.ICompanyUserCacheService;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.domain.CustomerTransferApprovalQw;
+import com.fs.qw.mapper.CustomerTransferApprovalQwMapper;
+import com.fs.qw.service.ICustomerTransferApprovalQwService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 客户转移审批-企微的Service业务层处理
+ *
+ * @author fs
+ * @date 2025-10-24
+ */
+@Service
+public class CustomerTransferApprovalQwServiceImpl extends ServiceImpl<CustomerTransferApprovalQwMapper, CustomerTransferApprovalQw> implements ICustomerTransferApprovalQwService {
+
+
+    @Autowired
+    private CustomerTransferApprovalQwMapper transferApprovalQwMapper;
+
+    @Autowired
+    private ICompanyCacheService companyCacheService;
+
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
+
+    /**
+     * 查询客户转移审批-企微的
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 客户转移审批-企微的
+     */
+    @Override
+    public CustomerTransferApprovalQw selectCustomerTransferApprovalQwById(Long id)
+    {
+        return baseMapper.selectCustomerTransferApprovalQwById(id);
+    }
+
+    /**
+     * 查询客户转移审批-企微的列表
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 客户转移审批-企微的
+     */
+    @Override
+    public List<CustomerTransferApprovalQw> selectCustomerTransferApprovalQwList(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        List<CustomerTransferApprovalQw> list = transferApprovalQwMapper.selectCustomerTransferApprovalQwList(customerTransferApprovalQw);
+        for (CustomerTransferApprovalQw item : list) {
+            if(ObjectUtils.isNotNull(item.getCorpId())){
+                Company company = companyCacheService.selectCompanyById(Long.valueOf(item.getCorpId()));
+                if(ObjectUtils.isNotNull(company)){
+                    item.setCompanyName(String.format("%s_%s",company.getCompanyName(),company.getCompanyId()));
+                }
+            }
+            if(ObjectUtils.isNotNull(item.getTransferType())){
+                String transferType = DictUtils.getDictLabel("transfer_type", String.valueOf(item.getTransferType()));
+                if(ObjectUtils.isNotEmpty(transferType)){
+                    item.setTransferTypeText(transferType);
+                }
+            }
+            if(ObjectUtils.isNotNull(item.getApprovalStatus())){
+                String approvalStatus = DictUtils.getDictLabel("transfer_approval_status", String.valueOf(item.getApprovalStatus()));
+                if(ObjectUtils.isNotEmpty(approvalStatus)){
+                    item.setApprovalStatusText(approvalStatus);
+                }
+            }
+
+            if(ObjectUtils.isNotNull(item.getOriginalUserId())){
+                CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(item.getOriginalUserId());
+                if(ObjectUtils.isNotNull(companyUser)){
+                    item.setOriginalUserName(String.format("%s_%d",companyUser.getUserName(),companyUser.getUserId()));
+                }
+            }
+
+            if(ObjectUtils.isNotNull(item.getTargetUserId())){
+                CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(item.getTargetUserId());
+                if(ObjectUtils.isNotNull(companyUser)){
+                    item.setTargetUserName(String.format("%s_%d", companyUser.getUserName(), companyUser.getUserId()));
+                }
+            }
+
+            if(ObjectUtils.isNotNull(item.getInitiatorUserId())){
+                CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(item.getInitiatorUserId());
+                if(ObjectUtils.isNotNull(companyUser)){
+                    item.setInitiatorUserName(String.format("%s_%d", companyUser.getUserName(), companyUser.getUserId()));
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * 新增客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    @Override
+    public int insertCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return baseMapper.insertCustomerTransferApprovalQw(customerTransferApprovalQw);
+    }
+
+    /**
+     * 修改客户转移审批-企微的
+     *
+     * @param customerTransferApprovalQw 客户转移审批-企微的
+     * @return 结果
+     */
+    @Override
+    public int updateCustomerTransferApprovalQw(CustomerTransferApprovalQw customerTransferApprovalQw)
+    {
+        return baseMapper.updateCustomerTransferApprovalQw(customerTransferApprovalQw);
+    }
+
+    /**
+     * 批量删除客户转移审批-企微的
+     *
+     * @param ids 需要删除的客户转移审批-企微的主键
+     * @return 结果
+     */
+    @Override
+    public int deleteCustomerTransferApprovalQwByIds(Long[] ids)
+    {
+        return baseMapper.deleteCustomerTransferApprovalQwByIds(ids);
+    }
+
+    /**
+     * 删除客户转移审批-企微的信息
+     *
+     * @param id 客户转移审批-企微的主键
+     * @return 结果
+     */
+    @Override
+    public int deleteCustomerTransferApprovalQwById(Long id)
+    {
+        return baseMapper.deleteCustomerTransferApprovalQwById(id);
+    }
+}

+ 45 - 0
fs-service/src/main/java/com/fs/qw/vo/FsUserCompanyUserQwVO.java

@@ -0,0 +1,45 @@
+package com.fs.qw.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class FsUserCompanyUserQwVO {
+
+
+    /** id */
+    private Long id;
+
+    /** 用户id(关联fs_user表user_id) */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    @Excel(name = "会员昵称")
+    private String nickname;
+
+    /** 销售名称 */
+    @Excel(name = "销售名称")
+    private String companyUserName;
+
+    /** 销售公司 */
+    @Excel(name = "销售公司")
+    private Long companyName;
+
+    /** 课程项目ID */
+    @Excel(name = "课程项目ID")
+    private Long projectId;
+
+    @Excel(name = "课程项目名称")
+    private String projectName;
+
+    @Excel(name = "备注")
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+}

+ 9 - 10
fs-service/src/main/resources/mapper/course/FsUserCompanyUserQwMapper.xml

@@ -3,7 +3,7 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.course.mapper.FsUserCompanyUserQwMapper">
-    
+
     <resultMap type="FsUserCompanyUserQw" id="FsUserCompanyUserQwResult">
         <result property="id"    column="id"    />
         <result property="userId"    column="user_id"    />
@@ -14,21 +14,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="qwUserId"    column="qw_user_id"    />
         <result property="qwExternalContactId"    column="qw_external_contact_id"    />
         <result property="qwCompanyId"    column="qw_company_id"    />
-        <result property="createBy"    column="create_by"    />
-        <result property="updateBy"    column="update_by"    />
         <result property="createTime"    column="create_time"    />
         <result property="status"    column="status"    />
         <result property="remark"    column="remark"    />
-        <result property="updateTime"    column="update_time"    />
+
     </resultMap>
 
     <sql id="selectFsUserCompanyUserQwVo">
-        select id, user_id, company_user_id, company_id, is_repeat_fans, project_id, qw_user_id, qw_external_contact_id, qw_company_id, create_by, update_by, create_time, status, remark, update_time from fs_user_company_user_qw
+        select id, user_id, company_user_id, company_id, is_repeat_fans, project_id, qw_user_id, qw_external_contact_id, qw_company_id, create_time, status, remark, update_time from fs_user_company_user_qw
     </sql>
 
     <select id="selectFsUserCompanyUserQwList" parameterType="FsUserCompanyUserQw" resultMap="FsUserCompanyUserQwResult">
         <include refid="selectFsUserCompanyUserQwVo"/>
-        <where>  
+        <where>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
             <if test="companyId != null "> and company_id = #{companyId}</if>
@@ -40,12 +38,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="status != null "> and status = #{status}</if>
         </where>
     </select>
-    
+
     <select id="selectFsUserCompanyUserQwById" parameterType="Long" resultMap="FsUserCompanyUserQwResult">
         <include refid="selectFsUserCompanyUserQwVo"/>
         where id = #{id}
     </select>
-        
+
+
     <insert id="insertFsUserCompanyUserQw" parameterType="FsUserCompanyUserQw" useGeneratedKeys="true" keyProperty="id">
         insert into fs_user_company_user_qw
         <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -108,9 +107,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </delete>
 
     <delete id="deleteFsUserCompanyUserQwByIds" parameterType="String">
-        delete from fs_user_company_user_qw where id in 
+        delete from fs_user_company_user_qw where id in
         <foreach item="id" collection="array" open="(" separator="," close=")">
             #{id}
         </foreach>
     </delete>
-</mapper>
+</mapper>

+ 126 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -382,6 +382,57 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         limit ${(pageNum-1)*pageSize},${pageSize}
     </select>
 
+    <select id="selectFsUserPageListNewQw" resultType="com.fs.store.vo.h5.FsUserPageListVO">
+        SELECT
+        fs_user.user_id,
+        fs_user.nick_name as nickname,
+        fs_user.avatar,
+        fs_user.phone,
+        fs_user.status,
+        fs_user.create_time,
+        fs_user.remark,
+        ucu.company_user_id,
+        ucu.company_id,
+        ucu.project_id
+        FROM
+        fs_user
+        left join fs_user_company_user_qw ucu on ucu.user_id = fs_user.user_id
+        <where>
+            fs_user.is_del = 0
+            <if test="userId != null">
+                AND fs_user.user_id = #{userId}
+            </if>
+            <if test="companyId != null">
+                AND ucu.company_id = #{companyId}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' ">
+                AND ucu.company_user_id = #{companyUserId}
+            </if>
+            <if test="registerStartTime != null and registerStartTime !='' ">
+                AND fs_user.create_time &gt;= #{registerStartTime}
+            </if>
+            <if test="registerEndTime != null and registerEndTime !='' ">
+                AND fs_user.create_time &lt;= #{registerEndTime}
+            </if>
+            <if test="companyUserIds != null and companyUserIds.size > 0">
+                AND ucu.company_user_id in
+                <foreach collection="companyUserIds" item="item" index="index" open="(" separator="," close=")">
+                    ${item}
+                </foreach>
+            </if>
+            <if test="nickname != null and nickname != ''">
+                AND fs_user.nick_name like concat('%', #{nickname},'%')
+            </if>
+            <if test="phone != null and phone != ''">
+                AND fs_user.phone like concat('%', #{phone},'%')
+            </if>
+            <if test="projectId != null">
+                AND ucu.project_id = #{projectId}
+            </if>
+        </where>
+        limit ${(pageNum-1)*pageSize},${pageSize}
+    </select>
+
     <select id="selectFsUserPageListCount" resultType="java.lang.Long">
         SELECT
         count(1)
@@ -1886,6 +1937,81 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY
         user_id DESC
     </select>
+
+    <select id="selectFsUserVOListByProjectByQw" resultType="com.fs.his.vo.FsUserVO">
+        SELECT distinct
+        b.total_amount,b.last_buy_time,p.pay_money as number,p.payment_id,p.pay_time,
+        u.user_id, u.nick_name, u.avatar, u.phone, u.integral, u.now_money,
+        fcc.watch_course_count, fcc.part_course_count, company_user.nick_name AS companyUserNickName, fcc.last_watch_date
+        ,company.company_name,
+        ucu.project_id,
+        ucu.id as companyUserId,
+        ucu.create_time as bindTime,
+        ucu.status
+        FROM
+        fs_user u
+        LEFT JOIN (
+        SELECT max( payment_id ) AS payment_id, max( pay_time ) AS last_buy_time, SUM( pay_money ) AS total_amount,
+        user_id
+        FROM
+        fs_store_payment
+        WHERE
+        STATUS = 1
+        AND user_id IS NOT NULL
+        GROUP BY
+        user_id
+        ) b ON u.user_id = b.user_id
+        LEFT JOIN fs_store_payment p ON u.user_id = p.user_id
+        AND b.last_buy_time = p.pay_time
+        AND b.payment_id = p.payment_id
+        LEFT JOIN (
+        SELECT
+        fs_user_course_count.user_id,Max( fs_user_course_count.last_watch_date ) AS last_watch_date,fs_user_course_count.watch_course_count,
+        fs_user_course_count.part_course_count
+        FROM
+        fs_user_course_count
+        GROUP BY fs_user_course_count.user_id
+        ) fcc ON fcc.user_id = u.user_id
+        inner join fs_user_company_user_qw ucu on ucu.user_id = u.user_id
+        LEFT JOIN company_user ON company_user.user_id = ucu.company_user_id
+        LEFT JOIN company on company.company_id = company_user.company_id
+        <where>
+            1 = 1 and u.nick_name is not null
+            and u.is_del = 0
+            <if test = "maps.nickname != null and  maps.nickname !='' " >
+                AND u.nick_name LIKE CONCAT("%",#{maps.nickname},"%")
+            </if >
+            <if test = "maps.userId != null and  maps.userId !='' " >
+                AND u.user_id = #{maps.userId}
+            </if >
+            <if test = "maps.phone != null   and  maps.phone !='' " >
+                AND u.phone LIKE CONCAT("%",#{maps.phone},"%")
+            </if >
+            <if test = "maps.startCreateTime != null and maps.endCreateTime != null" >
+                AND (DATE_FORMAT( ucu.create_time, "%Y-%m-%d" ) &gt;= DATE_FORMAT(#{maps.startCreateTime}, "%Y-%m-%d")
+                and DATE_FORMAT( ucu.create_time, "%Y-%m-%d" ) &lt;= DATE_FORMAT(#{maps.endCreateTime}, "%Y-%m-%d")
+                )
+            </if >
+            <if test = "maps.registerCode != null  and  maps.registerCode !=''  " >
+                AND u.register_code = #{maps.registerCode}
+            </if >
+            <if test = "maps.status != null" >
+                AND ucu.status = #{maps.status}
+            </if >
+            <if test = "maps.companyId != null and maps.companyId != '' " >
+                AND company.company_id = #{maps.companyId}
+            </if >
+            <if test = "maps.companyUserId != null" >
+                AND company_user.user_id = #{maps.companyUserId}
+            </if >
+            <if test = "maps.projectId != null" >
+                AND ucu.project_id = #{maps.projectId}
+            </if >
+        </where>
+        ORDER BY
+        user_id DESC
+    </select>
+
     <select id="selectCompanyAndDoctor" resultType="com.fs.watch.domain.vo.FsUserAndCompanyAndDoctorVo">
         SELECT
             f.*,

+ 121 - 0
fs-service/src/main/resources/mapper/qw/CustomerTransferApprovalQwMapper.xml

@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.qw.mapper.CustomerTransferApprovalQwMapper">
+
+    <resultMap type="CustomerTransferApprovalQw" id="CustomerTransferApprovalQwResult">
+        <result property="id"    column="id"    />
+        <result property="corpId"    column="corp_id"    />
+        <result property="transferType"    column="transfer_type"    />
+        <result property="customerIds"    column="customer_ids"    />
+        <result property="originalUserId"    column="original_user_id"    />
+        <result property="targetUserId"    column="target_user_id"    />
+        <result property="initiatorUserId"    column="initiator_user_id"    />
+        <result property="content"    column="content"    />
+        <result property="approvalStatus"    column="approval_status"    />
+        <result property="approverUserId"    column="approver_user_id"    />
+        <result property="approvalRemark"    column="approval_remark"    />
+        <result property="processedAt"    column="processed_at"    />
+        <result property="createdAt"    column="created_at"    />
+        <result property="updatedAt"    column="updated_at"    />
+        <result property="transferBefore"    column="transfer_before"    />
+    </resultMap>
+
+    <sql id="selectCustomerTransferApprovalQwVo">
+        select id, corp_id, transfer_type, customer_ids, original_user_id, target_user_id, initiator_user_id, content, approval_status, approver_user_id, approval_remark, processed_at, created_at, updated_at, transfer_before from customer_transfer_approval_qw
+    </sql>
+
+    <select id="selectCustomerTransferApprovalQwList" parameterType="CustomerTransferApprovalQw" resultMap="CustomerTransferApprovalQwResult">
+        <include refid="selectCustomerTransferApprovalQwVo"/>
+        <where>
+            <if test="corpId != null  and corpId != ''"> and corp_id = #{corpId}</if>
+            <if test="transferType != null "> and transfer_type = #{transferType}</if>
+            <if test="customerIds != null  and customerIds != ''"> and customer_ids = #{customerIds}</if>
+            <if test="originalUserId != null "> and original_user_id = #{originalUserId}</if>
+            <if test="targetUserId != null "> and target_user_id = #{targetUserId}</if>
+            <if test="initiatorUserId != null "> and initiator_user_id = #{initiatorUserId}</if>
+            <if test="content != null  and content != ''"> and content = #{content}</if>
+            <if test="approvalStatus != null "> and approval_status = #{approvalStatus}</if>
+            <if test="approverUserId != null "> and approver_user_id = #{approverUserId}</if>
+            <if test="approvalRemark != null  and approvalRemark != ''"> and approval_remark = #{approvalRemark}</if>
+            <if test="processedAt != null "> and processed_at = #{processedAt}</if>
+            <if test="createdAt != null "> and created_at = #{createdAt}</if>
+            <if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
+            <if test="transferBefore != null  and transferBefore != ''"> and transfer_before = #{transferBefore}</if>
+        </where>
+    </select>
+
+    <select id="selectCustomerTransferApprovalQwById" parameterType="Long" resultMap="CustomerTransferApprovalQwResult">
+        <include refid="selectCustomerTransferApprovalQwVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertCustomerTransferApprovalQw" parameterType="CustomerTransferApprovalQw" useGeneratedKeys="true" keyProperty="id">
+        insert into customer_transfer_approval_qw
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="corpId != null and corpId != ''">corp_id,</if>
+            <if test="transferType != null">transfer_type,</if>
+            <if test="customerIds != null and customerIds != ''">customer_ids,</if>
+            <if test="originalUserId != null">original_user_id,</if>
+            <if test="targetUserId != null">target_user_id,</if>
+            <if test="initiatorUserId != null">initiator_user_id,</if>
+            <if test="content != null">content,</if>
+            <if test="approvalStatus != null">approval_status,</if>
+            <if test="approverUserId != null">approver_user_id,</if>
+            <if test="approvalRemark != null">approval_remark,</if>
+            <if test="processedAt != null">processed_at,</if>
+            <if test="createdAt != null">created_at,</if>
+            <if test="updatedAt != null">updated_at,</if>
+            <if test="transferBefore != null">transfer_before,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="corpId != null and corpId != ''">#{corpId},</if>
+            <if test="transferType != null">#{transferType},</if>
+            <if test="customerIds != null and customerIds != ''">#{customerIds},</if>
+            <if test="originalUserId != null">#{originalUserId},</if>
+            <if test="targetUserId != null">#{targetUserId},</if>
+            <if test="initiatorUserId != null">#{initiatorUserId},</if>
+            <if test="content != null">#{content},</if>
+            <if test="approvalStatus != null">#{approvalStatus},</if>
+            <if test="approverUserId != null">#{approverUserId},</if>
+            <if test="approvalRemark != null">#{approvalRemark},</if>
+            <if test="processedAt != null">#{processedAt},</if>
+            <if test="createdAt != null">#{createdAt},</if>
+            <if test="updatedAt != null">#{updatedAt},</if>
+            <if test="transferBefore != null">#{transferBefore},</if>
+         </trim>
+    </insert>
+
+    <update id="updateCustomerTransferApprovalQw" parameterType="CustomerTransferApprovalQw">
+        update customer_transfer_approval_qw
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="corpId != null and corpId != ''">corp_id = #{corpId},</if>
+            <if test="transferType != null">transfer_type = #{transferType},</if>
+            <if test="customerIds != null and customerIds != ''">customer_ids = #{customerIds},</if>
+            <if test="originalUserId != null">original_user_id = #{originalUserId},</if>
+            <if test="targetUserId != null">target_user_id = #{targetUserId},</if>
+            <if test="initiatorUserId != null">initiator_user_id = #{initiatorUserId},</if>
+            <if test="content != null">content = #{content},</if>
+            <if test="approvalStatus != null">approval_status = #{approvalStatus},</if>
+            <if test="approverUserId != null">approver_user_id = #{approverUserId},</if>
+            <if test="approvalRemark != null">approval_remark = #{approvalRemark},</if>
+            <if test="processedAt != null">processed_at = #{processedAt},</if>
+            <if test="createdAt != null">created_at = #{createdAt},</if>
+            <if test="updatedAt != null">updated_at = #{updatedAt},</if>
+            <if test="transferBefore != null">transfer_before = #{transferBefore},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteCustomerTransferApprovalQwById" parameterType="Long">
+        delete from customer_transfer_approval_qw where id = #{id}
+    </delete>
+
+    <delete id="deleteCustomerTransferApprovalQwByIds" parameterType="String">
+        delete from customer_transfer_approval_qw where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>