feat(quotation): 添加折扣配置功能并优化价格配置

- 新增折扣配置控制器和相关VO类
- 添加直销类别字典常量
- 优化价格配置搜索方法使用统一的API返回格式
- 添加部门负责人验证逻辑防止重复设置
- 修复代码中的空格格式问题
- 更新价格配置保存逻辑支持区域价格设置
- 添加批次号字段到产品模型搜索VO
- 修改代码生成器目标表名为折扣区域配置表
This commit is contained in:
曹鹏飞 2026-02-25 16:52:56 +08:00
parent 79e877cb5e
commit 5264fbc0d6
28 changed files with 869 additions and 145 deletions

View File

@ -111,15 +111,15 @@ public class AdminUserController extends ControllerBase {
@ApiMark(moduleName = "账号管理", apiName = "新增账号")
public ApiResult<Void> addAccount(@Valid @RequestBody AccountAddRequest request) {
request.setPassword(RandomUtil.randomString(6));
AdminUser adminUser=adminUserService.add(request);
AdminUser adminUser = adminUserService.add(request);
try {
String email = adminUser.getEmail();
String subject = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_TITLE_ACCOUNT_ACTIVATION, Constant.DEFAULT_LANGUAGE_CODE);
String content = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_CONTENT_ACCOUNT_ACTIVATION_NOTIFY, Constant.DEFAULT_LANGUAGE_CODE)
.replace("${loginName}",adminUser.getLoginName())
.replace("${url}",activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((email+"|0").getBytes()))
.replace("${password}",request.getPassword())
.replace("${website}",websiteUrl);
.replace("${loginName}", adminUser.getLoginName())
.replace("${url}", activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((email + "|0").getBytes()))
.replace("${password}", request.getPassword())
.replace("${website}", websiteUrl);
emailService.sendEmail(email, subject, content);
} catch (MessagingException e) {
log.error("发送邮件失败", e);
@ -136,7 +136,7 @@ public class AdminUserController extends ControllerBase {
@MethodInfoMark(value = "更新账号", menuName = "账号管理")
@ApiMark(moduleName = "账号管理", apiName = "更新账号")
public ApiResult<Void> updateAccount(@Valid @RequestBody AccountUpdateRequest request) {
AdminUser user=adminUserService.getById(request.getId());
AdminUser user = adminUserService.getById(request.getId());
if (!Objects.equals(user.getDepartmentId(), request.getDepartmentId())) {
departmentService.updateHasManager(user.getDepartmentId());
departmentService.lambdaUpdate()
@ -144,6 +144,12 @@ public class AdminUserController extends ControllerBase {
.eq(TBaseDepartment::isHasManager, false)
.eq(TBaseDepartment::getId, request.getDepartmentId())
.update();
VUtils.trueThrowBusinessError(departmentService.lambdaQuery()
.eq(TBaseDepartment::getId, request.getDepartmentId())
.eq(TBaseDepartment::isHasManager, true)
.exists()
)
.throwMessage("部门已存在负责人");
}
user.setUserCode(request.getUserCode())
.setUserName(request.getUserName())
@ -154,6 +160,7 @@ public class AdminUserController extends ControllerBase {
.setProductLine(request.getProductLine())
.setGongFuHandler(request.isGongFuHandler())
.setGongfu(StrUtil.contains(request.getProductLine(), Constant.MOBILE_BROKEN))
.setCategoryId(request.getCategoryId())
.setUpdateBy(AdminUserUtil.getUserId())
.setUpdateTime(LocalDateTime.now());
if (!Objects.equals(user.getState(), UserState.ToBeActivated.getState()) && Objects.nonNull(request.getEnable())) {
@ -211,9 +218,9 @@ public class AdminUserController extends ControllerBase {
AdminUser adminUser = adminUserService.resetPassword(id, password);
String subject = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_TITLE_ACCOUNT_RESET_PASSWORD, Constant.DEFAULT_LANGUAGE_CODE);
String content = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_CONTENT_RESET_PASSWORD_NOTIFY, Constant.DEFAULT_LANGUAGE_CODE)
.replace("${loginName}",adminUser.getLoginName())
.replace("${url}",activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((adminUser.getEmail()+"|0").getBytes()))
.replace("${password}",password);
.replace("${loginName}", adminUser.getLoginName())
.replace("${url}", activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((adminUser.getEmail() + "|0").getBytes()))
.replace("${password}", password);
emailService.sendEmail(adminUser.getEmail(), subject, content);
}
} catch (Exception ex) {
@ -232,12 +239,12 @@ public class AdminUserController extends ControllerBase {
public ApiResult<Void> forgetPassword(@Valid @RequestParam @NotBlank String email) {
try {
String password = RandomUtil.randomString(6);
AdminUser adminUser=adminUserService.forgetPassword(email, password);
AdminUser adminUser = adminUserService.forgetPassword(email, password);
String subject = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_TITLE_ACCOUNT_RESET_PASSWORD, Constant.DEFAULT_LANGUAGE_CODE);
String content = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_CONTENT_RESET_PASSWORD_NOTIFY, Constant.DEFAULT_LANGUAGE_CODE)
.replace("${loginName}",adminUser.getLoginName())
.replace("${url}",activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((email+"|0").getBytes()))
.replace("${password}",password);
.replace("${loginName}", adminUser.getLoginName())
.replace("${url}", activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((email + "|0").getBytes()))
.replace("${password}", password);
emailService.sendEmail(email, subject, content);
} catch (Exception ex) {
throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage());
@ -271,7 +278,7 @@ public class AdminUserController extends ControllerBase {
*/
@GetMapping("getFollowUrl")
@ApiMark(moduleName = "账号管理", apiName = "获取关注二维码链接", isPublic = true)
public ApiResult<String> getFollowUrl(){
public ApiResult<String> getFollowUrl() {
return ApiResult.success(wxQRCodeService.getFollowUrl(AdminUserUtil.getUserId()));
}
@ -315,8 +322,8 @@ public class AdminUserController extends ControllerBase {
stringRedisTemplate.opsForValue().set(StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA_ADMIN, email), kaptcha, Duration.ofHours(72));
String subject = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_TITLE_ACCOUNT_CHANGE_PASSWORD, Constant.DEFAULT_LANGUAGE_CODE);
String content = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_CONTENT_ACCOUNT_CHANGE_PASSWORD, Constant.DEFAULT_LANGUAGE_CODE)
.replace("${loginName}",email)
.replace("${password}",kaptcha);
.replace("${loginName}", email)
.replace("${password}", kaptcha);
emailService.sendEmail(email, subject, content);
} catch (Exception ex) {
throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage());
@ -329,7 +336,7 @@ public class AdminUserController extends ControllerBase {
* @return 用户信息
**/
@GetMapping("getInfo")
@ApiMark(moduleName = "账号管理", apiName = "获取当前登录用户信息",isPublic = true)
@ApiMark(moduleName = "账号管理", apiName = "获取当前登录用户信息", isPublic = true)
public ApiResult<AdminUserVO> getInfo() {
AdminUserVO adminUserVO = adminUserService.getInfo(AdminUserUtil.getUserId());
return ApiResult.success(adminUserVO);
@ -341,7 +348,7 @@ public class AdminUserController extends ControllerBase {
* @return 用户信息
**/
@GetMapping("getInfoById")
public ApiResult<AdminUserVO> getInfoById(@Valid @RequestParam @NotNull Integer userId){
public ApiResult<AdminUserVO> getInfoById(@Valid @RequestParam @NotNull Integer userId) {
return ApiResult.success(adminUserService.getInfo(userId));
}
@ -351,7 +358,7 @@ public class AdminUserController extends ControllerBase {
**/
@PostMapping("deleteAccount")
@ApiMark(moduleName = "账号管理", apiName = "删除账号", code = "account.delete")
public ApiResult<Void> deleteAccount(@Valid @RequestBody DeleteRequest request){
public ApiResult<Void> deleteAccount(@Valid @RequestBody DeleteRequest request) {
adminUserService.deleteAccount(request.getId());
return ApiResult.success();
}
@ -363,19 +370,19 @@ public class AdminUserController extends ControllerBase {
@PostMapping("changeEmail")
@ApiMark(moduleName = "账号管理", apiName = "更改邮箱")
public ApiResult<Void> changeEmail(@Valid @RequestBody EmailChangeRequest request) throws MessagingException {
AdminUser user=adminUserService.getById(request.getUserId());
AdminUser user = adminUserService.getById(request.getUserId());
VUtils.trueThrowBusinessError(adminUserService.lambdaQuery()
.eq(AdminUser::getLoginName, request.getEmail())
.ne(AdminUser::getId, request.getUserId())
.exists())
.throwMessage("已存在相同的登录名");
String code= RandomUtil.randomString(6);
.eq(AdminUser::getLoginName, request.getEmail())
.ne(AdminUser::getId, request.getUserId())
.exists())
.throwMessage("已存在相同的登录名");
String code = RandomUtil.randomString(6);
stringRedisTemplate.opsForValue().set(Constant.REDIS_KEY_CHANGE_EMAIL_CODE + user.getLoginName(), code, Duration.ofHours(72));
stringRedisTemplate.opsForValue().set(Constant.REDIS_KEY_CHANGE_EMAIL_CODE + code, request.getEmail(), Duration.ofHours(72));
String subject = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_TITLE_CHANGE_EMAIL, Constant.DEFAULT_LANGUAGE_CODE);
String content = dictionaryItemTranslateService.getValueByCode(Constant.DICTIONARY_EMAIL_NOTIFY, Constant.DICTIONARY_ITEM_EMAIL_CONTENT_CHANGE_EMAIL, Constant.DEFAULT_LANGUAGE_CODE)
.replace("${email}", user.getLoginName())
.replace("${url}", activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((user.getLoginName()+"|1").getBytes()))
.replace("${url}", activateUrl + "?code=" + Base64.getUrlEncoder().encodeToString((user.getLoginName() + "|1").getBytes()))
.replace("${password}", code);
emailService.sendEmail(request.getEmail(), subject, content);
return ApiResult.success();

View File

@ -108,6 +108,7 @@ public class BaseAreaController extends ControllerBase {
oldEnt.setDataModifyUserNo(AdminUserUtil.getUserNo());
oldEnt.setDataModifyUserName(AdminUserUtil.getUserName());
oldEnt.setDataModifyTime(LocalDateTime.now());
oldEnt.setCategoryId(baseAreaEditDTO.getCategoryId());
baseAreaService.updateById(oldEnt);
return ApiResult.success(true);

View File

@ -143,4 +143,9 @@ public class Constant {
* 移动破产品线名称
*/
public static final String MOBILE_BROKEN = "移动破碎";
/**
* 字典-直销类别
*/
public static final String DICTIONARY_DIRECT_SALES_CATEGORY ="DirectSalesCategory";
}

View File

@ -8,6 +8,10 @@ import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
public class ApiResult<T> implements Serializable {
@ -60,6 +64,19 @@ public class ApiResult<T> implements Serializable {
return vo;
}
public static <T,D> ApiResult<PageData<D>> success(IPage<T> page, Function<T, D> converter) {
ApiResult<PageData<D>> vo = new ApiResult<>();
PageData<D> pageData = new PageData<>();
pageData.setPage((int) page.getCurrent());
pageData.setPageSize((int) page.getSize());
pageData.setTotal((int) page.getTotal());
pageData.setItems(page.getRecords().stream().map(converter).collect(Collectors.toList()));
vo.setCode(STATE.Success.getState());
vo.setType(STATE.Success.getType());
vo.setResult(pageData);
return vo;
}
public static <T> ApiResult<T> error(int state, String msg, T value) {
ApiResult<T> vo = new ApiResult<>();
vo.result = value;

View File

@ -0,0 +1,37 @@
package com.nflg.mobilebroken.common.pojo.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class ModelDiscountConfigAreaVO {
/**
* 价格区域字典id
*/
private Long areaId;
private String code;
/**
* 价格区域名称
*/
private String areaName;
/**
* 折扣如0.95
*/
private BigDecimal ratio;
/**
* 折扣开始时间
*/
private LocalDateTime discountStartDate;
/**
* 折扣结束时间
*/
private LocalDateTime discountEndDate;
}

View File

@ -0,0 +1,57 @@
package com.nflg.mobilebroken.common.pojo.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Accessors(chain = true)
public class ModelDiscountConfigVO {
@JsonIgnore
private Long id;
/**
* 机型表batch_number
*/
private Long modelId;
/**
* 系列名称
*/
private String seriesName;
/**
* 类型名称
*/
private String typeName;
/**
* 机型编号
*/
private String modelNo;
/**
* 价格配置id
*/
@JsonIgnore
private Long priceId;
@JsonIgnore
private List<ModelDiscountConfigAreaVO> areas;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -9,7 +9,7 @@ import java.math.BigDecimal;
@Accessors(chain = true)
public class ModelPriceConfigAreaVO {
private Long id;
// private Long id;
/**
* 价格区域字典id

View File

@ -39,6 +39,11 @@ public class ProductModelSearchVO {
*/
private String typeNumber;
/**
* 批次号
*/
private Long batchNumber;
/**
* 型号
*/

View File

@ -0,0 +1,138 @@
package com.nflg.mobilebroken.quotation.controller.admin;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import com.nflg.mobilebroken.common.pojo.PageData;
import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
import com.nflg.mobilebroken.common.pojo.request.ModelPriceSaveRequest;
import com.nflg.mobilebroken.common.pojo.vo.DynamicHeaderVO;
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
import com.nflg.mobilebroken.common.util.DateTimeUtil;
import com.nflg.mobilebroken.common.util.NumberUtil;
import com.nflg.mobilebroken.quotation.controller.ControllerBase;
import com.nflg.mobilebroken.repository.entity.DictionaryItem;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountArea;
import com.nflg.mobilebroken.repository.entity.QuotationModelPriceItemArea;
import com.nflg.mobilebroken.repository.service.IDictionaryItemService;
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountAreaService;
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountService;
import com.nflg.mobilebroken.repository.service.IQuotationModelPriceItemAreaService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 折扣配置
*/
@RestController
@RequestMapping("/discount/config")
public class DiscountConfigController extends ControllerBase {
@Resource
private ObjectMapper objectMapper;
@Resource
private IDictionaryItemService dictionaryItemService;
@Resource
private IQuotationModelDiscountService discountService;
@Resource
private IQuotationModelDiscountAreaService discountAreaService;
@Resource
private IQuotationModelPriceItemAreaService priceItemAreaService;
/**
* 获取动态表头
*/
@GetMapping("/headers")
public ApiResult<List<DynamicHeaderVO>> getHeaders() {
List<DynamicHeaderVO> vos = new ArrayList<>();
vos.add(new DynamicHeaderVO().setProp("modelId").setLabel("modelId").setKey(true).setShow(false));
vos.add(new DynamicHeaderVO().setProp("modelNo").setLabel("产品机型"));
vos.add(new DynamicHeaderVO().setProp("seriesName").setLabel("产品系列"));
vos.add(new DynamicHeaderVO().setProp("typeName").setLabel("产品类型"));
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
areas.forEach(area -> {
vos.add(new DynamicHeaderVO().setProp(area.getCode()).setLabel(area.getName())
.setChildren(
List.of(new DynamicHeaderVO().setProp(area.getCode() + "_price").setLabel("标配保护价")
, new DynamicHeaderVO().setProp(area.getCode() + "_ratio").setLabel("折扣系数")
, new DynamicHeaderVO().setProp(area.getCode() + "_discount_price").setLabel("折扣系数")
, new DynamicHeaderVO().setProp(area.getCode() + "_start").setLabel("折扣开始时间")
, new DynamicHeaderVO().setProp(area.getCode() + "_end").setLabel("折扣结束时间")
, new DynamicHeaderVO().setProp(area.getCode() + "_days").setLabel("折扣天数")
)
)
);
});
vos.add(new DynamicHeaderVO().setProp("apply").setLabel("折扣对象"));
vos.add(new DynamicHeaderVO().setProp("updateBy").setLabel("设置人"));
vos.add(new DynamicHeaderVO().setProp("updateTime").setLabel("设置时间"));
return ApiResult.success(vos);
}
/**
* 搜索
*/
@PostMapping("/search")
public ApiResult<PageData<Map<String, Object>>> search(@Valid @RequestBody ModelConfigSearchRequest request) {
IPage<ModelDiscountConfigVO> pdata = discountService.search(request);
if (CollectionUtil.isEmpty(pdata.getRecords())) {
return ApiResult.success(PageData.empty());
}
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
List<QuotationModelPriceItemArea> modelPrices = priceItemAreaService.lambdaQuery()
.eq(QuotationModelPriceItemArea::getPriceItemId, 0)
.in(QuotationModelPriceItemArea::getPriceId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getPriceId).collect(Collectors.toList()))
.list();
List<QuotationModelDiscountArea> discountAreas = discountAreaService.lambdaQuery()
.in(QuotationModelDiscountArea::getDiscountId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getId).collect(Collectors.toList()))
.list();
return ApiResult.success(pdata,data->{
Map<String, Object> map = objectMapper.convertValue(data, new TypeReference<>() {
});
areas.forEach(area -> {
QuotationModelPriceItemArea modelPrice = modelPrices.stream()
.filter(price -> price.getAreaId().equals(area.getId()))
.findFirst()
.get();
map.put(area.getCode() + "_price", modelPrice.getAmount());
QuotationModelDiscountArea discountArea = discountAreas.stream()
.filter(price -> price.getAreaId().equals(area.getId()))
.findFirst()
.orElse(null);
BigDecimal ratio = Optional.ofNullable(discountArea).map(QuotationModelDiscountArea::getRatio).orElse(BigDecimal.ONE);
map.put(area.getCode() + "_ratio", NumberUtil.format(ratio));
map.put(area.getCode() + "_discount_price", NumberUtil.format(ratio.multiply(modelPrice.getAmount())));
map.put(area.getCode() + "_start", DateTimeUtil.format(Optional.ofNullable(discountArea).map(QuotationModelDiscountArea::getDiscountStartDate).orElse(null), "yyyy-MM-dd"));
map.put(area.getCode() + "_end", DateTimeUtil.format(Optional.ofNullable(discountArea).map(QuotationModelDiscountArea::getDiscountEndDate).orElse(null), "yyyy-MM-dd"));
map.put(area.getCode() + "_days", Optional.ofNullable(discountArea).map(QuotationModelDiscountArea::getDays).orElse(null));
});
return map;
});
}
// /**
// * 保存
// */
// @Transactional
// @PostMapping("/save")
// public ApiResult<Void> save(@Valid @RequestBody List<ModelDiscountSaveRequest> datas) {
//
// }
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import com.nflg.mobilebroken.common.pojo.PageData;
@ -72,7 +73,7 @@ public class PriceConfigController extends ControllerBase {
vos.add(new DynamicHeaderVO().setProp("priceStatusDesc").setLabel("单价版本状态"));
vos.add(new DynamicHeaderVO().setProp("typeDesc").setLabel("配置类别"));
vos.add(new DynamicHeaderVO().setProp("optionalTypeDesc").setLabel("配置单价类型"));
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode("DispatchCategory");
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
vos.add(new DynamicHeaderVO().setProp("").setLabel("保护价(¥)")
.setChildren(
areas.stream()
@ -89,33 +90,20 @@ public class PriceConfigController extends ControllerBase {
}
/**
* 获取机型价格配置列表
* 搜索
*/
@PostMapping("/search")
public ApiResult<PageData<Map<String, Object>>> search(@Valid @RequestBody ModelConfigSearchRequest request) {
IPage<ModelPriceConfigVO> pdata = priceService.search(request);
ApiResult<PageData<Map<String, Object>>> vo = new ApiResult<>();
PageData<Map<String, Object>> pageData = new PageData<>();
pageData.setPage((int) pdata.getCurrent());
pageData.setPageSize((int) pdata.getSize());
pageData.setTotal((int) pdata.getTotal());
pageData.setItems(pdata.getRecords().stream()
.map(it -> {
Map<String, Object> map = objectMapper.convertValue(it, new TypeReference<>() {
});
if (CollectionUtil.isNotEmpty(it.getAreas())) {
it.getAreas().forEach(area -> {
map.put(area.getCode(), NumberUtil.format(area.getAmount()));
});
}
return map;
})
.collect(Collectors.toList())
);
vo.setCode(STATE.Success.getState());
vo.setType(STATE.Success.getType());
vo.setResult(pageData);
return vo;
return ApiResult.success(priceService.search(request), data -> {
Map<String, Object> map = objectMapper.convertValue(data, new TypeReference<>() {
});
if (CollectionUtil.isNotEmpty(data.getAreas())) {
data.getAreas().forEach(area -> {
map.put(area.getCode(), NumberUtil.format(area.getAmount()));
});
}
return map;
});
}
/**
@ -124,7 +112,7 @@ public class PriceConfigController extends ControllerBase {
@Transactional
@PostMapping("/save")
public ApiResult<Void> save(@Valid @RequestBody List<ModelPriceSaveRequest> datas) {
List<DictionaryItem> dbAreas = dictionaryItemService.getListByDictionaryCode("DispatchCategory");
List<DictionaryItem> dbAreas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
Map<Long, List<ModelPriceSaveRequest>> group = datas.stream().collect(Collectors.groupingBy(ModelPriceSaveRequest::getModelId));
group.forEach((modelId, itemList) -> {
QuotationModelPrice price = priceService.lambdaQuery()
@ -147,14 +135,18 @@ public class PriceConfigController extends ControllerBase {
List<QuotationModelPriceItem> items = new ArrayList<>();
List<QuotationModelPriceItemArea> areas = new ArrayList<>();
for (ModelPriceSaveRequest it : itemList) {
QuotationModelPriceItem item = new QuotationModelPriceItem()
.setPriceId(price.getId())
.setId(IdUtil.getSnowflakeNextId())
.setConfigItemUniqueId(it.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
items.add(item);
Long itemId = 0L;
if (it.getConfigItemUniqueId() > 0) {
QuotationModelPriceItem item = new QuotationModelPriceItem()
.setPriceId(price.getId())
.setId(IdUtil.getSnowflakeNextId())
.setConfigItemUniqueId(it.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
items.add(item);
itemId = item.getId();
}
for (ModelPriceSaveAreaRequest ait : it.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
@ -164,7 +156,7 @@ public class PriceConfigController extends ControllerBase {
QuotationModelPriceItemArea area = new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setPriceItemId(itemId)
.setAmount(ait.getAmount());
areas.add(area);
}
@ -182,9 +174,11 @@ public class PriceConfigController extends ControllerBase {
.list();
List<QuotationModelPriceItemArea> areas = priceItemAreaService.lambdaQuery()
.eq(QuotationModelPriceItemArea::getPriceId, price.getId())
.in(QuotationModelPriceItemArea::getPriceItemId, items.stream()
.map(QuotationModelPriceItem::getId)
.collect(Collectors.toList())
.and(or -> or.eq(QuotationModelPriceItemArea::getPriceItemId, 0)
.in(QuotationModelPriceItemArea::getPriceItemId, items.stream()
.map(QuotationModelPriceItem::getId)
.collect(Collectors.toList())
)
)
.list();
List<QuotationModelPriceItem> itemsForAdd = new ArrayList<>();
@ -192,37 +186,63 @@ public class PriceConfigController extends ControllerBase {
List<QuotationModelPriceItemArea> areasForAdd = new ArrayList<>();
List<QuotationModelPriceItemArea> areasForUpdate = new ArrayList<>();
for (ModelPriceSaveRequest sit : itemList) {
QuotationModelPriceItem item = items.stream()
.filter(it -> sit.getConfigItemUniqueId().equals(it.getConfigItemUniqueId()))
.findFirst()
.orElse(null);
if (Objects.isNull(item)) {
item = new QuotationModelPriceItem()
.setId(IdUtil.getSnowflakeNextId())
.setPriceId(price.getId())
.setConfigItemUniqueId(sit.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
itemsForAdd.add(item);
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
if (sit.getConfigItemUniqueId() > 0) {
QuotationModelPriceItem item = items.stream()
.filter(it -> sit.getConfigItemUniqueId().equals(it.getConfigItemUniqueId()))
.findFirst()
.orElse(null);
if (Objects.isNull(item)) {
item = new QuotationModelPriceItem()
.setId(IdUtil.getSnowflakeNextId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
.setConfigItemUniqueId(sit.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
itemsForAdd.add(item);
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
}
} else {
item.setUpdateById(AdminUserUtil.getUserId());
item.setUpdateBy(AdminUserUtil.getUserName());
item.setUpdateTime(LocalDateTime.now());
itemsForUpdate.add(item);
QuotationModelPriceItem finalItem = item;
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
QuotationModelPriceItemArea area = areas.stream()
.filter(it -> it.getPriceItemId().equals(finalItem.getId())
&& it.getAreaId().equals(ai.getId())
)
.findFirst()
.orElse(null);
if (Objects.isNull(area)) {
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
} else {
area.setAmount(ait.getAmount());
areasForUpdate.add(area);
}
}
}
} else {
item.setUpdateById(AdminUserUtil.getUserId());
item.setUpdateBy(AdminUserUtil.getUserName());
item.setUpdateTime(LocalDateTime.now());
itemsForUpdate.add(item);
QuotationModelPriceItem finalItem = item;
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
@ -230,18 +250,12 @@ public class PriceConfigController extends ControllerBase {
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
QuotationModelPriceItemArea area = areas.stream()
.filter(it -> it.getPriceItemId().equals(finalItem.getId())
.filter(it -> it.getPriceItemId().equals(0L)
&& it.getAreaId().equals(ai.getId())
)
.findFirst()
.orElse(null);
if (Objects.isNull(area)) {
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
} else {
if (Objects.nonNull(area)) {
area.setAmount(ait.getAmount());
areasForUpdate.add(area);
}
@ -279,69 +293,90 @@ public class PriceConfigController extends ControllerBase {
price.setUpdateBy(AdminUserUtil.getUserName());
price.setUpdateTime(LocalDateTime.now());
for (ModelPriceSaveRequest sit : itemList) {
QuotationModelPriceItem dbItem = dbItems.stream()
.filter(ait -> ait.getConfigItemUniqueId().equals(sit.getConfigItemUniqueId()))
.findFirst()
.orElse(null);
if (Objects.nonNull(dbItem)) {
List<QuotationModelPriceItemArea> areas = areasForAdd.stream()
.filter(area -> area.getPriceItemId().equals(dbItem.getId()))
.collect(Collectors.toList());
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
QuotationModelPriceItemArea area = areas.stream()
.filter(it -> it.getAreaId().equals(ai.getId()))
.findFirst()
.orElse(null);
if (Objects.nonNull(area)) {
area.setId(IdUtil.getSnowflakeNextId());
area.setPriceId(price.getId());
area.setAmount(ait.getAmount());
areasForAdd.add(area);
} else {
if (sit.getConfigItemUniqueId() > 0) {
QuotationModelPriceItem dbItem = dbItems.stream()
.filter(ait -> ait.getConfigItemUniqueId().equals(sit.getConfigItemUniqueId()))
.findFirst()
.orElse(null);
if (Objects.nonNull(dbItem)) {
List<QuotationModelPriceItemArea> areas = areasForAdd.stream()
.filter(area -> area.getPriceItemId().equals(dbItem.getId()))
.collect(Collectors.toList());
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
QuotationModelPriceItemArea area = areas.stream()
.filter(it -> it.getAreaId().equals(ai.getId()))
.findFirst()
.orElse(null);
if (Objects.nonNull(area)) {
area.setId(IdUtil.getSnowflakeNextId());
area.setPriceId(price.getId());
area.setAmount(ait.getAmount());
areasForAdd.add(area);
} else {
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(dbItem.getId())
.setAmount(ait.getAmount()));
}
}
} else {
QuotationModelPriceItem item = new QuotationModelPriceItem()
.setId(IdUtil.getSnowflakeNextId())
.setPriceId(price.getId())
.setConfigItemUniqueId(sit.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
itemsForAdd.add(item);
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(dbItem.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
}
}
} else {
QuotationModelPriceItem item = new QuotationModelPriceItem()
.setId(IdUtil.getSnowflakeNextId())
.setPriceId(price.getId())
.setConfigItemUniqueId(sit.getConfigItemUniqueId())
.setUpdateById(AdminUserUtil.getUserId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
itemsForAdd.add(item);
for (ModelPriceSaveAreaRequest ait : sit.getAreas()) {
DictionaryItem ai = dbAreas.stream()
.filter(a -> a.getCode().equals(ait.getAreaCode()))
.findFirst()
.orElse(null);
VUtils.trueThrowBusinessError(Objects.isNull(ai)).throwMessage("找不到区域:" + ait.getAreaCode());
areasForAdd.add(new QuotationModelPriceItemArea()
.setAreaId(ai.getId())
.setPriceId(price.getId())
.setPriceItemId(item.getId())
.setAmount(ait.getAmount()));
QuotationModelPriceItemArea area = areasForAdd.stream()
.filter(it -> it.getPriceItemId().equals(0L)
&& it.getAreaId().equals(ai.getId())
)
.findFirst()
.orElse(null);
if (Objects.nonNull(area)) {
area.setAmount(ait.getAmount());
areasForAdd.add(area);
}
}
}
}
for (QuotationModelPriceItem item : dbItems) {
Long itemId = IdUtil.getSnowflakeNextId();
item.setUpdateById(AdminUserUtil.getUserId());
item.setUpdateBy(AdminUserUtil.getUserName());
item.setUpdateTime(LocalDateTime.now());
item.setId(IdUtil.getSnowflakeNextId());
item.setPriceId(price.getId());
areasForAdd.stream()
.filter(area -> area.getPriceItemId().equals(item.getId()))
.forEach(area -> area.setPriceItemId(item.getId()));
.forEach(area -> area.setPriceItemId(itemId));
item.setId(itemId);
}
priceService.save(price);
if (CollectionUtil.isNotEmpty(itemsForAdd)) {

View File

@ -0,0 +1,73 @@
package com.nflg.mobilebroken.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
* 报价-机型折扣
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("quotation_model_discount")
public class QuotationModelDiscount implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 流水号
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 机型编号
*/
private Long modelId;
/**
* 版本状态0草稿1已发布2已弃用
*/
private Integer discountStatus;
/**
* 新增人编号
*/
private Integer createById;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 修改人编号
*/
private Integer updateById;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,63 @@
package com.nflg.mobilebroken.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
* 报价-机型折扣-折扣对象
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("quotation_model_discount_apply")
public class QuotationModelDiscountApply implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 折扣ID
*/
private Integer discountId;
/**
* 用户类型 0 内部用户1 代理商公司
*/
private Integer sourceType;
/**
* 用户ID
*/
private Integer sourceId;
/**
* 新增人编号
*/
private Integer createById;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@ -0,0 +1,64 @@
package com.nflg.mobilebroken.repository.entity;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
* 报价-机型折扣-区域
* </p>
* @author 代码生成器生成
* @since 2026
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("quotation_model_discount_area")
public class QuotationModelDiscountArea implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
/**
* 折扣id
*/
private Long discountId;
/**
* 区域字典id
*/
private Long areaId;
/**
* 折扣如0.95
*/
private BigDecimal ratio;
/**
* 折扣开始时间
*/
private LocalDateTime discountStartDate;
/**
* 折扣结束时间
*/
private LocalDateTime discountEndDate;
@TableField(exist = false)
private Long days;
public Long getDays() {
return ChronoUnit.DAYS.between(discountStartDate, discountEndDate) + 1;
}
}

View File

@ -0,0 +1,16 @@
package com.nflg.mobilebroken.repository.mapper;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountApply;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 报价-机型折扣-折扣对象 Mapper 接口
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface QuotationModelDiscountApplyMapper extends BaseMapper<QuotationModelDiscountApply> {
}

View File

@ -0,0 +1,16 @@
package com.nflg.mobilebroken.repository.mapper;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountArea;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 报价-机型折扣-区域 Mapper 接口
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface QuotationModelDiscountAreaMapper extends BaseMapper<QuotationModelDiscountArea> {
}

View File

@ -0,0 +1,21 @@
package com.nflg.mobilebroken.repository.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscount;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 报价-机型折扣 Mapper 接口
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface QuotationModelDiscountMapper extends BaseMapper<QuotationModelDiscount> {
IPage<ModelDiscountConfigVO> search(ModelConfigSearchRequest request, Page<?> page);
}

View File

@ -0,0 +1,16 @@
package com.nflg.mobilebroken.repository.service;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountApply;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 报价-机型折扣-折扣对象 服务类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface IQuotationModelDiscountApplyService extends IService<QuotationModelDiscountApply> {
}

View File

@ -0,0 +1,16 @@
package com.nflg.mobilebroken.repository.service;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountArea;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 报价-机型折扣-区域 服务类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface IQuotationModelDiscountAreaService extends IService<QuotationModelDiscountArea> {
}

View File

@ -0,0 +1,22 @@
package com.nflg.mobilebroken.repository.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscount;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
/**
* <p>
* 报价-机型折扣 服务类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
public interface IQuotationModelDiscountService extends IService<QuotationModelDiscount> {
IPage<ModelDiscountConfigVO> search(ModelConfigSearchRequest request);
}

View File

@ -87,6 +87,12 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
@Override
public AdminUser add(AccountAddRequest request) {
VUtils.trueThrowBusinessError(departmentService.lambdaQuery()
.eq(TBaseDepartment::getId, request.getDepartmentId())
.eq(TBaseDepartment::isHasManager, true)
.exists()
)
.throwMessage("部门已存在负责人");
AdminUser user = lambdaQuery().eq(AdminUser::getLoginName, request.getLoginName()).one();
if (Objects.nonNull(user)) {
VUtils.trueThrowBusinessError(!user.getIsDel())
@ -463,7 +469,7 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
List<AdminUser> roots = adminUsers.stream()
.filter(u -> Objects.equals(u.getDepartmentId(), department.getId()))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(adminUsers)) {
if (CollectionUtil.isEmpty(roots)) {
return Collections.emptyList();
}
List<AdminUserVO> rootUserVOS = convert(roots, department, positions, roleMaps, roles);

View File

@ -0,0 +1,20 @@
package com.nflg.mobilebroken.repository.service.impl;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountApply;
import com.nflg.mobilebroken.repository.mapper.QuotationModelDiscountApplyMapper;
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountApplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 报价-机型折扣-折扣对象 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
@Service
public class QuotationModelDiscountApplyServiceImpl extends ServiceImpl<QuotationModelDiscountApplyMapper, QuotationModelDiscountApply> implements IQuotationModelDiscountApplyService {
}

View File

@ -0,0 +1,20 @@
package com.nflg.mobilebroken.repository.service.impl;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscountArea;
import com.nflg.mobilebroken.repository.mapper.QuotationModelDiscountAreaMapper;
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountAreaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 报价-机型折扣-区域 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
@Service
public class QuotationModelDiscountAreaServiceImpl extends ServiceImpl<QuotationModelDiscountAreaMapper, QuotationModelDiscountArea> implements IQuotationModelDiscountAreaService {
}

View File

@ -0,0 +1,28 @@
package com.nflg.mobilebroken.repository.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
import com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO;
import com.nflg.mobilebroken.repository.entity.QuotationModelDiscount;
import com.nflg.mobilebroken.repository.mapper.QuotationModelDiscountMapper;
import com.nflg.mobilebroken.repository.service.IQuotationModelDiscountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 报价-机型折扣 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2026
*/
@Service
public class QuotationModelDiscountServiceImpl extends ServiceImpl<QuotationModelDiscountMapper, QuotationModelDiscount> implements IQuotationModelDiscountService {
@Override
public IPage<ModelDiscountConfigVO> search(ModelConfigSearchRequest request) {
return baseMapper.search(request, new Page<>(request.getPage(), request.getPageSize()));
}
}

View File

@ -3,6 +3,7 @@ package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.pojo.request.ModelConfigSearchRequest;
import com.nflg.mobilebroken.common.pojo.vo.ModelPriceConfigAreaVO;
import com.nflg.mobilebroken.common.pojo.vo.ModelPriceConfigVO;
@ -63,7 +64,7 @@ public class QuotationModelPriceServiceImpl extends ServiceImpl<QuotationModelPr
List<QuotationModelPriceItem> priceItems = CollectionUtil.isEmpty(priceIds) ? new ArrayList<>() : priceItemService.lambdaQuery()
.in(QuotationModelPriceItem::getPriceId, priceIds)
.list();
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode("DispatchCategory");
List<DictionaryItem> areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY);
pdata.getRecords().forEach(data -> {
if (Objects.nonNull(data.getConfigId())) {
List<QuotationModelConfigItem> items = configItems.stream()
@ -108,7 +109,7 @@ public class QuotationModelPriceServiceImpl extends ServiceImpl<QuotationModelPr
.findFirst()
.orElse(null);
return new ModelPriceConfigAreaVO()
.setId(area.getId())
// .setId(area.getId())
.setAmount(area.getAmount())
.setAreaId(area.getAreaId())
.setCode(Objects.isNull(aa) ? "" : aa.getCode())

View File

@ -0,0 +1,5 @@
<?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.nflg.mobilebroken.repository.mapper.QuotationModelDiscountApplyMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?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.nflg.mobilebroken.repository.mapper.QuotationModelDiscountAreaMapper">
</mapper>

View File

@ -0,0 +1,30 @@
<?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.nflg.mobilebroken.repository.mapper.QuotationModelDiscountMapper">
<select id="search" resultType="com.nflg.mobilebroken.common.pojo.vo.ModelDiscountConfigVO">
SELECT qmd.model_id,qmp.id as 'priceId',ps.name as 'seriesName',pt.name as 'typeName',pm.`no` as 'modelNo',qmp.update_by,qmp.update_time
FROM quotation_model_discount qmd
INNER JOIN quotation_model_price qmp ON qmp.model_id=qmd.model_id and qmp.price_status=1
INNER JOIN product_model pm ON qmd.model_id=pm.batch_number
LEFT JOIN product_type pt on pm.type_number=pt.batch_number AND pt.state=1
LEFT JOIN product_series ps ON pm.series_number=ps.batch_number AND ps.state=1
LEFT JOIN dictionary_item di ON di.id=pm.module_id
WHERE pm.state=1
<where>
<if test="request.moduleId!=null">
AND pm.module_id=#{request.moduleId}
</if>
<if test="request.seriesNumber!=null">
AND pm.series_number=#{request.seriesNumber}
</if>
<if test="request.typeNumber!=null">
AND pm.type_number=#{request.typeNumber}
</if>
<if test="request.no!=null and request.no!=''">
AND pm.`no` like concat('%', #{request.no}, '%')
</if>
</where>
order by qmd.update_time desc,qmd.id desc
</select>
</mapper>

View File

@ -33,7 +33,7 @@ public class CodeGeneratorTest {
, Paths.get(System.getProperty("user.dir")) + "/src/main/resources/mapper"))
)
.strategyConfig(builder -> {
builder.addInclude("quotation_model_price_item_area") //只生成指定表
builder.addInclude("quotation_model_discount_area") //只生成指定表
.entityBuilder()
.enableLombok()
.enableChainModel()