diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/ProductTypeSimpleVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/ProductTypeSimpleVO.java index 3c4b7e20..8bd6460c 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/ProductTypeSimpleVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/ProductTypeSimpleVO.java @@ -10,6 +10,11 @@ public class ProductTypeSimpleVO { */ private String moduleName; + /** + * 系列ID + */ + private Long seriesNumber; + /** * 系列名称 */ @@ -28,5 +33,5 @@ public class ProductTypeSimpleVO { /** * 批次号 */ - private String batchNumber; + private String typeNumber; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelInfoVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelInfoVO.java index 5cadae40..0588a88a 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelInfoVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelInfoVO.java @@ -20,6 +20,11 @@ public class QuotationProductModelInfoVO { */ private String typeName; + /** + * 批次编号 + */ + private Long batchNumber; + /** * 机型 */ diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelSearchVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelSearchVO.java index 796a0d7d..a2196b40 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelSearchVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/QuotationProductModelSearchVO.java @@ -55,4 +55,9 @@ public class QuotationProductModelSearchVO { */ @JsonProperty("hasDiscount") private Boolean hasDiscount; + + /** + * 机型图片 + */ + private String image; } diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java index 817df415..1f39466b 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/AdminShoppingController.java @@ -12,14 +12,13 @@ import com.nflg.mobilebroken.common.util.AppUserUtil; import com.nflg.mobilebroken.quotation.controller.ControllerBase; import com.nflg.mobilebroken.repository.entity.AdminUser; import com.nflg.mobilebroken.repository.entity.ProductModel; +import com.nflg.mobilebroken.repository.entity.QuotationShoppingOrderAdjust; import com.nflg.mobilebroken.repository.entity.TBaseCustomer; import com.nflg.mobilebroken.repository.service.IAdminUserService; +import com.nflg.mobilebroken.repository.service.IQuotationShoppingOrderAdjustService; import com.nflg.mobilebroken.repository.service.IQuotationShoppingOrderService; import com.nflg.mobilebroken.repository.service.ITBaseCustomerService; -import org.springframework.web.bind.annotation.PostMapping; -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; @@ -36,13 +35,16 @@ public class AdminShoppingController extends ControllerBase { @Resource private IQuotationShoppingOrderService shoppingOrderService; + @Resource + private IQuotationShoppingOrderAdjustService shoppingOrderAdjustService; + /** * 查询报价单 */ @PostMapping("/search") public ApiResult> searchQuotation(@Valid @RequestBody QuotationAdminSearchRequest request) { IPage datas = shoppingOrderService.searchFromAdmin(request); - if (CollectionUtil.isEmpty(datas.getRecords())){ + if (CollectionUtil.isEmpty(datas.getRecords())) { return ApiResult.success(PageData.empty()); } return ApiResult.success(datas, data -> { @@ -50,4 +52,15 @@ public class AdminShoppingController extends ControllerBase { return data; }); } + + /** + * 获取调价记录 + */ + @GetMapping("/adjusts") + public ApiResult> getAdjusts(@RequestParam Long orderId) { + return ApiResult.success(shoppingOrderAdjustService.lambdaQuery() + .eq(QuotationShoppingOrderAdjust::getOrderId, orderId) + .list() + ); + } } \ No newline at end of file diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/DiscountConfigController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/DiscountConfigController.java index a73d7167..644bf80e 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/DiscountConfigController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/DiscountConfigController.java @@ -80,6 +80,12 @@ public class DiscountConfigController extends ControllerBase { @Resource private IProductModelService productModelService; + @Resource + private IAppUserService appUserService; + + @Resource + private ITBaseAreaService areaService; + /** * 根据机型获取价格 */ @@ -132,6 +138,61 @@ public class DiscountConfigController extends ControllerBase { return ApiResult.success(vos); } + /** + * 获取所有报价对象 + */ + @GetMapping("/applyFors") + public ApiResult> getApplyFors() { + List applyFors = new ArrayList<>(); + List areas = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_DIRECT_SALES_CATEGORY); + List appUsers = appUserService.getEndUsers(); + if (CollectionUtil.isNotEmpty(appUsers)) { + List baseAreas = areaService.lambdaQuery() + .in(TBaseArea::getId, appUsers.stream().map(AppUser::getAreaId).collect(Collectors.toSet())) + .list(); + appUsers.forEach(appUser -> { + applyFors.add(new DiscountApplyForVO() + .setSourceType(0) + .setSourceId(appUser.getId()) + .setName(appUser.getName()) + .setAreaName( + areas.stream() + .filter(area -> Objects.equals(area.getId() + , baseAreas.stream() + .filter(ba -> ba.getId().equals(appUser.getAreaId())) + .findFirst() + .map(TBaseArea::getCategoryId) + .orElse(null) + ) + ) + .findFirst() + .map(DictionaryItem::getName) + .orElse("未知") + ) + ); + }); + } + List customers = customerService.getForQuotation(); + if (CollectionUtil.isNotEmpty(customers)) { + applyFors.addAll(customers.stream() + .map(c -> new DiscountApplyForVO() + .setSourceType(1) + .setSourceId(c.getId()) + .setName(c.getAgencyCompanyName()) + .setAreaName( + areas.stream() + .filter(area -> area.getId().equals(c.getCategoryId())) + .findFirst() + .map(DictionaryItem::getName) + .orElse("未知") + ) + ) + .collect(Collectors.toList()) + ); + } + return ApiResult.success(applyFors); + } + /** * 搜索 */ @@ -150,7 +211,6 @@ public class DiscountConfigController extends ControllerBase { .in(QuotationModelDiscountArea::getDiscountId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getId).collect(Collectors.toList())) .list(); List applies = discountApplyService.lambdaQuery() - .eq(QuotationModelDiscountApply::getSourceType, 1) .in(QuotationModelDiscountApply::getDiscountId, pdata.getRecords().stream().map(ModelDiscountConfigVO::getId).collect(Collectors.toList())) .list(); return ApiResult.success(pdata, data -> { @@ -173,26 +233,63 @@ public class DiscountConfigController extends ControllerBase { 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)); }); - List customers = customerService.lambdaQuery() - .in(TBaseCustomer::getId, applies.stream() - .filter(apply -> apply.getDiscountId().equals(data.getId())) - .map(QuotationModelDiscountApply::getSourceId) - .collect(Collectors.toList()) - ) - .list(); - map.put("applyFors", customers.stream() - .map(c -> new DiscountApplyForVO() - .setId(c.getId()) - .setAgencyCompanyName(c.getAgencyCompanyName()) + List applyIds = applies.stream() + .filter(apply -> apply.getSourceType() == 0 && apply.getDiscountId().equals(data.getId())) + .map(QuotationModelDiscountApply::getSourceId) + .collect(Collectors.toList()); + List applyFors = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(applyIds)) { + List appUsers = appUserService.listByIds(applyIds); + List baseAreas = areaService.lambdaQuery() + .in(TBaseArea::getId, appUsers.stream().map(AppUser::getAreaId).collect(Collectors.toSet())) + .list(); + appUsers.forEach(appUser -> { + applyFors.add(new DiscountApplyForVO() + .setSourceType(0) + .setSourceId(appUser.getId()) + .setName(appUser.getName()) .setAreaName( areas.stream() - .filter(area -> area.getId().equals(c.getCategoryId())) + .filter(area -> Objects.equals(area.getId() + , baseAreas.stream() + .filter(ba -> ba.getId().equals(appUser.getAreaId())) + .findFirst() + .map(TBaseArea::getCategoryId) + .orElse(null) + ) + ) .findFirst() .map(DictionaryItem::getName) .orElse("未知") ) - ).collect(Collectors.toList()) - ); + ); + }); + } + applyIds = applies.stream() + .filter(apply -> apply.getSourceType() == 1 && apply.getDiscountId().equals(data.getId())) + .map(QuotationModelDiscountApply::getSourceId) + .collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(applyIds)) { + List customers = customerService.lambdaQuery() + .in(TBaseCustomer::getId, applyIds) + .list(); + applyFors.addAll(customers.stream() + .map(c -> new DiscountApplyForVO() + .setSourceType(1) + .setSourceId(c.getId()) + .setName(c.getAgencyCompanyName()) + .setAreaName( + areas.stream() + .filter(area -> area.getId().equals(c.getCategoryId())) + .findFirst() + .map(DictionaryItem::getName) + .orElse("未知") + ) + ) + .collect(Collectors.toList()) + ); + } + map.put("applyFors", applyFors); return map; }); } @@ -233,7 +330,8 @@ public class DiscountConfigController extends ControllerBase { for (JsonNode apply : data.get("applyFors")) { discountApplies.add(new QuotationModelDiscountApply() .setDiscountId(discount.getId()) - .setSourceId(apply.get("id").asInt()) + .setSourceType(apply.get("sourceType").asInt()) + .setSourceId(apply.get("sourceId").asInt()) .setCreateById(AdminUserUtil.getUserId()) .setCreateBy(AdminUserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/ForbidConfigController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/ForbidConfigController.java index 043e9b07..37fd85d2 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/ForbidConfigController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/admin/ForbidConfigController.java @@ -99,7 +99,7 @@ public class ForbidConfigController extends ControllerBase { map.put("modelId", data.getBatchNumber()); map.put("modelNo", data.getNo()); customers.forEach(customer -> { - map.put(customer.getAgencyCompanyCode(), forbids.stream() + map.put(customer.getAgencyCompanyCode(), !forbids.stream() .filter(forbid -> forbid.getModelId().equals(data.getBatchNumber()) && forbid.getSourceType().equals(1) && forbid.getSourceId().equals(customer.getId())) @@ -142,7 +142,7 @@ public class ForbidConfigController extends ControllerBase { .findFirst() .orElse(null); if (Objects.nonNull(customer)) { - Boolean isForbid = (Boolean) value; + Boolean isForbid = !(Boolean)value; QuotationModelForbid forbid = forbids.stream() .filter(f -> f.getModelId().equals(modelId) && f.getSourceType() == 1 && f.getSourceId().equals(customer.getId())) .findFirst() diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/AppRatioAgentConfigController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/AppRatioAgentConfigController.java index eb003bad..f4d5b12f 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/AppRatioAgentConfigController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/AppRatioAgentConfigController.java @@ -251,6 +251,7 @@ public class AppRatioAgentConfigController extends ControllerBase { DictionaryItem category = appUserService.getCategory(cuser); VUtils.trueThrowBusinessError(Objects.isNull(category)).throwMessage("请联系管理员为你设置区域类型"); List plans = planModelItemService.getEffectivesForAgent(); + List items = ratioAgentItemService.getEffectiveByCreate(AppUserUtil.getUserId()); if (Objects.isNull(request.getUserId())) { List vos = new ArrayList<>(); IPage pdatas = priceService.search(request); @@ -258,8 +259,10 @@ public class AppRatioAgentConfigController extends ControllerBase { pdatas.getRecords().forEach(data -> { RatioConfigSearchVO vo = new RatioConfigSearchVO().setModelNo(data.getModelNo()); vos.add(vo); - List items = ratioAgentItemService.getEffectiveByCreate(AppUserUtil.getUserId()); - if (CollectionUtil.isNotEmpty(items)) { + List modelItems= items.stream() + .filter(it -> it.getModelId().equals(data.getModelId())) + .collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(modelItems)) { ModelPriceVO modelPrice = prices.stream() .filter(it -> it.getModelId().equals(data.getModelId()) && it.getAreaId().equals(category.getId())) .findFirst() @@ -270,7 +273,7 @@ public class AppRatioAgentConfigController extends ControllerBase { .map(QuotationModelRatioAgentItem::getStandardRatio) .orElse(null)) : null; - items.forEach(item -> { + modelItems.forEach(item -> { RatioConfigSearchVO vou = new RatioConfigSearchVO() .setName(item.getUserName()) .setStandardPrice(basePrice) @@ -301,7 +304,6 @@ public class AppRatioAgentConfigController extends ControllerBase { pageData.setPageSize(request.getPageSize()); List vos = new ArrayList<>(); pageData.setItems(vos); - List items = ratioAgentItemService.getEffectiveByCreate(AppUserUtil.getUserId()); List filterItems = items.stream() .filter(item -> item.getUserId().equals(request.getUserId())) .collect(Collectors.toList()); diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/PlanController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/PlanController.java index 9e3132cb..747ca8e1 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/PlanController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/PlanController.java @@ -1,5 +1,6 @@ package com.nflg.mobilebroken.quotation.controller.app; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.nflg.mobilebroken.common.pojo.ApiResult; diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java index f37766c4..634c8cea 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/controller/app/ShoppingController.java @@ -5,6 +5,9 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.itextpdf.text.pdf.BaseFont; +import com.nflg.mobilebroken.common.constant.STATE; +import com.nflg.mobilebroken.common.exception.NflgException; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; import com.nflg.mobilebroken.common.pojo.dto.ModelConfigEffectiveDTO; @@ -18,10 +21,7 @@ import com.nflg.mobilebroken.common.pojo.vo.ShoppingSearchVO; import com.nflg.mobilebroken.common.pojo.vo.SimpleUserVO; import com.nflg.mobilebroken.common.util.*; import com.nflg.mobilebroken.quotation.controller.ControllerBase; -import com.nflg.mobilebroken.quotation.pojo.request.QuotationInfoUpdateRequest; -import com.nflg.mobilebroken.quotation.pojo.request.QuotationPriceUpdateRequest; -import com.nflg.mobilebroken.quotation.pojo.request.ShoppingInitRequest; -import com.nflg.mobilebroken.quotation.pojo.request.ShoppingSaveRequest; +import com.nflg.mobilebroken.quotation.pojo.request.*; import com.nflg.mobilebroken.quotation.pojo.vo.QuotationOrderInfoVO; import com.nflg.mobilebroken.quotation.pojo.vo.ShoppingCartPartVO; import com.nflg.mobilebroken.quotation.pojo.vo.ShoppingCartVO; @@ -29,13 +29,29 @@ import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import org.springframework.core.io.ClassPathResource; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.context.Context; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; +import org.xhtmlrenderer.pdf.ITextRenderer; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.OutputStream; import java.math.BigDecimal; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; @@ -49,6 +65,8 @@ import java.util.stream.Collectors; @RequestMapping("/app/shopping") public class ShoppingController extends ControllerBase { + private static final PasswordEncoder PASSWORDENCODER = new BCryptPasswordEncoder(); + @Resource private IAppUserService appUserService; @@ -106,6 +124,9 @@ public class ShoppingController extends ControllerBase { @Resource private IQuotationModelForbidService forbidService; + @Resource + private StringRedisTemplate stringRedisTemplate; + /** * 购物车-获取报价对象 */ @@ -122,10 +143,13 @@ public class ShoppingController extends ControllerBase { .collect(Collectors.toList()) ); } else { - return ApiResult.success(List.of(new SimpleUserVO() - .setUserId(AppUserUtil.getUserId()) - .setUserName(AppUserUtil.getUserName()) + List appUsers = appUserService.getEndUsers(); + return ApiResult.success(appUsers.stream() + .map(appUser -> new SimpleUserVO() + .setUserId(appUser.getId()) + .setUserName(appUser.getName()) ) + .collect(Collectors.toList()) ); } } @@ -136,7 +160,7 @@ public class ShoppingController extends ControllerBase { @PostMapping("/cart/init") public ApiResult init(@Valid @RequestBody ShoppingInitRequest request) { Long categoryId = getCategoryId(); - VUtils.trueThrowBusinessError(forbidService.isForbid(request.getModelId(), 1,request.getTargetId())) + VUtils.trueThrowBusinessError(forbidService.isForbid(request.getModelId(), 1, request.getTargetId())) .throwMessage("该机型已禁售"); ModelPrice1VO modelPrice = priceService.getModelPrice(request.getModelId(), categoryId); VUtils.trueThrowBusinessError(Objects.isNull(modelPrice)).throwMessage("该机型尚未设置价格"); @@ -163,19 +187,21 @@ public class ShoppingController extends ControllerBase { Pair pair = getRatio(request.getModelId()); BigDecimal standardRatio = pair.getLeft(), optionalRatio = pair.getRight(); log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); - //方案 - QuotationUserPlanModelItem planModelItem = userPlanModelItemService.getEffectiveForUser(request.getModelId(), AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); - if (Objects.nonNull(planModelItem)) { - log.debug("机型【{}】方案为{},系数:{}", request.getModelNo(), planModelItem.getName(), planModelItem.getRatio()); - standardRatio = NumberUtil.multiply(standardRatio, planModelItem.getRatio()); - log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); - vo.setPlanItemId(planModelItem.getId()); - } else { - QuotationUserPlanDefault userPlanDefault = userPlanDefaultService.getEffectiveForUser(AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); - if (Objects.nonNull(userPlanDefault)) { - log.debug("用户方案默认系数为{}", userPlanDefault.getRatio()); - standardRatio = NumberUtil.multiply(standardRatio, userPlanDefault.getRatio()); + if (!request.getShowLowestPrice()) { + //方案 + QuotationUserPlanModelItem planModelItem = userPlanModelItemService.getEffectiveForUser(request.getModelId(), AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); + if (Objects.nonNull(planModelItem)) { + log.debug("机型【{}】方案为{},系数:{}", request.getModelNo(), planModelItem.getName(), planModelItem.getRatio()); + standardRatio = NumberUtil.multiply(standardRatio, planModelItem.getRatio()); log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); + vo.setPlanItemId(planModelItem.getId()); + } else { + QuotationUserPlanDefault userPlanDefault = userPlanDefaultService.getEffectiveForUser(AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); + if (Objects.nonNull(userPlanDefault)) { + log.debug("用户方案默认系数为{}", userPlanDefault.getRatio()); + standardRatio = NumberUtil.multiply(standardRatio, userPlanDefault.getRatio()); + log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); + } } } vo.setActualFee(vo.getTotalFee().subtract(vo.getDiscount()).multiply(standardRatio)); @@ -312,6 +338,19 @@ public class ShoppingController extends ControllerBase { return ApiResult.success(); } + /** + * 购物车-获取购物车数量 + */ + @GetMapping("/cart/count") + public ApiResult getCount() { + return ApiResult.success(shoppingCartService.lambdaQuery() + .eq(QuotationShoppingCart::getStatus, 0) + .eq(QuotationShoppingCart::getCreateByType, AppUserUtil.isAgent() ? 1 : 0) + .eq(QuotationShoppingCart::getCreateById, AppUserUtil.getUserId()) + .count() + ); + } + /** * 报价单-生成报价单 */ @@ -378,16 +417,19 @@ public class ShoppingController extends ControllerBase { request.setPage(page); request.setPageSize(pageSize); IPage datas = shoppingOrderService.search(request); - if(CollectionUtil.isEmpty(datas.getRecords())){ + if (CollectionUtil.isEmpty(datas.getRecords())) { return ApiResult.success(PageData.empty()); } boolean isAgent = AppUserUtil.isAgent(); List customers; + List endUsers; if (isAgent) { customers = customerService.lambdaQuery() .in(TBaseCustomer::getId, datas.getRecords().stream().map(QuotationSearchVO::getTargetId).collect(Collectors.toList())) .list(); + endUsers = null; } else { + endUsers = appUserService.getEndUsers(); customers = null; } return ApiResult.success(datas, data -> { @@ -400,7 +442,12 @@ public class ShoppingController extends ControllerBase { .orElse("") ); } else { - data.setTargetName(AppUserUtil.getUserName()); + data.setTargetName(endUsers.stream() + .filter(item -> item.getId().equals(data.getTargetId())) + .map(AppUser::getName) + .findFirst() + .orElse("") + ); } //TODO 设置汇率价格 return data; @@ -487,6 +534,142 @@ public class ShoppingController extends ControllerBase { return ApiResult.success(); } +// /** +// * 报价单-复制报价单 +// */ +// @PostMapping("/quotation/copy") +// public ApiResult copyQuotation(@Valid @RequestBody QuotationCopyRequest request){ +// QuotationShoppingOrder order = shoppingOrderService.getById(request.getId()); +// VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单"); +// List orderItems = shoppingOrderItemService.lambdaQuery() +// .eq(QuotationShoppingOrderItem::getOrderId, request.getId()) +// .list(); +// List carts = shoppingCartService.lambdaQuery() +// .in(QuotationShoppingCart::getId, orderItems.stream().map(QuotationShoppingOrderItem::getCartId).collect(Collectors.toList())) +// .list(); +// ShoppingCartVO vo = new ShoppingCartVO() +// .setModelId(request.getModelId()) +// .setTargetId(request.getTargetId()) +// .setCustomerName(request.getCustomerName()) +// .setPriceId(modelPrice.getPriceId()) +// .setConfigId(modelPrice.getConfigId()) +// .setTotalFee(modelPrice.getAmount()) +// .setActualFee(modelPrice.getAmount()); +// log.debug("机型【{}】售价为{}", request.getModelNo(), modelPrice); +// if (AppUserUtil.isAgent()) { +// //代理商 +// QuotationDiscountDTO discountDTO = discountService.getEffectiveForCustomer(request.getModelId(), request.getTargetId(), categoryId); +// if (Objects.nonNull(discountDTO)) { +// vo.setDiscountId(discountDTO.getDiscountId()); +// vo.setActualFee(vo.getTotalFee().multiply(discountDTO.getRatio())); +// vo.setDiscount(vo.getTotalFee().subtract(vo.getActualFee())); +// log.debug("机型【{}】打折后价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount()); +// } +// } +// //系数 +// Pair pair = getRatio(request.getModelId()); +// BigDecimal standardRatio = pair.getLeft(), optionalRatio = pair.getRight(); +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// if (!request.getShowLowestPrice()) { +// //方案 +// QuotationUserPlanModelItem planModelItem = userPlanModelItemService.getEffectiveForUser(request.getModelId(), AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); +// if (Objects.nonNull(planModelItem)) { +// log.debug("机型【{}】方案为{},系数:{}", request.getModelNo(), planModelItem.getName(), planModelItem.getRatio()); +// standardRatio = NumberUtil.multiply(standardRatio, planModelItem.getRatio()); +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// vo.setPlanItemId(planModelItem.getId()); +// } else { +// QuotationUserPlanDefault userPlanDefault = userPlanDefaultService.getEffectiveForUser(AppUserUtil.isAgent() ? 1 : 0, AppUserUtil.getUserId()); +// if (Objects.nonNull(userPlanDefault)) { +// log.debug("用户方案默认系数为{}", userPlanDefault.getRatio()); +// standardRatio = NumberUtil.multiply(standardRatio, userPlanDefault.getRatio()); +// log.debug("机型【{}】标准配件系数为{},可选配件系数为{}", request.getModelNo(), standardRatio, optionalRatio); +// } +// } +// } +// vo.setActualFee(vo.getTotalFee().subtract(vo.getDiscount()).multiply(standardRatio)); +// log.debug("机型【{}】价格为{},优惠{}", request.getModelNo(), vo.getActualFee(), vo.getDiscount()); +// //获取部件配置 +// List parts = modelConfigService.getEffectives(modelPrice.getPriceId(), categoryId, MultilingualUtil.getLanguage()); +// VUtils.trueThrowBusinessError(CollectionUtil.isEmpty(parts)).throwMessage("未获取到部件信息"); +// vo.setStandardParts(parts.stream() +// .filter(part -> part.getParentId() == 0L && part.getType() == 1) +// .map(part -> { +// ShoppingCartPartVO vi = convert(part, optionalRatio); +// vi.setChildren( +// parts.stream() +// .filter(pi -> pi.getParentId().equals(part.getId())) +// .map(pi -> convert(pi, optionalRatio)) +// .collect(Collectors.toList()) +// ); +// return vi; +// } +// ).collect(Collectors.toList()) +// ); +// vo.setOptionalParts(parts.stream() +// .filter(part -> part.getParentId() == 0L && part.getType() == 0) +// .map(part -> { +// ShoppingCartPartVO vi = convert(part, optionalRatio); +// vi.setChildren( +// parts.stream() +// .filter(pi -> pi.getParentId().equals(part.getId())) +// .map(pi -> convert(pi, optionalRatio)) +// .collect(Collectors.toList()) +// ); +// return vi; +// } +// ).collect(Collectors.toList()) +// ); +// vo.setStandardFee(vo.getActualFee()); +// return ApiResult.success(vo); +// carts.forEach(cart -> { +// QuotationShoppingOrderItem orderItem = orderItems.stream() +// .filter(item -> item.getCartId().equals(cart.getId())) +// .findFirst() +// .orElse(null); +// //获取部件配置 +// List parts = shoppingCartItemService.getSelectedParts(cart.getId(), MultilingualUtil.getLanguage()); +// +// +// cartVO.setStandardParts(parts.stream() +// .filter(part -> part.getParentId() == 0L && part.getType() == 1) +// .map(part -> { +// ShoppingCartPartVO vi = Convert.convert(ShoppingCartPartVO.class, part); +// vi.setAmount( +// vi.getAmount().add( +// parts.stream() +// .filter(pi -> pi.getParentId().equals(part.getId()) && pi.getType() == 0) +// .map(ModelConfigEffectiveDTO::getAmount) +// .reduce(BigDecimal::add) +// .orElse(BigDecimal.ZERO) +// ) +// ); +// return vi; +// } +// ).collect(Collectors.toList()) +// ); +// cartVO.setOptionalParts(parts.stream() +// .filter(part -> part.getParentId() == 0L && part.getType() == 0) +// .map(part -> { +// ShoppingCartPartVO vi = Convert.convert(ShoppingCartPartVO.class, part); +// vi.setAmount( +// vi.getAmount().add( +// parts.stream() +// .filter(pi -> pi.getParentId().equals(part.getId()) && pi.getType() == 0) +// .map(ModelConfigEffectiveDTO::getAmount) +// .reduce(BigDecimal::add) +// .orElse(BigDecimal.ZERO) +// ) +// ); +// return vi; +// } +// ).collect(Collectors.toList()) +// ); +// vo.getItems().add(cartVO); +// }); +// return ApiResult.success(vo); +// } + /** * 报价单-调价 */ @@ -522,25 +705,88 @@ public class ShoppingController extends ControllerBase { return ApiResult.success(); } + /** + * 报价单-导出PDF + */ + @GetMapping("/quotation/exportToPdf") + public void exportToPdf(HttpServletResponse response, @RequestParam @NotNull(message = "报价单id不能为空") Long id){ +// QuotationShoppingOrder order = shoppingOrderService.getById(id); +// VUtils.trueThrowBusinessError(Objects.isNull(order)).throwMessage("未找到报价单"); + Map order = new HashMap<>(); + order.put("no", "DFENNIKFWE562D"); + Map variables = new HashMap<>(); + variables.put("info", order); + // 渲染HTML + TemplateEngine templateEngine = new TemplateEngine(); + ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); + resolver.setPrefix("/templates/"); + resolver.setSuffix(".html"); + templateEngine.setTemplateResolver(resolver); + + Context context = new Context(); + context.setVariables(variables); + String html = templateEngine.process("pdf.html", context); + + response.setContentType(MediaType.APPLICATION_PDF_VALUE); + String encode = URLEncoder.encode("aaaa" + ".pdf", StandardCharsets.UTF_8); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=" + encode); + // 生成PDF + try { + ITextRenderer renderer = new ITextRenderer(); + renderer.getFontResolver().addFont("fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); + URL baseUrl = new ClassPathResource("templates/").getURL(); + renderer.setDocumentFromString(html,baseUrl.toString()); + renderer.layout(); + try (OutputStream outputStream = response.getOutputStream()) { + renderer.createPDF(outputStream); + } + } catch (Exception e) { + log.error("生成pdf出错", e); + throw new NflgException(STATE.BusinessError, "生成pdf出错"); + } + } + + /** + * 设置查看密码 + */ + @PostMapping("/setPassword") + public ApiResult setPassword(@RequestBody String password) { + stringRedisTemplate.opsForHash().put("quotation:password:", String.valueOf(AppUserUtil.getUserId()), PASSWORDENCODER.encode(password)); + return ApiResult.success(); + } + + /** + * 验证查看密码 + */ + @PostMapping("/validatePassword") + public ApiResult validatePassword(@RequestBody String password) { + Object pwd = stringRedisTemplate.opsForHash().get("quotation:password:", String.valueOf(AppUserUtil.getUserId())); + VUtils.trueThrowBusinessError(Objects.isNull(pwd)).throwMessage("还未设置过查看密码"); + if (!PASSWORDENCODER.matches(password, pwd.toString())) { + return ApiResult.error("查看密码不正确"); + } + return ApiResult.success(true); + } + private Pair getRatio(Long modelId) { Pair pair = Pair.of(BigDecimal.ONE, BigDecimal.ONE); if (AppUserUtil.isAgent()) { //代理商 if (AppUserUtil.isPrimary()) { //主账号 - QuotationModelRatioAgentItem pRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId,AppUserUtil.getUserId()); + QuotationModelRatioAgentItem pRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId, AppUserUtil.getUserId()); if (Objects.nonNull(pRatioAgentItem)) { pair = Pair.of(pRatioAgentItem.getStandardRatio(), pRatioAgentItem.getOptionalRatio()); } } else { //子账号 Integer parentUserId = appUserService.getPrimaryByChild(AppUserUtil.getUserId()); - QuotationModelRatioAgentItem pRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId,parentUserId); + QuotationModelRatioAgentItem pRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId, parentUserId); if (Objects.nonNull(pRatioAgentItem)) { pair = Pair.of(NumberUtil.multiply(pair.getLeft(), pRatioAgentItem.getStandardRatio()) , NumberUtil.multiply(pair.getRight(), pRatioAgentItem.getOptionalRatio())); } - QuotationModelRatioAgentItem cRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId,AppUserUtil.getUserId()); + QuotationModelRatioAgentItem cRatioAgentItem = ratioAgentItemService.getEffectiveForUser(modelId, AppUserUtil.getUserId()); if (Objects.nonNull(cRatioAgentItem)) { pair = Pair.of(NumberUtil.multiply(pair.getLeft(), cRatioAgentItem.getStandardRatio()) , NumberUtil.multiply(pair.getRight(), cRatioAgentItem.getOptionalRatio())); diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java new file mode 100644 index 00000000..9c2814af --- /dev/null +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/QuotationCopyRequest.java @@ -0,0 +1,28 @@ +package com.nflg.mobilebroken.quotation.pojo.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class QuotationCopyRequest { + + /** + * 报价ID + */ + @NotNull + private Long id; + + /** + * 客户名称 + */ + @NotBlank + private String customerName; + + /** + * 报价对象ID + */ + @NotNull + private Integer targetId; +} diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/ShoppingInitRequest.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/ShoppingInitRequest.java index 9e7d62ec..1964853b 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/ShoppingInitRequest.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/request/ShoppingInitRequest.java @@ -23,7 +23,6 @@ public class ShoppingInitRequest { /** * 客户名称 */ - @NotBlank private String customerName; /** @@ -31,4 +30,9 @@ public class ShoppingInitRequest { */ @NotNull private Integer targetId; + + /** + * 是否显示底价 + */ + private Boolean showLowestPrice = false; } diff --git a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/DiscountApplyForVO.java b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/DiscountApplyForVO.java index 9f675ae8..821711f9 100644 --- a/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/DiscountApplyForVO.java +++ b/nflg-mobilebroken-quotation/src/main/java/com/nflg/mobilebroken/quotation/pojo/vo/DiscountApplyForVO.java @@ -7,9 +7,23 @@ import lombok.experimental.Accessors; @Accessors(chain = true) public class DiscountApplyForVO { - private Integer id; + /** + * 用户ID + */ + private Integer sourceId; - private String agencyCompanyName; + /** + * 用户类型 0 终端用户;1 代理商公司 + */ + private Integer sourceType; + /** + * 名称 + */ + private String name; + + /** + * 区域名称 + */ private String areaName; } diff --git a/nflg-mobilebroken-quotation/src/main/resources/fonts/simsun.ttc b/nflg-mobilebroken-quotation/src/main/resources/fonts/simsun.ttc new file mode 100644 index 00000000..4cbcb711 Binary files /dev/null and b/nflg-mobilebroken-quotation/src/main/resources/fonts/simsun.ttc differ diff --git a/nflg-mobilebroken-quotation/src/main/resources/images/logo.png b/nflg-mobilebroken-quotation/src/main/resources/images/logo.png new file mode 100644 index 00000000..34ae65a8 Binary files /dev/null and b/nflg-mobilebroken-quotation/src/main/resources/images/logo.png differ diff --git a/nflg-mobilebroken-quotation/src/main/resources/templates/pdf.html b/nflg-mobilebroken-quotation/src/main/resources/templates/pdf.html new file mode 100644 index 00000000..0543c188 --- /dev/null +++ b/nflg-mobilebroken-quotation/src/main/resources/templates/pdf.html @@ -0,0 +1,116 @@ + + + + + + + + + +
+ +
+
+
+
+
CLOSE TO OUR CUSTOMERS
+
报价主体
+
+
+
报价人代码
+
报价人
+
报价人电话
+
报价人邮箱地址
+
报价日期
+
+
+
+ 报价有效期 + 报价有效期 +
+
+
+ 报价单号 + 报价单号 +
+
+ 总价 + 总价 +
+
+
包含下列费用
+
- 标准配置价格
+
- 选配价格
+
- 其他配置价格
+
- 附加服务费用
+
- 随机备件价格
+
- 运费
+
+
+ 付款方式 + 付款方式 +
+
+
机型
+ +
设备简介
+
+
+
配置详情
+
标准配置
+
AAA
+
+
 AAA
+
+
+
可选配置
+
AAA
+
+
 AAA
+
+
其他配置
+
油漆要求
+ +
+ + \ No newline at end of file diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/QuotationModelDiscountApply.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/QuotationModelDiscountApply.java index c8d558d3..13f74bb4 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/QuotationModelDiscountApply.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/QuotationModelDiscountApply.java @@ -37,7 +37,7 @@ public class QuotationModelDiscountApply implements Serializable { private Long discountId; /** - * 用户类型 0 内部用户;1 代理商公司 + * 用户类型 0 终端用户;1 代理商公司 */ private Integer sourceType; diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java index 95e02825..6e350d5a 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java @@ -85,4 +85,6 @@ public interface IAppUserService extends IService { DictionaryItem getCategory(AppUser cuser); List getCustomers(Integer userId); + + List getEndUsers(); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITBaseCustomerService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITBaseCustomerService.java index a7ca6b00..b33d1fb6 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITBaseCustomerService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITBaseCustomerService.java @@ -34,4 +34,6 @@ public interface ITBaseCustomerService extends IService { Collection getAreas(List companyIds); Collection getAreaIds(List companyIds); + + List getForQuotation(); } 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 197b3b15..820e4eb6 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 @@ -528,6 +528,14 @@ public class AppUserServiceImpl extends ServiceImpl impl .list(); } + @Override + public List getEndUsers() { + return lambdaQuery() + .eq(AppUser::getIsDel,0) + .eq(AppUser::getType,1) + .list(); + } + private void bindChildren1(AreaSimpleVO vo) { List datas = appAreaService.lambdaQuery().eq(AppArea::getParentId, vo.getId()).eq(AppArea::getEnable, true).list(); List vos = datas.stream().map(d -> new AreaSimpleVO().setId(d.getId()).setName(d.getName())).collect(Collectors.toList()); diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TBaseCustomerServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TBaseCustomerServiceImpl.java index a1909d4f..221532fe 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TBaseCustomerServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TBaseCustomerServiceImpl.java @@ -140,4 +140,13 @@ public class TBaseCustomerServiceImpl extends ServiceImpl getForQuotation() { + return lambdaQuery() + .eq(TBaseCustomer::getDelIs, 0) + .eq(TBaseCustomer::getEnableState, 1) + .eq(TBaseCustomer::getQuotationUse, true) + .list(); + } } diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/ProductModelMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/ProductModelMapper.xml index e718f699..ebe4bcd4 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/ProductModelMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/ProductModelMapper.xml @@ -115,7 +115,7 @@ diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/ProductTypeMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/ProductTypeMapper.xml index ff7937f3..d68d9cbc 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/ProductTypeMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/ProductTypeMapper.xml @@ -84,9 +84,9 @@ SELECT qupmi.id,qupmi.plan_id,pm.batch_number as 'modelId',pm.`no` as 'modelNo',qupmi.`name`,qupmi.ratio,qupmi.is_default - FROM product_model pm + FROM v_quotation_model_price vqmp + inner join product_model pm on vqmp.model_id=pm.batch_number LEFT JOIN quotation_user_plan_model_item qupmi ON qupmi.model_id=pm.batch_number left join quotation_user_plan_model qupm on qupmi.plan_id=qupm.id and qupm.`status`=1 and qupm.create_by_type=#{userType} and qupm.create_by_id=#{userId} WHERE pm.state=1