Prechádzať zdrojové kódy

Merge branch 'refs/heads/master_feat_transfer'

# Conflicts:
#	fs-service-system/src/main/java/com/fs/store/domain/FsUser.java
#	fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
#	fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
#	fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
xdd 2 týždňov pred
rodič
commit
7c1a52a062
18 zmenil súbory, kde vykonal 1206 pridanie a 111 odobranie
  1. 104 0
      fs-admin/src/main/java/com/fs/transfer/CustomerTransferApprovalController.java
  2. 1 1
      fs-company-app/src/main/java/com/fs/app/exception/FSExceptionHandler.java
  3. 8 1
      fs-company/src/main/java/com/fs/core/exception/FSExceptionHandler.java
  4. 84 0
      fs-company/src/main/java/com/fs/users/controller/MyCompanyCustomerController.java
  5. 102 0
      fs-service-system/src/main/java/com/fs/qw/domain/CustomerTransferApproval.java
  6. 62 0
      fs-service-system/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalMapper.java
  7. 14 0
      fs-service-system/src/main/java/com/fs/qw/param/TransferParam.java
  8. 62 0
      fs-service-system/src/main/java/com/fs/qw/service/ICustomerTransferApprovalService.java
  9. 269 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalServiceImpl.java
  10. 30 0
      fs-service-system/src/main/java/com/fs/qw/vo/TransferCustomDTO.java
  11. 16 0
      fs-service-system/src/main/java/com/fs/store/domain/FsUser.java
  12. 31 0
      fs-service-system/src/main/java/com/fs/store/dto/FsUserTransferParamDTO.java
  13. 12 0
      fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
  14. 26 0
      fs-service-system/src/main/java/com/fs/store/param/SelectCusListPageParam.java
  15. 7 0
      fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
  16. 51 1
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  17. 121 0
      fs-service-system/src/main/resources/mapper/qw/CustomerTransferApprovalMapper.xml
  18. 206 108
      fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

+ 104 - 0
fs-admin/src/main/java/com/fs/transfer/CustomerTransferApprovalController.java

@@ -0,0 +1,104 @@
+package com.fs.transfer;
+
+import java.util.List;
+
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.service.ICustomerTransferApprovalService;
+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.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 客户转移审批Controller
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+@RestController
+@RequestMapping("/system/approval")
+public class CustomerTransferApprovalController extends BaseController
+{
+    @Autowired
+    private ICustomerTransferApprovalService customerTransferApprovalService;
+
+    /**
+     * 查询客户转移审批列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CustomerTransferApproval customerTransferApproval)
+    {
+        startPage();
+        List<CustomerTransferApproval> list = customerTransferApprovalService.selectCustomerTransferApprovalList(customerTransferApproval);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出客户转移审批列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:export')")
+    @Log(title = "客户转移审批", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(CustomerTransferApproval customerTransferApproval)
+    {
+        List<CustomerTransferApproval> list = customerTransferApprovalService.selectCustomerTransferApprovalList(customerTransferApproval);
+        ExcelUtil<CustomerTransferApproval> util = new ExcelUtil<CustomerTransferApproval>(CustomerTransferApproval.class);
+        return util.exportExcel(list, "approval");
+    }
+
+    /**
+     * 获取客户转移审批详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(customerTransferApprovalService.selectCustomerTransferApprovalById(id));
+    }
+
+    /**
+     * 新增客户转移审批
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:add')")
+    @Log(title = "客户转移审批", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CustomerTransferApproval customerTransferApproval)
+    {
+        return toAjax(customerTransferApprovalService.insertCustomerTransferApproval(customerTransferApproval));
+    }
+
+    /**
+     * 修改客户转移审批
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:edit')")
+    @Log(title = "客户转移审批", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CustomerTransferApproval customerTransferApproval)
+    {
+        return toAjax(customerTransferApprovalService.updateCustomerTransferApproval(customerTransferApproval));
+    }
+
+    /**
+     * 删除客户转移审批
+     */
+    @PreAuthorize("@ss.hasPermi('system:approval:remove')")
+    @Log(title = "客户转移审批", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(customerTransferApprovalService.deleteCustomerTransferApprovalByIds(ids));
+    }
+}

+ 1 - 1
fs-company-app/src/main/java/com/fs/app/exception/FSExceptionHandler.java

@@ -62,7 +62,7 @@ public class FSExceptionHandler {
 
 			return R.error(defaultMessage);
 		}else {
-			return R.error();
+			return R.error(e.getMessage());
 		}
 
 	}

+ 8 - 1
fs-company/src/main/java/com/fs/core/exception/FSExceptionHandler.java

@@ -21,6 +21,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.servlet.NoHandlerFoundException;
 
+import java.sql.SQLSyntaxErrorException;
+
 
 /**
  * 异常处理器
@@ -53,11 +55,16 @@ public class FSExceptionHandler {
 		return R.error("数据库中已存在该记录");
 	}
 
+	@ExceptionHandler(SQLSyntaxErrorException.class)
+	public R handleSQLSyntaxErrorException(SQLSyntaxErrorException e){
+		logger.error(e.getMessage(), e);
+		return R.error("SQL语法错误,请联系管理员!");
+	}
 
 	@ExceptionHandler(Exception.class)
 	public R handleException(Exception e){
 		logger.error(e.getMessage(), e);
-		return R.error();
+		return R.error(e.getMessage());
 	}
 
 

+ 84 - 0
fs-company/src/main/java/com/fs/users/controller/MyCompanyCustomerController.java

@@ -0,0 +1,84 @@
+package com.fs.users.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.utils.ServletUtils;
+import com.fs.core.security.LoginUser;
+import com.fs.core.web.service.TokenService;
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.service.ICustomerTransferApprovalService;
+import com.fs.store.dto.FsUserTransferParamDTO;
+import com.fs.store.param.SelectCusListPageParam;
+import com.fs.store.service.IFsUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+/**
+ * 客户转移审批Controller
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+@Slf4j
+@RestController
+@RequestMapping("/fsuser/user")
+public class MyCompanyCustomerController {
+
+    @Autowired
+    private ICustomerTransferApprovalService transferApprovalService;
+
+    @Autowired
+    private IFsUserService fsUserService;
+
+    @Autowired
+    private TokenService tokenService;
+
+
+    /**
+     * 列出当前公司的客户
+     * @param param 参数
+     * @return 返回数据
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(SelectCusListPageParam param){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+        return fsUserService.selectCusListPage(param);
+    }
+    /**
+     * 导出
+     */
+    @PostMapping("/export")
+    public void export(){
+
+    }
+    /**
+     * 转移
+     * @param param
+     */
+    @PostMapping("/transfer")
+    public R transfer(@RequestBody FsUserTransferParamDTO param){
+        log.info("客户转移: {}",param);
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setSourceCompanyUserId(loginUser.getUser().getUserId());
+        CustomerTransferApproval customerTransferApproval = new CustomerTransferApproval();
+        customerTransferApproval.setCorpId(String.valueOf(loginUser.getCompany().getCompanyId()));
+        customerTransferApproval.setCustomerIds(JSON.toJSONString(param.getUserIds()));
+        customerTransferApproval.setOriginalUserId(param.getSourceCompanyUserId());
+        customerTransferApproval.setTargetUserId(param.getTargetCompanyUserId());
+        customerTransferApproval.setInitiatorUserId(param.getSourceCompanyUserId());
+        customerTransferApproval.setContent(param.getContent());
+        customerTransferApproval.setCreatedAt(new Date());
+        customerTransferApproval.setUpdatedAt(new Date());
+        customerTransferApproval.setApprovalStatus(0);
+        customerTransferApproval.setTransferType(2);
+        transferApprovalService.insertCustomerTransferApproval(customerTransferApproval);
+        return R.ok("转移申请已经提交,等待总后台审核!");
+    }
+
+}

+ 102 - 0
fs-service-system/src/main/java/com/fs/qw/domain/CustomerTransferApproval.java

@@ -0,0 +1,102 @@
+package com.fs.qw.domain;
+
+import java.util.Date;
+import java.util.List;
+
+import cn.hutool.core.lang.Pair;
+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 org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 客户转移审批对象 customer_transfer_approval
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerTransferApproval 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;
+
+}

+ 62 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalMapper.java

@@ -0,0 +1,62 @@
+package com.fs.qw.mapper;
+
+import com.fs.qw.domain.CustomerTransferApproval;
+
+import java.util.List;
+
+/**
+ * 客户转移审批Mapper接口
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+public interface CustomerTransferApprovalMapper
+{
+    /**
+     * 查询客户转移审批
+     *
+     * @param id 客户转移审批ID
+     * @return 客户转移审批
+     */
+    public CustomerTransferApproval selectCustomerTransferApprovalById(Long id);
+
+    /**
+     * 查询客户转移审批列表
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 客户转移审批集合
+     */
+    public List<CustomerTransferApproval> selectCustomerTransferApprovalList(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 新增客户转移审批
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 结果
+     */
+    public int insertCustomerTransferApproval(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 修改客户转移审批
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 结果
+     */
+    public int updateCustomerTransferApproval(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 删除客户转移审批
+     *
+     * @param id 客户转移审批ID
+     * @return 结果
+     */
+    public int deleteCustomerTransferApprovalById(Long id);
+
+    /**
+     * 批量删除客户转移审批
+     *
+     * @param ids 需要删除的数据ID
+     * @return 结果
+     */
+    public int deleteCustomerTransferApprovalByIds(Long[] ids);
+}

+ 14 - 0
fs-service-system/src/main/java/com/fs/qw/param/TransferParam.java

@@ -6,8 +6,22 @@ import java.util.List;
 
 @Data
 public class TransferParam {
+
+    /**
+     * 客户id列表
+     */
     List<Long> ids;
+    /**
+     * 销售id
+     */
     Long  userId;
+
+    /**
+     * 企业id
+     */
     String corpId;
+    /**
+     * 转移提示内容
+     */
     String content;
 }

+ 62 - 0
fs-service-system/src/main/java/com/fs/qw/service/ICustomerTransferApprovalService.java

@@ -0,0 +1,62 @@
+package com.fs.qw.service;
+
+import com.fs.qw.domain.CustomerTransferApproval;
+
+import java.util.List;
+
+/**
+ * 客户转移审批Service接口
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+public interface ICustomerTransferApprovalService
+{
+    /**
+     * 查询客户转移审批
+     *
+     * @param id 客户转移审批ID
+     * @return 客户转移审批
+     */
+    public CustomerTransferApproval selectCustomerTransferApprovalById(Long id);
+
+    /**
+     * 查询客户转移审批列表
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 客户转移审批集合
+     */
+    public List<CustomerTransferApproval> selectCustomerTransferApprovalList(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 新增客户转移审批
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 结果
+     */
+    public int insertCustomerTransferApproval(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 修改客户转移审批
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 结果
+     */
+    public int updateCustomerTransferApproval(CustomerTransferApproval customerTransferApproval);
+
+    /**
+     * 批量删除客户转移审批
+     *
+     * @param ids 需要删除的客户转移审批ID
+     * @return 结果
+     */
+    public int deleteCustomerTransferApprovalByIds(Long[] ids);
+
+    /**
+     * 删除客户转移审批信息
+     *
+     * @param id 客户转移审批ID
+     * @return 结果
+     */
+    public int deleteCustomerTransferApprovalById(Long id);
+}

+ 269 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalServiceImpl.java

@@ -0,0 +1,269 @@
+package com.fs.qw.service.impl;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import cn.hutool.core.lang.Pair;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+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.mapper.CustomerTransferApprovalMapper;
+import com.fs.qw.service.ICustomerTransferApprovalService;
+import com.fs.qw.vo.TransferCustomDTO;
+import com.fs.store.domain.FsUser;
+import com.fs.store.dto.FsUserTransferParamDTO;
+import com.fs.store.service.IFsUserService;
+import com.fs.store.service.cache.IFsUserCacheService;
+import com.hc.openapi.tool.util.StringUtils;
+import org.apache.http.util.Asserts;
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 客户转移审批Service业务层处理
+ *
+ * @author fs
+ * @date 2025-04-01
+ */
+@Service
+@EnableAspectJAutoProxy(proxyTargetClass = true,exposeProxy = true)
+public class CustomerTransferApprovalServiceImpl implements ICustomerTransferApprovalService
+{
+    @Autowired
+    private CustomerTransferApprovalMapper customerTransferApprovalMapper;
+
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
+
+    @Autowired
+    private ICompanyCacheService companyCacheService;
+
+    @Autowired
+    private IFsUserCacheService fsUserCacheService;
+
+    @Autowired
+    private IFsUserService fsUserService;
+
+    /**
+     * 查询客户转移审批
+     *
+     * @param id 客户转移审批ID
+     * @return 客户转移审批
+     */
+    @Override
+    public synchronized CustomerTransferApproval selectCustomerTransferApprovalById(Long id)
+    {
+        CustomerTransferApproval item = customerTransferApprovalMapper.selectCustomerTransferApprovalById(id);
+
+        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()));
+            }
+        }
+
+        if(StringUtils.isBlank(item.getTransferBefore()) && StringUtils.isNotBlank(item.getCustomerIds())){
+            List<Long> customerIds = JSON.parseArray(item.getCustomerIds(), Long.class);
+            List<TransferCustomDTO> customerList = getCustomerList(customerIds, item);
+            item.setCustomerList(customerList);
+        } else {
+            List<TransferCustomDTO> customerList = JSON.parseArray(item.getTransferBefore(), TransferCustomDTO.class);
+            item.setCustomerList(customerList);
+        }
+        return item;
+    }
+
+    private List<TransferCustomDTO> getCustomerList(List<Long> customerIds, CustomerTransferApproval item) {
+        List<TransferCustomDTO> customerList = new ArrayList<>();
+
+        for (Long customerId : customerIds) {
+
+            FsUser fsUser = fsUserCacheService.selectFsUserById(customerId);
+            if(ObjectUtils.isNotNull(fsUser)){
+                String companyUserName = "无";
+                if(ObjectUtils.isNotNull(fsUser.getCompanyUserId())){
+                    CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(fsUser.getCompanyUserId());
+                    companyUserName = String.format("%s_%d", companyUser.getUserName(), companyUser.getUserId());
+                }
+
+                customerList.add(TransferCustomDTO.builder()
+                        .userName(String.format("%s_%d", fsUser.getNickname(), fsUser.getUserId()))
+                        .userId(fsUser.getUserId())
+                        .beforeCompanyUserName(companyUserName)
+                        .beforeCompanyUserId(fsUser.getCompanyUserId())
+                        .afterCompanyUserName(item.getTargetUserName())
+                        .afterCompanyUserId(item.getTargetUserId())
+                        .build());
+            }
+        }
+        return customerList;
+    }
+
+    /**
+     * 查询客户转移审批列表
+     *
+     * @param customerTransferApproval 客户转移审批
+     * @return 客户转移审批
+     */
+    @Override
+    public List<CustomerTransferApproval> selectCustomerTransferApprovalList(CustomerTransferApproval customerTransferApproval)
+    {
+        List<CustomerTransferApproval> list = customerTransferApprovalMapper.selectCustomerTransferApprovalList(customerTransferApproval);
+        for (CustomerTransferApproval 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 customerTransferApproval 客户转移审批
+     * @return 结果
+     */
+    @Override
+    public int insertCustomerTransferApproval(CustomerTransferApproval customerTransferApproval)
+    {
+        return customerTransferApprovalMapper.insertCustomerTransferApproval(customerTransferApproval);
+    }
+
+    /**
+     * 修改客户转移审批
+     *
+     * @param item 客户转移审批
+     * @return 结果
+     */
+    @Override
+    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
+    public int updateCustomerTransferApproval(CustomerTransferApproval item)
+    {
+        item.setProcessedAt(new Date());
+//        审批状态: 0=待审批, 1=审批通过, 2=审批驳回, 3=已撤销
+        // 如果审批通过 进行转移
+        if(ObjectUtil.equal(1,item.getApprovalStatus())){
+            FsUserTransferParamDTO transferParam = new FsUserTransferParamDTO();
+            transferParam.setContent(item.getContent());
+            transferParam.setTargetCompanyUserId(item.getTargetUserId());
+
+            Asserts.check(StringUtils.isNotBlank(item.getCustomerIds()),"转移客户不能为空!");
+            List<Long> customerIds = JSON.parseArray(item.getCustomerIds(), Long.class);
+            transferParam.setUserIds(customerIds);
+            transferParam.setSourceCompanyUserId(item.getOriginalUserId());
+
+            fsUserService.transfer(transferParam);
+        }
+        List<Long> customerIds = JSON.parseArray(item.getCustomerIds(), Long.class);
+        List<TransferCustomDTO> customerList = getCustomerList(customerIds, item);
+        item.setTransferBefore(JSON.toJSONString(customerList));
+        return customerTransferApprovalMapper.updateCustomerTransferApproval(item);
+    }
+
+    /**
+     * 批量删除客户转移审批
+     *
+     * @param ids 需要删除的客户转移审批ID
+     * @return 结果
+     */
+    @Override
+    public int deleteCustomerTransferApprovalByIds(Long[] ids)
+    {
+        return customerTransferApprovalMapper.deleteCustomerTransferApprovalByIds(ids);
+    }
+
+    /**
+     * 删除客户转移审批信息
+     *
+     * @param id 客户转移审批ID
+     * @return 结果
+     */
+    @Override
+    public int deleteCustomerTransferApprovalById(Long id)
+    {
+        return customerTransferApprovalMapper.deleteCustomerTransferApprovalById(id);
+    }
+}

+ 30 - 0
fs-service-system/src/main/java/com/fs/qw/vo/TransferCustomDTO.java

@@ -0,0 +1,30 @@
+package com.fs.qw.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TransferCustomDTO implements Serializable {
+    /**
+     * 用户名
+     */
+    private String userName;
+    private Long userId;
+    /**
+     * 转移前销售
+     */
+    private String beforeCompanyUserName;
+    private Long beforeCompanyUserId;
+    /**
+     * 转移后销售
+     */
+    private String afterCompanyUserName;
+    private Long afterCompanyUserId;
+}

+ 16 - 0
fs-service-system/src/main/java/com/fs/store/domain/FsUser.java

@@ -73,6 +73,7 @@ public class FsUser extends BaseEntity
     /** 1为正常,0为禁止 */
     @Excel(name = "状态:1为正常,0为禁止")
     private Integer status;
+    private String statusText;
 
     /** 等级 */
     private Integer level;
@@ -113,6 +114,7 @@ public class FsUser extends BaseEntity
     private Long companyId;
 
     private Long companyUserId;
+    private String companyUserName;
 
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "推线日期", width = 30, dateFormat = "yyyy-MM-dd")
@@ -146,7 +148,21 @@ public class FsUser extends BaseEntity
     public void setCourseMaOpenId(String courseMaOpenId) {
         this.courseMaOpenId = courseMaOpenId;
     }
+    public String getStatusText() {
+        return statusText;
+    }
+
+    public void setStatusText(String statusText) {
+        this.statusText = statusText;
+    }
 
+    public String getCompanyUserName() {
+        return companyUserName;
+    }
+
+    public void setCompanyUserName(String companyUserName) {
+        this.companyUserName = companyUserName;
+    }
     public Integer getIsAddQw() {
         return isAddQw;
     }

+ 31 - 0
fs-service-system/src/main/java/com/fs/store/dto/FsUserTransferParamDTO.java

@@ -0,0 +1,31 @@
+package com.fs.store.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 客户转移dto
+ */
+@Data
+public class FsUserTransferParamDTO implements Serializable {
+
+    /**
+     * 来源销售id
+     */
+    private Long sourceCompanyUserId;
+    /**
+     * 目标销售id
+     */
+    private Long targetCompanyUserId;
+    /**
+     * 客户id
+     */
+    private List<Long> userIds;
+
+    /**
+     * 转移提示内容/原因
+     */
+    private String content;
+}

+ 12 - 0
fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java

@@ -7,6 +7,8 @@ import com.fs.qw.vo.QwFsUserVO;
 import com.fs.qw.vo.newvo.ExternalContactNumVO;
 import com.fs.store.domain.FsStorePayment;
 import com.fs.store.domain.FsUser;
+import com.fs.store.dto.FsUserTransferParamDTO;
+import com.fs.store.param.SelectCusListPageParam;
 import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.vo.FSUserVO;
 
@@ -218,4 +220,14 @@ public interface FsUserMapper
     UserDetailsVO getCountRedPacket(@Param("userId") Long userId, @Param("fsUserId") Long fsUserId, @Param("dateTag") String dateTag);
 
     int batchUpdateFsUserByIds(@Param("ids") String[] ids, @Param("status") Integer status);
+
+    /**
+     * 分页获取客户
+     * @param param 参数
+     * @return 结果
+     */
+    List<FsUser> selectCusListPage(SelectCusListPageParam param);
+    Long selectCusListPageCount(SelectCusListPageParam param);
+
+    void transferCompanyUser(FsUserTransferParamDTO param);
 }

+ 26 - 0
fs-service-system/src/main/java/com/fs/store/param/SelectCusListPageParam.java

@@ -0,0 +1,26 @@
+package com.fs.store.param;
+
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SelectCusListPageParam extends BaseEntity {
+    /**
+     * 公司id
+     */
+    private Long companyId;
+    /**
+     * 销售id
+     */
+    private Long companyUserId;
+
+    /**
+     * 手机号码
+     */
+    private String phone;
+
+    private Long pageNum;
+    private Long pageSize;
+}

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

@@ -3,6 +3,7 @@ package com.fs.store.service;
 import java.util.List;
 
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.qw.vo.newvo.ExternalContactDetailsVO;
@@ -11,6 +12,8 @@ import com.fs.store.domain.FsStoreOrder;
 import com.fs.store.domain.FsStoreOrderItem;
 import com.fs.store.domain.FsUser;
 
+import com.fs.store.dto.FsUserTransferParamDTO;
+import com.fs.store.param.SelectCusListPageParam;
 import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
@@ -99,6 +102,8 @@ public interface IFsUserService
 
     FsUser selectFsUserByPhone(String phone);
 
+    TableDataInfo selectCusListPage(SelectCusListPageParam param);
+
     List<FsCompanyUserListQueryVO> selectFsCompanyUserListQuery(FsUser fsUser);
 
     List<FsUserTuiVO> selectFsUserTuiList(String userId);
@@ -139,4 +144,6 @@ public interface IFsUserService
 
     Boolean disabledUser(String[] ids, boolean status);
 
+    void transfer(FsUserTransferParamDTO param);
+
 }

+ 51 - 1
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -1,14 +1,19 @@
 package com.fs.store.service.impl;
 
 import java.math.BigDecimal;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.utils.DateUtils;
+import com.fs.company.cache.ICompanyUserCacheService;
+import com.fs.company.domain.CompanyUser;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.qw.vo.newvo.ExternalContactNumVO;
@@ -17,14 +22,18 @@ import com.fs.store.domain.FsStoreOrder;
 import com.fs.store.domain.FsStoreOrderItem;
 import com.fs.store.domain.FsUserBill;
 import com.fs.store.dto.FsStoreCartDTO;
+import com.fs.store.dto.FsUserTransferParamDTO;
 import com.fs.store.enums.BillDetailEnum;
 import com.fs.store.mapper.FsStoreOrderMapper;
 import com.fs.store.mapper.FsStoreProductAttrValueMapper;
 import com.fs.store.param.h5.FsUserPageListParam;
+import com.fs.store.param.SelectCusListPageParam;
 import com.fs.store.service.IFsUserBillService;
 import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.http.util.Asserts;
 import com.fs.store.vo.h5.FsUserPageListVO;
 import com.fs.store.vo.h5.UserDetailsVO;
 import com.fs.store.vo.h5.UserListCountVO;
@@ -35,6 +44,7 @@ import org.springframework.stereotype.Service;
 import com.fs.store.mapper.FsUserMapper;
 import com.fs.store.domain.FsUser;
 import com.fs.store.service.IFsUserService;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import static com.fs.store.enums.BillDetailEnum.CATEGORY_1;
@@ -59,6 +69,9 @@ public class FsUserServiceImpl implements IFsUserService
     private IFsUserBillService billService;
     @Autowired
     private FsStoreOrderMapper storeOrderMapper;
+
+    @Autowired
+    private ICompanyUserCacheService companyUserCacheService;
     /**
      * 查询用户
      *
@@ -160,6 +173,34 @@ public class FsUserServiceImpl implements IFsUserService
         return fsUserMapper.selectFsUserByPhone(phone);
     }
 
+    @Override
+    public TableDataInfo selectCusListPage(SelectCusListPageParam param) {
+        Asserts.check(ObjectUtils.isNotNull(param.getPageNum()), "页数不能为空");
+        Asserts.check(ObjectUtils.isNotNull(param.getPageSize()), "页大小不能为空");
+
+        List<FsUser> fsUsers = fsUserMapper.selectCusListPage(param);
+        for (FsUser fsUser : fsUsers) {
+            if(ObjectUtils.isNotNull(fsUser.getStatus())){
+                if(ObjectUtil.equal(0,fsUser.getStatus())){
+                    fsUser.setStatusText("禁止");
+                } else {
+                    fsUser.setStatusText("正常");
+                }
+            }
+            if(ObjectUtils.isNotNull(fsUser.getCompanyUserId())){
+                CompanyUser companyUser = companyUserCacheService.selectCompanyUserById(fsUser.getCompanyUserId());
+                if(ObjectUtils.isNotNull(companyUser)){
+                    fsUser.setCompanyUserName(String.format("%s_%d",companyUser.getUserName(),companyUser.getUserId()));
+                }
+            }
+        }
+        TableDataInfo tableDataInfo = new TableDataInfo();
+        tableDataInfo.setRows(fsUsers);
+        tableDataInfo.setTotal(fsUserMapper.selectCusListPageCount(param));
+        return tableDataInfo;
+    }
+
+
     @Override
     public List<FsCompanyUserListQueryVO> selectFsCompanyUserListQuery(FsUser fsUser) {
         return fsUserMapper.selectFsCompanyUserListQuery(fsUser);
@@ -406,4 +447,13 @@ public class FsUserServiceImpl implements IFsUserService
         }
         return result;
     }
+    @Override
+    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
+    public void transfer(FsUserTransferParamDTO param) {
+        Asserts.check(ObjectUtils.isNotNull(param.getSourceCompanyUserId()), "来源用户不能为空!");
+        Asserts.check(ObjectUtils.isNotNull(param.getTargetCompanyUserId()), "转移用户不能为空!");
+        Asserts.check(CollectionUtils.isNotEmpty(param.getUserIds()), "要转移的客户列表不能为空!");
+
+        fsUserMapper.transferCompanyUser(param);
+    }
 }

+ 121 - 0
fs-service-system/src/main/resources/mapper/qw/CustomerTransferApprovalMapper.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.CustomerTransferApprovalMapper">
+
+    <resultMap type="CustomerTransferApproval" id="CustomerTransferApprovalResult">
+        <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="selectCustomerTransferApprovalVo">
+        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
+    </sql>
+
+    <select id="selectCustomerTransferApprovalList" parameterType="CustomerTransferApproval" resultMap="CustomerTransferApprovalResult">
+        <include refid="selectCustomerTransferApprovalVo"/>
+        <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>
+        </where>
+    </select>
+
+    <select id="selectCustomerTransferApprovalById" parameterType="Long" resultMap="CustomerTransferApprovalResult">
+        <include refid="selectCustomerTransferApprovalVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertCustomerTransferApproval" parameterType="CustomerTransferApproval" useGeneratedKeys="true" keyProperty="id">
+        insert into customer_transfer_approval
+        <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="updateCustomerTransferApproval" parameterType="CustomerTransferApproval">
+        update customer_transfer_approval
+        <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="deleteCustomerTransferApprovalById" parameterType="Long">
+        delete from customer_transfer_approval where id = #{id}
+    </delete>
+
+    <delete id="deleteCustomerTransferApprovalByIds" parameterType="String">
+        delete from customer_transfer_approval where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>

+ 206 - 108
fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

@@ -1,86 +1,126 @@
 <?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">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.store.mapper.FsUserMapper">
     <resultMap type="FsUser" id="FsUserResult">
-        <result property="userId"    column="user_id"    />
-        <result property="username"    column="username"    />
-        <result property="password"    column="password"    />
-        <result property="realName"    column="real_name"    />
-        <result property="birthday"    column="birthday"    />
-        <result property="idCard"    column="id_card"    />
-        <result property="remark"    column="remark"    />
-        <result property="nickname"    column="nickname"    />
-        <result property="avatar"    column="avatar"    />
-        <result property="phone"    column="phone"    />
-        <result property="createTime"    column="create_time"    />
-        <result property="updateTime"    column="update_time"    />
-        <result property="lastIp"    column="last_ip"    />
-        <result property="nowMoney"    column="now_money"    />
-        <result property="brokeragePrice"    column="brokerage_price"    />
-        <result property="integral"    column="integral"    />
-        <result property="signNum"    column="sign_num"    />
-        <result property="status"    column="status"    />
-        <result property="level"    column="level"    />
-        <result property="spreadUserId"    column="spread_user_id"    />
-        <result property="spreadTime"    column="spread_time"    />
-        <result property="userType"    column="user_type"    />
-        <result property="isPromoter"    column="is_promoter"    />
-        <result property="payCount"    column="pay_count"    />
-        <result property="spreadCount"    column="spread_count"    />
-        <result property="addres"    column="addres"    />
-        <result property="maOpenId"    column="ma_open_id"    />
-        <result property="mpOpenId"    column="mp_open_id"    />
-        <result property="unionId"    column="union_id"    />
-        <result property="isDel"    column="is_del"    />
-        <result property="isWeixinAuth"    column="is_weixin_auth"    />
-        <result property="companyId"    column="company_id"    />
-        <result property="companyUserId"    column="company_user_id"    />
-        <result property="registerDate"    column="register_date"    />
-        <result property="registerCode"    column="register_code"    />
-        <result property="source"    column="source"    />
-        <result property="userCode"    column="user_code"    />
-        <result property="isShow"    column="is_show"    />
+        <result property="userId" column="user_id"/>
+        <result property="username" column="username"/>
+        <result property="password" column="password"/>
+        <result property="realName" column="real_name"/>
+        <result property="birthday" column="birthday"/>
+        <result property="idCard" column="id_card"/>
+        <result property="remark" column="remark"/>
+        <result property="nickname" column="nickname"/>
+        <result property="avatar" column="avatar"/>
+        <result property="phone" column="phone"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="lastIp" column="last_ip"/>
+        <result property="nowMoney" column="now_money"/>
+        <result property="brokeragePrice" column="brokerage_price"/>
+        <result property="integral" column="integral"/>
+        <result property="signNum" column="sign_num"/>
+        <result property="status" column="status"/>
+        <result property="level" column="level"/>
+        <result property="spreadUserId" column="spread_user_id"/>
+        <result property="spreadTime" column="spread_time"/>
+        <result property="userType" column="user_type"/>
+        <result property="isPromoter" column="is_promoter"/>
+        <result property="payCount" column="pay_count"/>
+        <result property="spreadCount" column="spread_count"/>
+        <result property="addres" column="addres"/>
+        <result property="maOpenId" column="ma_open_id"/>
+        <result property="mpOpenId" column="mp_open_id"/>
+        <result property="unionId" column="union_id"/>
+        <result property="isDel" column="is_del"/>
+        <result property="isWeixinAuth" column="is_weixin_auth"/>
+        <result property="companyId" column="company_id"/>
+        <result property="companyUserId" column="company_user_id"/>
+        <result property="registerDate" column="register_date"/>
+        <result property="registerCode" column="register_code"/>
+        <result property="source" column="source"/>
+        <result property="userCode" column="user_code"/>
+        <result property="isShow" column="is_show"/>
     </resultMap>
 
     <sql id="selectFsUserVo">
-        select user_id,is_show, username, password, real_name, birthday, id_card, remark, nickname, avatar, phone, create_time, update_time, last_ip, now_money, brokerage_price, integral, sign_num, status, level, spread_user_id, spread_time, user_type, is_promoter, pay_count, spread_count, addres,ma_open_id,mp_open_id,union_id, is_del,is_weixin_auth,company_id,company_user_id,register_date,register_code,source,user_code from fs_user
+        select user_id,
+               is_show,
+               username,
+               password,
+               real_name,
+               birthday,
+               id_card,
+               remark,
+               nickname,
+               avatar,
+               phone,
+               create_time,
+               update_time,
+               last_ip,
+               now_money,
+               brokerage_price,
+               integral,
+               sign_num,
+               status,
+               level,
+               spread_user_id,
+               spread_time,
+               user_type,
+               is_promoter,
+               pay_count,
+               spread_count,
+               addres,
+               ma_open_id,
+               mp_open_id,
+               union_id,
+               is_del,
+               is_weixin_auth,
+               company_id,
+               company_user_id,
+               register_date,
+               register_code,
+               source,
+               user_code
+        from fs_user
     </sql>
 
     <select id="selectFsUserList" parameterType="FsUser" resultMap="FsUserResult">
         <include refid="selectFsUserVo"/>
         <where>
-            <if test="username != null  and username != ''"> and username like concat('%', #{username}, '%')</if>
-            <if test="password != null  and password != ''"> and password = #{password}</if>
-            <if test="realName != null  and realName != ''"> and real_name like concat('%', #{realName}, '%')</if>
-            <if test="birthday != null "> and birthday = #{birthday}</if>
-            <if test="idCard != null  and idCard != ''"> and id_card = #{idCard}</if>
-            <if test="remark != null  and remark != ''"> and remark = #{remark}</if>
-            <if test="nickname != null  and nickname != ''"> and nickname like concat('%', #{nickname}, '%')</if>
-            <if test="avatar != null  and avatar != ''"> and avatar = #{avatar}</if>
-            <if test="phone != null  and phone != ''"> and phone = #{phone}</if>
-            <if test="lastIp != null  and lastIp != ''"> and last_ip = #{lastIp}</if>
-            <if test="nowMoney != null "> and now_money = #{nowMoney}</if>
-            <if test="brokeragePrice != null "> and brokerage_price = #{brokeragePrice}</if>
-            <if test="integral != null "> and integral = #{integral}</if>
-            <if test="signNum != null "> and sign_num = #{signNum}</if>
-            <if test="status != null "> and status = #{status}</if>
-            <if test="level != null "> and level = #{level}</if>
-            <if test="spreadUserId != null "> and spread_user_id = #{spreadUserId}</if>
-            <if test="spreadTime != null "> and spread_time = #{spreadTime}</if>
-            <if test="userType != null  and userType != ''"> and user_type = #{userType}</if>
-            <if test="isPromoter != null "> and is_promoter = #{isPromoter}</if>
-            <if test="payCount != null "> and pay_count = #{payCount}</if>
-            <if test="spreadCount != null "> and spread_count = #{spreadCount}</if>
-            <if test="addres != null  and addres != ''"> and addres = #{addres}</if>
-            <if test="isDel != null "> and is_del = #{isDel}</if>
-            <if test="companyId != null "> and company_id = #{companyId}</if>
-            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
-            <if test="registerDate != null "> and DATE_FORMAT(register_date,'%Y-%m-%d') = DATE_FORMAT(#{registerDate},'%Y-%m-%d')</if>
-            <if test="registerCode != null   and registerCode != '' "> and register_code = #{registerCode}</if>
-            <if test="source != null  and source != '' "> and source = #{source}</if>
-            <if test="isShow != null  "> and is_show = #{isShow}</if>
+            <if test="username != null  and username != ''">and username like concat('%', #{username}, '%')</if>
+            <if test="password != null  and password != ''">and password = #{password}</if>
+            <if test="realName != null  and realName != ''">and real_name like concat('%', #{realName}, '%')</if>
+            <if test="birthday != null ">and birthday = #{birthday}</if>
+            <if test="idCard != null  and idCard != ''">and id_card = #{idCard}</if>
+            <if test="remark != null  and remark != ''">and remark = #{remark}</if>
+            <if test="nickname != null  and nickname != ''">and nickname like concat('%', #{nickname}, '%')</if>
+            <if test="avatar != null  and avatar != ''">and avatar = #{avatar}</if>
+            <if test="phone != null  and phone != ''">and phone = #{phone}</if>
+            <if test="lastIp != null  and lastIp != ''">and last_ip = #{lastIp}</if>
+            <if test="nowMoney != null ">and now_money = #{nowMoney}</if>
+            <if test="brokeragePrice != null ">and brokerage_price = #{brokeragePrice}</if>
+            <if test="integral != null ">and integral = #{integral}</if>
+            <if test="signNum != null ">and sign_num = #{signNum}</if>
+            <if test="status != null ">and status = #{status}</if>
+            <if test="level != null ">and level = #{level}</if>
+            <if test="spreadUserId != null ">and spread_user_id = #{spreadUserId}</if>
+            <if test="spreadTime != null ">and spread_time = #{spreadTime}</if>
+            <if test="userType != null  and userType != ''">and user_type = #{userType}</if>
+            <if test="isPromoter != null ">and is_promoter = #{isPromoter}</if>
+            <if test="payCount != null ">and pay_count = #{payCount}</if>
+            <if test="spreadCount != null ">and spread_count = #{spreadCount}</if>
+            <if test="addres != null  and addres != ''">and addres = #{addres}</if>
+            <if test="isDel != null ">and is_del = #{isDel}</if>
+            <if test="companyId != null ">and company_id = #{companyId}</if>
+            <if test="companyUserId != null ">and company_user_id = #{companyUserId}</if>
+            <if test="registerDate != null ">and DATE_FORMAT(register_date,'%Y-%m-%d') =
+                DATE_FORMAT(#{registerDate},'%Y-%m-%d')
+            </if>
+            <if test="registerCode != null   and registerCode != '' ">and register_code = #{registerCode}</if>
+            <if test="source != null  and source != '' ">and source = #{source}</if>
+            <if test="isShow != null  ">and is_show = #{isShow}</if>
         </where>
         order by user_id desc
     </select>
@@ -92,44 +132,91 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectFsUserListLimit" resultType="com.fs.store.domain.FsUser">
         <include refid="selectFsUserVo"/>
         <where>
-            <if test="password != null  and password != ''"> and password = #{password}</if>
-            <if test="realName != null  and realName != ''"> and real_name like concat('%', #{realName}, '%')</if>
-            <if test="birthday != null "> and birthday = #{birthday}</if>
-            <if test="idCard != null  and idCard != ''"> and id_card = #{idCard}</if>
-            <if test="remark != null  and remark != ''"> and remark = #{remark}</if>
-            <if test="avatar != null  and avatar != ''"> and avatar = #{avatar}</if>
-            <if test="lastIp != null  and lastIp != ''"> and last_ip = #{lastIp}</if>
-            <if test="nowMoney != null "> and now_money = #{nowMoney}</if>
-            <if test="brokeragePrice != null "> and brokerage_price = #{brokeragePrice}</if>
-            <if test="integral != null "> and integral = #{integral}</if>
-            <if test="signNum != null "> and sign_num = #{signNum}</if>
-            <if test="status != null "> and status = #{status}</if>
-            <if test="level != null "> and level = #{level}</if>
-            <if test="spreadUserId != null "> and spread_user_id = #{spreadUserId}</if>
-            <if test="spreadTime != null "> and spread_time = #{spreadTime}</if>
-            <if test="userType != null  and userType != ''"> and user_type = #{userType}</if>
-            <if test="isPromoter != null "> and is_promoter = #{isPromoter}</if>
-            <if test="payCount != null "> and pay_count = #{payCount}</if>
-            <if test="spreadCount != null "> and spread_count = #{spreadCount}</if>
-            <if test="addres != null  and addres != ''"> and addres = #{addres}</if>
-            <if test="isDel != null "> and is_del = #{isDel}</if>
-            <if test="companyId != null "> and company_id = #{companyId}</if>
-            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
-            <if test="registerDate != null "> and DATE_FORMAT(register_date,'%Y-%m-%d') = DATE_FORMAT(#{registerDate},'%Y-%m-%d')</if>
-            <if test="registerCode != null   and registerCode != '' "> and register_code = #{registerCode}</if>
-            <if test="source != null  and source != '' "> and source = #{source}</if>
-            <if test="isShow != null  "> and is_show = #{isShow}</if>
-             <if test="(username != null  and username != '') or (nickname != null  and nickname != '') or (phone != null  and phone != '')">
-                 and (
-                 <if test="username != null  and username != ''"> username like concat('%', #{username}, '%')</if>
-                 <if test="nickname != null  and nickname != ''"> or nickname like concat('%', #{nickname}, '%')</if>
-                 <if test="phone != null  and phone != ''"> or phone like concat('%',#{phone},'%')</if>
-                 )
-             </if>
+            <if test="password != null  and password != ''">and password = #{password}</if>
+            <if test="realName != null  and realName != ''">and real_name like concat('%', #{realName}, '%')</if>
+            <if test="birthday != null ">and birthday = #{birthday}</if>
+            <if test="idCard != null  and idCard != ''">and id_card = #{idCard}</if>
+            <if test="remark != null  and remark != ''">and remark = #{remark}</if>
+            <if test="avatar != null  and avatar != ''">and avatar = #{avatar}</if>
+            <if test="lastIp != null  and lastIp != ''">and last_ip = #{lastIp}</if>
+            <if test="nowMoney != null ">and now_money = #{nowMoney}</if>
+            <if test="brokeragePrice != null ">and brokerage_price = #{brokeragePrice}</if>
+            <if test="integral != null ">and integral = #{integral}</if>
+            <if test="signNum != null ">and sign_num = #{signNum}</if>
+            <if test="status != null ">and status = #{status}</if>
+            <if test="level != null ">and level = #{level}</if>
+            <if test="spreadUserId != null ">and spread_user_id = #{spreadUserId}</if>
+            <if test="spreadTime != null ">and spread_time = #{spreadTime}</if>
+            <if test="userType != null  and userType != ''">and user_type = #{userType}</if>
+            <if test="isPromoter != null ">and is_promoter = #{isPromoter}</if>
+            <if test="payCount != null ">and pay_count = #{payCount}</if>
+            <if test="spreadCount != null ">and spread_count = #{spreadCount}</if>
+            <if test="addres != null  and addres != ''">and addres = #{addres}</if>
+            <if test="isDel != null ">and is_del = #{isDel}</if>
+            <if test="companyId != null ">and company_id = #{companyId}</if>
+            <if test="companyUserId != null ">and company_user_id = #{companyUserId}</if>
+            <if test="registerDate != null ">and DATE_FORMAT(register_date,'%Y-%m-%d') =
+                DATE_FORMAT(#{registerDate},'%Y-%m-%d')
+            </if>
+            <if test="registerCode != null   and registerCode != '' ">and register_code = #{registerCode}</if>
+            <if test="source != null  and source != '' ">and source = #{source}</if>
+            <if test="isShow != null  ">and is_show = #{isShow}</if>
+            <if test="(username != null  and username != '') or (nickname != null  and nickname != '') or (phone != null  and phone != '')">
+                and (
+                <if test="username != null  and username != ''">username like concat('%', #{username}, '%')</if>
+                <if test="nickname != null  and nickname != ''">or nickname like concat('%', #{nickname}, '%')</if>
+                <if test="phone != null  and phone != ''">or phone like concat('%',#{phone},'%')</if>
+                )
+            </if>
         </where>
         order by user_id desc
         limit 10
     </select>
+    <select id="selectCusListPage" resultType="com.fs.store.domain.FsUser">
+        select user.user_id,
+        user.username,
+        user.real_name,
+        user.id_card,
+        user.phone,
+        user.addres,
+        user.nickname,
+        user.status,
+        user.company_id,
+        user.company_user_id,
+        user.create_time
+        from
+        fs_user `user` join (
+        select user_id from fs_user
+        <where>
+            <if test="companyId != null and companyId != ''">
+                AND company_id = #{companyId}
+            </if>
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user_id = #{companyUserId}
+            </if>
+            <if test="phone != null and phone != ''">
+                AND phone = #{phone}
+            </if>
+        </where>
+        order by user_id desc
+        limit ${(pageNum-1)*pageSize},${pageSize}
+        ) t on t.user_id = `user`.user_id
+    </select>
+    <select id="selectCusListPageCount" resultType="java.lang.Long">
+        SELECT COUNT(user_id)
+        FROM fs_user
+        <where>
+            <if test="companyId != null and companyId != ''">
+                AND company_id = #{companyId}
+            </if>
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user_id = #{companyUserId}
+            </if>
+            <if test="phone != null and phone != ''">
+                AND phone = #{phone}
+            </if>
+        </where>
+    </select>
 
     <insert id="insertFsUser" parameterType="FsUser" useGeneratedKeys="true" keyProperty="userId">
         insert into fs_user
@@ -171,7 +258,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="source != null">source,</if>
             <if test="userCode != null">user_code,</if>
             <if test="isShow != null">is_show,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="username != null">#{username},</if>
             <if test="password != null">#{password},</if>
@@ -210,7 +297,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="source != null">#{source},</if>
             <if test="userCode != null">#{userCode},</if>
             <if test="isShow != null">#{isShow},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateFsUser" parameterType="FsUser">
@@ -256,9 +343,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </trim>
         where user_id = #{userId}
     </update>
+    <update id="transferCompanyUser">
+        update fs_user
+        set company_user_id=#{targetCompanyUserId}
+        where
+            user_id in
+        <foreach collection="userIds" open="(" close=")" separator="," item="item">
+            ${item}
+        </foreach>
+    </update>
 
     <delete id="deleteFsUserById" parameterType="Long">
-        delete from fs_user where user_id = #{userId}
+        delete
+        from fs_user
+        where user_id = #{userId}
     </delete>
 
     <delete id="deleteFsUserByIds" parameterType="String">