From d22b1900839f12ef45c136fb2d8b0b3f85e7bd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Mon, 2 Mar 2026 15:40:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(quotation):=20=E6=B7=BB=E5=8A=A0=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=A1=A8=E6=A0=BC=E5=8A=9F=E8=83=BD=E5=92=8C=E7=9B=B4?= =?UTF-8?q?=E9=94=80=E7=B3=BB=E6=95=B0=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 DynamicTableVO 类用于动态表格数据传输 - 在 IQuotationModelRatioDirectItemService 中添加 getEffectiveByUser 方法 - 更新 QuotationModelPriceMapper.xml 查询字段 - 在 QuotationModelRatioDirectItemMapper 中添加 getEffectiveByUser 方法 - 实现 QuotationModelRatioDirectItemMapper.xml 的 getEffectiveByUser 查询 - 完成 QuotationModelRatioDirectItemServiceImpl 的 getEffectiveByUser 实现 - 新增 QuotationModelRatioVO 类用于报价模型系数视图 - 修改 RatioAgentController 使用转换器返回 QuotationModelRatioVO - 更新 RatioAgentSearchVO 的 info 字段类型为 QuotationModelRatioVO - 在 RatioDirectController 中添加动态表头、搜索和数据获取接口 - 修改 RatioDirectEffectiveDTO 的 modelId 类型为 Long - 新增 UserModelPriceDTO 类用于用户机型价格数据传输 --- .../pojo/dto/RatioDirectEffectiveDTO.java | 2 +- .../common/pojo/dto/UserModelPriceDTO.java | 17 ++ .../common/pojo/vo/DynamicTableVO.java | 15 ++ .../admin/RatioAgentController.java | 4 +- .../admin/RatioDirectController.java | 241 ++++++++++++++---- .../pojo/vo/QuotationModelRatioVO.java | 29 +++ .../quotation/pojo/vo/RatioAgentSearchVO.java | 2 +- .../QuotationModelRatioDirectItemMapper.java | 3 + ...IQuotationModelRatioDirectItemService.java | 3 + ...tationModelRatioDirectItemServiceImpl.java | 6 + .../mapper/QuotationModelPriceMapper.xml | 2 +- .../QuotationModelRatioDirectItemMapper.xml | 6 + 12 files changed, 279 insertions(+), 51 deletions(-) create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/UserModelPriceDTO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DynamicTableVO.java create mode 100644 nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/QuotationModelRatioVO.java diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/RatioDirectEffectiveDTO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/RatioDirectEffectiveDTO.java index 3926cf69..2a1146db 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/RatioDirectEffectiveDTO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/RatioDirectEffectiveDTO.java @@ -10,7 +10,7 @@ public class RatioDirectEffectiveDTO { /** * 机型id */ - private Integer modelId; + private Long modelId; /** * 用户id diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/UserModelPriceDTO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/UserModelPriceDTO.java new file mode 100644 index 00000000..663fef42 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/UserModelPriceDTO.java @@ -0,0 +1,17 @@ +package com.nflg.mobilebroken.common.pojo.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; + +@Data +@Accessors(chain = true) +public class UserModelPriceDTO { + + private Integer userId; + + private Long modelId; + + private BigDecimal price; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DynamicTableVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DynamicTableVO.java new file mode 100644 index 00000000..e110f6b4 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DynamicTableVO.java @@ -0,0 +1,15 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Data +public class DynamicTableVO { + + private List headers=new ArrayList<>(); + + private List> datas=new ArrayList<>(); +} diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioAgentController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioAgentController.java index 7108a21c..f4f8d57e 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioAgentController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioAgentController.java @@ -1,6 +1,7 @@ package com.nflg.mobilebroken.quotation.controller.admin; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -13,6 +14,7 @@ import com.nflg.mobilebroken.common.pojo.vo.ModelPriceVO; import com.nflg.mobilebroken.common.pojo.vo.ProductModelSimpleVO; import com.nflg.mobilebroken.common.util.*; import com.nflg.mobilebroken.quotation.controller.ControllerBase; +import com.nflg.mobilebroken.quotation.pojo.vo.QuotationModelRatioVO; import com.nflg.mobilebroken.quotation.pojo.vo.RatioAgentSearchVO; import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; @@ -124,7 +126,7 @@ public class RatioAgentController extends ControllerBase { QuotationModelRatioAgent ratioAgent = ratioAgentService.lambdaQuery() .eq(QuotationModelRatioAgent::getStatus, 1) .one(); - vo.setInfo(ratioAgent); + vo.setInfo(Convert.convert(QuotationModelRatioVO.class,ratioAgent)); IPage pdatas = ratioAgentService.search(request); if (CollectionUtil.isEmpty(pdatas.getRecords())) { vo.setPageData(PageData.empty()); diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioDirectController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioDirectController.java index 09ba9b77..fac3eef0 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioDirectController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/RatioDirectController.java @@ -4,25 +4,24 @@ import cn.hutool.core.collection.CollectionUtil; import com.nflg.mobilebroken.common.constant.Constant; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.dto.RatioDirectEffectiveDTO; +import com.nflg.mobilebroken.common.pojo.dto.UserModelPriceDTO; +import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest; import com.nflg.mobilebroken.common.pojo.vo.DynamicHeaderVO; +import com.nflg.mobilebroken.common.pojo.vo.DynamicTableVO; import com.nflg.mobilebroken.common.pojo.vo.ModelPriceVO; +import com.nflg.mobilebroken.common.util.AdminUserUtil; +import com.nflg.mobilebroken.common.util.NumberUtil; import com.nflg.mobilebroken.quotation.controller.ControllerBase; -import com.nflg.mobilebroken.repository.entity.AdminUser; -import com.nflg.mobilebroken.repository.entity.DictionaryItem; -import com.nflg.mobilebroken.repository.entity.TBaseDepartment; +import com.nflg.mobilebroken.quotation.pojo.vo.RatioAgentSearchVO; +import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; /** @@ -47,59 +46,207 @@ public class RatioDirectController extends ControllerBase { @Resource private IQuotationModelRatioDirectService ratioDirectService; + @Resource + private IQuotationModelRatioDirectItemService ratioDirectItemService; + + @Resource + private IProductModelService productModelService; + /** * 获取动态表头 + */ + @GetMapping("/headers") + public ApiResult> getHeaders() { + List vos = new ArrayList<>(); + vos.add(new DynamicHeaderVO() + .setProp("adminUser") + .setLabel("员工姓名") + .setChildren(new ArrayList<>() { + { + add(new DynamicHeaderVO().setProp("modelNo").setLabel("机型")); + } + }) + ); + List items = ratioDirectItemService.getEffectiveByUser(AdminUserUtil.getUserId()); + if (CollectionUtil.isEmpty(items)) { + return ApiResult.success(vos); + } + List users = adminUserService.lambdaQuery() + .in(AdminUser::getId, items.stream().map(QuotationModelRatioDirectItem::getUserId).collect(Collectors.toSet())) + .list(); + List categories = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY); + List departments = departmentService.list(); + vos.addAll( + users.stream() + .map(user -> new DynamicHeaderVO() + .setProp(user.getId().toString()) + .setLabel(user.getUserName() + getDepartmentName( + departments.stream() + .filter(d -> d.getId().equals(user.getDepartmentId())) + .findFirst() + .orElse(null) + ) + ) + .setChildren( + new ArrayList<>() { + { + add(new DynamicHeaderVO() + .setProp(user.getId() + "standardPrice") + .setLabel("标配价" + getCategoryName( + categories.stream() + .filter(c -> c.getId().equals(user.getCategoryId())) + .findFirst() + .orElse(null) + ) + ) + ); + add(new DynamicHeaderVO() + .setProp(user.getId() + "standardRatio") + .setLabel("标配系数") + ); + add(new DynamicHeaderVO() + .setProp(user.getId() + "optionalRatio") + .setLabel("选配系数") + ); + add(new DynamicHeaderVO() + .setProp(user.getId() + "salePrice") + .setLabel("市场价" + getCategoryName( + categories.stream() + .filter(c -> c.getId().equals(user.getCategoryId())) + .findFirst() + .orElse(null) + ) + ) + ); + } + } + ) + ) + .collect(Collectors.toList()) + ); + return ApiResult.success(vos); + } + + /** + * 搜索 + */ + @PostMapping("/search") + public ApiResult search(@Valid @RequestBody ModelConfigSearchRequest request) { + QuotationModelRatioDirect ratioAgent = ratioDirectService.lambdaQuery() + .eq(QuotationModelRatioDirect::getStatus, 1) + .one(); + List items = ratioDirectItemService.getEffectiveByUser(AdminUserUtil.getUserId()); +// if (CollectionUtil.isEmpty(items)){ +// return ApiResult.success(vos); +// } + return ApiResult.success(new RatioAgentSearchVO()); + } + + /** + * 获取动态数据 * @param userIds 用户id列表 */ - @GetMapping("/header") - public ApiResult> getHeaders(@RequestBody @NotEmpty List userIds) { + @GetMapping("/getDatas") + public ApiResult getDatas(@RequestBody @NotEmpty List userIds) { List users = adminUserService.lambdaQuery().in(AdminUser::getId, userIds).list(); if (CollectionUtil.isEmpty(users)) { - return ApiResult.success(Collections.emptyList()); + return ApiResult.success(new DynamicTableVO()); } List categories = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY); List departments = departmentService.list(); - List ratioDirects=ratioDirectService.getEffectives(); + List ratioDirects = ratioDirectService.getEffectives(); List prices = priceService.getAllModelPrice(); - return ApiResult.success(users.stream() - .map(user -> new DynamicHeaderVO() - .setProp(user.getId().toString()) - .setLabel(user.getUserName() + getDepartmentName( - departments.stream() - .filter(d -> d.getId().equals(user.getDepartmentId())) - .findFirst() - .orElse(null) + DynamicTableVO vo = new DynamicTableVO(); + vo.setHeaders( + users.stream() + .map(user -> new DynamicHeaderVO() + .setProp(user.getId().toString()) + .setLabel(user.getUserName() + getDepartmentName( + departments.stream() + .filter(d -> d.getId().equals(user.getDepartmentId())) + .findFirst() + .orElse(null) + ) + ) + .setChildren( + new ArrayList<>() { + { + add(new DynamicHeaderVO() + .setProp(user.getId() + "standardPrice") + .setLabel("标配价" + getCategoryName( + categories.stream() + .filter(c -> c.getId().equals(user.getCategoryId())) + .findFirst() + .orElse(null) + ) + ) + ); + } + } ) ) - .setChildren( - new ArrayList<>() { - { - add(new DynamicHeaderVO() - .setProp(user.getId() + "standardPrice") - .setLabel("标配价" + getCategoryName( - categories.stream() - .filter(c -> c.getId().equals(user.getCategoryId())) - .findFirst() - .orElse(null) - ) - ) - ); - - } - } - ) - ) - .collect(Collectors.toList()) + .collect(Collectors.toList()) ); + List userPrices = new ArrayList<>(); + productModelService.lambdaQuery() + .select(ProductModel::getBatchNumber) + .eq(ProductModel::getState, 1) + .list() + .stream() + .map(ProductModel::getBatchNumber) + .collect(Collectors.toList()) + .forEach(modelId -> { + Map data = new HashMap<>(); + users.forEach(user -> { + data.put(user.getId() + "-standardPrice", getUserStandardPrice(modelId, user, users, ratioDirects, prices, userPrices)); + }); + vo.getDatas().add(data); + }); + return ApiResult.success(vo); } - private BigDecimal getUserStandardPrice(Integer userId,List ratioDirects,List prices){ - RatioDirectEffectiveDTO ratioDirect = ratioDirects.stream() - .filter(r -> r.getUserId().equals(userId)) + private BigDecimal getUserStandardPrice(Long modelId, AdminUser user, List users, List ratioDirects + , List prices, List userPrices) { + UserModelPriceDTO userPrice = userPrices.stream() + .filter(p -> p.getUserId().equals(user.getId()) && p.getModelId().equals(modelId)) .findFirst() .orElse(null); - if (Objects.isNull(ratioDirect)){ - return BigDecimal.ZERO; + if (Objects.isNull(userPrice)) { + RatioDirectEffectiveDTO ratioDirect = ratioDirects.stream() + .filter(r -> r.getUserId().equals(user.getId()) && r.getModelId().equals(modelId)) + .findFirst() + .orElse(null); + if (Objects.isNull(ratioDirect)) { + BigDecimal price = prices.stream() + .filter(p -> p.getModelId().equals(modelId) && p.getAreaId().equals(user.getCategoryId())) + .findFirst() + .map(ModelPriceVO::getAmount) + .orElse(null); + userPrices.add(new UserModelPriceDTO().setUserId(user.getId()).setModelId(modelId).setPrice(price)); + return price; + } else { + AdminUser parentUser = users.stream() + .filter(u -> u.getId().equals(ratioDirect.getParentUserId())) + .findFirst() + .orElse(null); + if (Objects.isNull(parentUser)) { + userPrices.add(new UserModelPriceDTO().setUserId(user.getId()).setModelId(modelId).setPrice(null)); + BigDecimal price = prices.stream() + .filter(p -> p.getModelId().equals(modelId) && p.getAreaId().equals(user.getCategoryId())) + .findFirst() + .map(ModelPriceVO::getAmount) + .orElse(null); + userPrices.add(new UserModelPriceDTO().setUserId(user.getId()).setModelId(modelId).setPrice(price)); + return price; + } else { + BigDecimal parentPrice = getUserStandardPrice(modelId, parentUser, users, ratioDirects, prices, userPrices); + BigDecimal price = NumberUtil.multiply(parentPrice, ratioDirect.getStandardRatio()); + userPrices.add(new UserModelPriceDTO().setUserId(user.getId()).setModelId(modelId).setPrice(price)); + return price; + } + } + } else { + return userPrice.getPrice(); } } diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/QuotationModelRatioVO.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/QuotationModelRatioVO.java new file mode 100644 index 00000000..9bec2df2 --- /dev/null +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/QuotationModelRatioVO.java @@ -0,0 +1,29 @@ +package com.nflg.mobilebroken.quotation.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class QuotationModelRatioVO { + + /** + * 年份 + */ + private String year; + + /** + * 版本号 + */ + private String version; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/RatioAgentSearchVO.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/RatioAgentSearchVO.java index 178d6dd1..200cb314 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/RatioAgentSearchVO.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/RatioAgentSearchVO.java @@ -11,7 +11,7 @@ import java.util.Map; @Accessors(chain = true) public class RatioAgentSearchVO { - private QuotationModelRatioAgent info; + private QuotationModelRatioVO info; private PageData> pageData; } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/QuotationModelRatioDirectItemMapper.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/QuotationModelRatioDirectItemMapper.java index c22f425c..5f27d9ad 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/QuotationModelRatioDirectItemMapper.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/QuotationModelRatioDirectItemMapper.java @@ -3,6 +3,8 @@ package com.nflg.mobilebroken.repository.mapper; import com.nflg.mobilebroken.repository.entity.QuotationModelRatioDirectItem; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.util.List; + /** *

* 报价-直销系数-子项 Mapper 接口 @@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface QuotationModelRatioDirectItemMapper extends BaseMapper { + List getEffectiveByUser(Integer userId); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IQuotationModelRatioDirectItemService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IQuotationModelRatioDirectItemService.java index 26932cd8..a9a7e352 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IQuotationModelRatioDirectItemService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IQuotationModelRatioDirectItemService.java @@ -3,6 +3,8 @@ package com.nflg.mobilebroken.repository.service; import com.nflg.mobilebroken.repository.entity.QuotationModelRatioDirectItem; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + /** *

* 报价-直销系数-子项 服务类 @@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface IQuotationModelRatioDirectItemService extends IService { + List getEffectiveByUser(Integer userId); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/QuotationModelRatioDirectItemServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/QuotationModelRatioDirectItemServiceImpl.java index 08d138a8..d6f77d57 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/QuotationModelRatioDirectItemServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/QuotationModelRatioDirectItemServiceImpl.java @@ -6,6 +6,8 @@ import com.nflg.mobilebroken.repository.service.IQuotationModelRatioDirectItemSe import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import java.util.List; + /** *

* 报价-直销系数-子项 服务实现类 @@ -17,4 +19,8 @@ import org.springframework.stereotype.Service; @Service public class QuotationModelRatioDirectItemServiceImpl extends ServiceImpl implements IQuotationModelRatioDirectItemService { + @Override + public List getEffectiveByUser(Integer userId) { + return baseMapper.getEffectiveByUser(userId); + } } diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/QuotationModelPriceMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/QuotationModelPriceMapper.xml index b2fd62f9..af7145b3 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/QuotationModelPriceMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/QuotationModelPriceMapper.xml @@ -3,7 +3,7 @@ + SELECT qmrdi.* + FROM quotation_model_ratio_direct_item qmrdi + INNER JOIN quotation_model_ratio_direct qmrd ON qmrdi.ratio_id=qmrd.id + WHERE qmrd.`status`=1 AND qmrd.create_by_id=#{userId} +