From 8ad99e5f72085d14fd56e8faa7aa36701823c8b5 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期四, 05 十一月 2026 20:16:23 +0800
Subject: [PATCH] feat(crm): 统一客户团队数据权限并放开开票金额上限

---
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 114 insertions(+), 0 deletions(-)

diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
index 0aaa4ec..4cb7956 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -3,9 +3,15 @@
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessImportExcelVO;
+import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessImportReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessImportRespVO;
 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
@@ -17,8 +23,10 @@
 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
+import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper;
+import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
@@ -43,14 +51,17 @@
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
 
@@ -67,6 +78,8 @@
     private CrmBusinessMapper businessMapper;
     @Resource
     private CrmBusinessProductMapper businessProductMapper;
+    @Resource
+    private CrmCustomerMapper customerMapper;
 
     @Resource
     private CrmBusinessStatusService businessStatusService;
@@ -113,6 +126,9 @@
         permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(business.getOwnerUserId())
                 .setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setBizId(business.getId())
                 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
+        // 3.1 瀹㈡埛璐熻矗浜鸿嚜鍔ㄦ嫢鏈夎鍟嗘満鐨勮鍐欐潈闄�
+        permissionService.createPermissionForCustomerOwner(CrmBizTypeEnum.CRM_BUSINESS.getType(),
+                business.getId(), business.getCustomerId(), business.getOwnerUserId());
 
         // 4. 鍦ㄨ仈绯讳汉鐨勮鎯呴〉锛屽鏋滅洿鎺ャ�愭柊寤哄晢鏈恒�戯紝鍒欓渶瑕佸叧鑱斾笅
         if (createReqVO.getContactId() != null) {
@@ -257,6 +273,9 @@
                 if (product.getItemUnitId() == null) {
                     product.setItemUnitId(old.getItemUnitId());
                 }
+            } else {
+                // 鏂颁骇鍝侊細娓呴櫎鍓嶇鐢熸垚鐨勪复鏃� ID锛岃鏁版嵁搴� AUTO_INCREMENT 鎺ョ
+                product.setId(null);
             }
             // 浼樺厛浣跨敤鍓嶇浼犲叆鐨� totalPrice锛屽惁鍒欓�氳繃 businessPrice * count 璁$畻
             if (o.getTotalPrice() != null) {
@@ -462,4 +481,99 @@
         return businessMapper.selectPage(pageVO);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public CrmBusinessImportRespVO importBusinessList(List<CrmBusinessImportExcelVO> importBusinesses,
+                                                      CrmBusinessImportReqVO importReqVO) {
+        // 1. 鏍¢獙闈炵┖
+        importBusinesses = filterList(importBusinesses, item -> StrUtil.isNotBlank(item.getName()));
+        if (CollUtil.isEmpty(importBusinesses)) {
+            throw exception(BUSINESS_IMPORT_LIST_IS_EMPTY);
+        }
+        // 2. 鏍¢獙璐熻矗浜猴紙涓虹┖鍒欓粯璁ゅ綋鍓嶆搷浣滀汉锛�
+        Long ownerUserId = importReqVO.getOwnerUserId() != null ? importReqVO.getOwnerUserId() : getLoginUserId();
+        adminUserApi.validateUser(ownerUserId);
+        // 3. 榛樿鍟嗘満鐘舵�佺粍 + 鐘舵��
+        Long defaultStatusTypeId = businessStatusService.getBusinessStatusTypeList().get(0).getId();
+        Long defaultStatusId = businessStatusService.getBusinessStatusListByTypeId(defaultStatusTypeId).get(0).getId();
+
+        // 4. 閫愭潯澶勭悊
+        CrmBusinessImportRespVO respVO = CrmBusinessImportRespVO.builder()
+                .createBusinessNames(new ArrayList<>())
+                .updateBusinessNames(new ArrayList<>())
+                .failureBusinessNames(new LinkedHashMap<>())
+                .build();
+        importBusinesses.forEach(importBusiness -> {
+            try {
+                // 4.1 瑙f瀽瀹㈡埛
+                CrmCustomerDO customer = customerMapper.selectByCustomerName(importBusiness.getCustomerName());
+                if (customer == null) {
+                    throw exception(BUSINESS_IMPORT_CUSTOMER_NOT_EXISTS, importBusiness.getCustomerName());
+                }
+                // 4.2 鍒ゆ柇鏄惁瀛樺湪
+                CrmBusinessDO existBusiness = businessMapper.selectByNameAndCustomerId(
+                        importBusiness.getName(), customer.getId());
+                if (existBusiness == null) {
+                    // 4.2.1 鏂板
+                    CrmBusinessDO business = BeanUtils.toBean(importBusiness, CrmBusinessDO.class)
+                            .setCustomerId(customer.getId()).setOwnerUserId(ownerUserId)
+                            .setStatusTypeId(defaultStatusTypeId).setStatusId(defaultStatusId);
+                    if (business.getDiscountPercent() == null) {
+                        business.setDiscountPercent(BigDecimal.ZERO);
+                    }
+                    calculateTotalPrice(business, Collections.emptyList());
+                    businessMapper.insert(business);
+                    // 鍒涘缓鏁版嵁鏉冮檺
+                    permissionService.createPermission(new CrmPermissionCreateReqBO()
+                            .setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setBizId(business.getId())
+                            .setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
+                    // 瀹㈡埛璐熻矗浜鸿嚜鍔ㄦ嫢鏈夎鍟嗘満鐨勮鍐欐潈闄�
+                    permissionService.createPermissionForCustomerOwner(CrmBizTypeEnum.CRM_BUSINESS.getType(),
+                            business.getId(), customer.getId(), ownerUserId);
+                    respVO.getCreateBusinessNames().add(importBusiness.getName());
+                    // 璁板綍鎿嶄綔鏃ュ織
+                    getSelf().importBusinessLog(business, false);
+                    return;
+                }
+                // 4.2.2 宸插瓨鍦紝鍒ゆ柇鏄惁鍏佽鏇存柊
+                if (!importReqVO.getUpdateSupport()) {
+                    respVO.getFailureBusinessNames().put(importBusiness.getName(),
+                            StrUtil.format(BUSINESS_NAME_EXISTS.getMsg(), importBusiness.getName()));
+                    return;
+                }
+                CrmBusinessDO updateBusiness = BeanUtils.toBean(importBusiness, CrmBusinessDO.class)
+                        .setId(existBusiness.getId()).setCustomerId(customer.getId());
+                businessMapper.updateById(updateBusiness);
+                respVO.getUpdateBusinessNames().add(importBusiness.getName());
+                // 璁板綍鎿嶄綔鏃ュ織
+                getSelf().importBusinessLog(updateBusiness, true);
+            } catch (ServiceException ex) {
+                respVO.getFailureBusinessNames().put(importBusiness.getName(), ex.getMessage());
+            }
+        });
+        return respVO;
+    }
+
+    /**
+     * 璁板綍瀵煎叆鍟嗘満鏃剁殑鎿嶄綔鏃ュ織
+     *
+     * @param business 鍟嗘満淇℃伅
+     * @param isUpdate 鏄惁鏇存柊锛泃rue - 鏇存柊锛宖alse - 鏂板
+     */
+    @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_IMPORT_SUB_TYPE, bizNo = "{{#business.id}}",
+            success = CRM_BUSINESS_IMPORT_SUCCESS)
+    public void importBusinessLog(CrmBusinessDO business, boolean isUpdate) {
+        LogRecordContext.putVariable("business", business);
+        LogRecordContext.putVariable("isUpdate", isUpdate);
+    }
+
+    /**
+     * 鑾峰緱鑷韩鐨勪唬鐞嗗璞★紝瑙e喅 AOP 鐢熸晥闂
+     *
+     * @return 鑷繁
+     */
+    private CrmBusinessServiceImpl getSelf() {
+        return SpringUtil.getBean(getClass());
+    }
+
 }

--
Gitblit v1.9.3