From 6acd9f8a527fd8d9bdc9b901dea6c41f36e65974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Wed, 13 May 2026 11:34:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(appUser):=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E5=95=86=E6=8A=A5=E4=BB=B7=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E9=80=BB=E8=BE=91=E5=B9=B6=E6=94=AF=E6=8C=81Redis?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用Redis缓存报价代码索引,提升报价代码生成性能 - 替换原有序列号生成服务,改用Redis自增策略生成报价代码 - 在编辑客户时,新增根据配置自动生成所属代理商报价代码功能 - 添加初始化APP用户报价代码接口,支持批量生成报价代码 - 修正代码格式及部分逻辑细节,提高代码可读性和维护性 - 在CustomerController中增加事务管理及日志记录功能 --- .../admin/controller/CustomerController.java | 23 +++++++++ .../quotation/controller/TestController.java | 51 +++++++++++++++---- .../service/impl/AppUserServiceImpl.java | 29 +++++++---- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/CustomerController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/CustomerController.java index eb7d6966..c72718d9 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/CustomerController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/CustomerController.java @@ -31,6 +31,8 @@ import com.nflg.mobilebroken.repository.service.IAppUserService; import com.nflg.mobilebroken.repository.service.ITBaseAreaService; import com.nflg.mobilebroken.repository.service.ITBaseCustomerService; import com.nflg.mobilebroken.starter.annotation.MethodInfoMark; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.ttzero.excel.entity.ListSheet; @@ -40,6 +42,7 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Set; @@ -48,6 +51,7 @@ import java.util.stream.Collectors; /** * 客户管理 */ +@Slf4j @RestController @RequestMapping("/customer") public class CustomerController extends ControllerBase { @@ -120,6 +124,7 @@ public class CustomerController extends ControllerBase { * @param customerDTO * @return */ + @Transactional @PostMapping("updateCompany") @MethodInfoMark(value = "编辑", menuName = "客户管理") @ApiMark(moduleName = "客户管理", apiName = "编辑") @@ -135,6 +140,23 @@ public class CustomerController extends ControllerBase { //检查公司名称是否已存在 TBaseCustomer oldEnt = baseCustomerService.getById(customerDTO.getId()); VUtils.trueThrow(Objects.isNull(oldEnt)).throwMessage(STATE.PageError, customerDTO.getAgencyCompanyName() + "公司不存在"); + if (customerDTO.getQuotationUse() && !oldEnt.getQuotationUse()) { + //该公司对应的代理商需要生成报价代码 + List appUsers = appUserService.lambdaQuery() + .eq(AppUser::getType, 0) + .isNull(AppUser::getQuotationCode) + .apply("FIND_IN_SET({0}, companyId) > 0", customerDTO.getId()) + .orderByAsc(AppUser::getId) + .list(); + if (CollUtil.isNotEmpty(appUsers)) { + appUsers.forEach(appUser -> { + String quotationCode = appUserService.getAppUserQuotationCode(Arrays.stream(StrUtil.splitToInt(appUser.getCompanyId(), ",")).boxed().collect(Collectors.toList())); + log.info("生成报价代码【{}】:{}", appUser.getName(), quotationCode); + appUser.setQuotationCode(quotationCode); + }); + appUserService.updateBatchById(appUsers); + } + } BeanUtil.copyProperties(customerDTO, oldEnt); oldEnt.setAreaCode(StrUtil.join(",", customerDTO.getAreaList().stream().map(CustomerAreaDTO::getAreaCode).collect(Collectors.toList()))); oldEnt.setAreaName(StrUtil.join(",", customerDTO.getAreaList().stream().map(CustomerAreaDTO::getAreaName).collect(Collectors.toList()))); @@ -203,6 +225,7 @@ public class CustomerController extends ControllerBase { EecExcelUtil.setResponseExcelHeader(response, "客户列表"); final ListSheet listSheet = new ListSheet() { int i = 0; + @Override protected List more() { List list = baseCustomerService.list(); diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/TestController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/TestController.java index c9186d56..0136ad5f 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/TestController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/TestController.java @@ -5,10 +5,7 @@ import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.util.VUtils; -import com.nflg.mobilebroken.repository.entity.AdminUser; -import com.nflg.mobilebroken.repository.entity.ProductModel; -import com.nflg.mobilebroken.repository.entity.TBaseArea; -import com.nflg.mobilebroken.repository.entity.TBaseCustomer; +import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; @@ -18,9 +15,7 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.sql.Struct; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -47,6 +42,12 @@ public class TestController extends ControllerBase { @Resource private IAdminBaseSerialNumberService serialNumberService; + @Resource + private IAppUserService appUserService; + + @Resource + private ITBaseCustomerService customerService; + /** * 初始化机型表的BatchNumber字段数据 */ @@ -133,8 +134,8 @@ public class TestController extends ControllerBase { * 初始化内部用户报价代码字段数据 */ @PostMapping("initAdminUserQuotationCode") - public ApiResult initAdminUserQuotationCode(){ - List adminUsers=adminUserService.lambdaQuery() + public ApiResult initAdminUserQuotationCode() { + List adminUsers = adminUserService.lambdaQuery() .isNull(AdminUser::getQuotationCode) .orderByAsc(AdminUser::getId) .list(); @@ -150,4 +151,36 @@ public class TestController extends ControllerBase { return ApiResult.success(); } + /** + * 初始化APP用户报价代码字段数据 + */ + @PostMapping("initAppUserQuotationCode") + public ApiResult initAppUserQuotationCode() { + Set customers = customerService.getForQuotation() + .stream() + .map(TBaseCustomer::getId) + .collect(Collectors.toSet()); + List appUsers = appUserService.lambdaQuery() + .eq(AppUser::getType, 0) + .isNull(AppUser::getQuotationCode) + .orderByAsc(AppUser::getId) + .list(); + appUsers.removeIf(appUser -> customers.stream() + .noneMatch(customerId -> Arrays.stream(StrUtil.splitToInt(appUser.getCompanyId(), ",")) + .boxed() + .collect(Collectors.toList()) + .contains(customerId) + ) + ); + if (CollectionUtil.isNotEmpty(appUsers)) { + appUsers.forEach(appUser -> { + String quotationCode = appUserService.getAppUserQuotationCode(Arrays.stream(StrUtil.splitToInt(appUser.getCompanyId(), ",")).boxed().collect(Collectors.toList())); + log.info("生成报价代码【{}】:{}", appUser.getName(), quotationCode); + appUser.setQuotationCode(quotationCode); + }); + appUserService.updateBatchById(appUsers); + return ApiResult.success(); + } + return ApiResult.success(); + } } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java index 820e4eb6..9b7df596 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java @@ -19,6 +19,7 @@ import com.nflg.mobilebroken.common.util.VUtils; import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.mapper.AppUserMapper; import com.nflg.mobilebroken.repository.service.*; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -80,7 +81,7 @@ public class AppUserServiceImpl extends ServiceImpl impl private IDictionaryItemService dictionaryItemService; @Resource - private IAdminBaseSerialNumberService adminBaseSerialNumberService; + private RedisTemplate redisTemplate; @Override public String getAppUserQuotationCode(List companyId) { @@ -105,7 +106,7 @@ public class AppUserServiceImpl extends ServiceImpl impl .filter(StrUtil::isNotBlank) .collect(Collectors.toSet()); VUtils.trueThrowBusinessError(CollectionUtil.isEmpty(uniqueAreaCodes)).throwMessage("存在未维护区域信息的代理公司,请先维护区域信息"); - String specialCode = ""; + String specialCode = "A"; List areas = adminAreaService.lambdaQuery() .in(TBaseArea::getAreaCode, uniqueAreaCodes) .list(); @@ -117,7 +118,7 @@ public class AppUserServiceImpl extends ServiceImpl impl // 如果是只有一个公司或区域,就返回区域报价代码 if (areas.size() == 1) { VUtils.trueThrowBusinessError(StrUtil.isBlank(areas.get(0).getAreaQuoteCode())).throwMessage("区域报价代码没有维护,请先维护"); - specialCode = areas.get(0).getAreaQuoteCode(); + specialCode += areas.get(0).getAreaQuoteCode(); } // 如果存在多个公司或区域,需要查询上级 Set parentIds = areas.stream() @@ -130,7 +131,7 @@ public class AppUserServiceImpl extends ServiceImpl impl // 如果只有一个上级,就返回上级报价代码 if (parentAreas.size() == 1) { VUtils.trueThrowBusinessError(StrUtil.isBlank(parentAreas.get(0).getAreaQuoteCode())).throwMessage("区域报价代码没有维护,请先维护"); - specialCode = parentAreas.get(0).getAreaQuoteCode(); + specialCode += parentAreas.get(0).getAreaQuoteCode(); } else { // 多个上级,区别处理,合并相同上级的,单独列出一个上级的 Map parentCountMap = areas.stream() @@ -168,9 +169,19 @@ public class AppUserServiceImpl extends ServiceImpl impl specialCode += "-" + baseArea.getAreaQuoteCode(); } } - - String code = adminBaseSerialNumberService.generateSerialNumber(1, "", specialCode, false, 6); - return code; + String key = "quotation:appUser:quotationCode:" + specialCode; + Integer index = redisTemplate.opsForValue().get(key); + if (Objects.isNull(index)) { + AppUser lastUser = lambdaQuery() + .likeRight(AppUser::getQuotationCode, specialCode) + .orderByDesc(AppUser::getQuotationCode) + .last("limit 1") + .one(); + index = Objects.isNull(lastUser) ? 0 : Integer.parseInt(lastUser.getQuotationCode().replace(specialCode, "")); + } + index++; + redisTemplate.opsForValue().set(key, index); + return specialCode + String.format("%06d", index); } @@ -531,8 +542,8 @@ public class AppUserServiceImpl extends ServiceImpl impl @Override public List getEndUsers() { return lambdaQuery() - .eq(AppUser::getIsDel,0) - .eq(AppUser::getType,1) + .eq(AppUser::getIsDel, 0) + .eq(AppUser::getType, 1) .list(); }