feat(project): 更新产品列表页面折扣文案及计算逻辑- 将"利润折扣"统一修改为"商务折扣"

- 修改"终端产品"为"硬件产品"- 优化总价计算逻辑,区分软件、硬件、服务分类小计
- 添加各分类折后小计金额显示-修复金额格式化方法调用问题
- 完善审批流程中商务角色处理逻辑- 增加CSS邮件列表参数支持
-优化库存状态设置逻辑,避免重复赋值
-修复发货数量校验逻辑问题
dev_1.0.0
chenhao 2025-10-15 15:16:40 +08:00
parent 6185245482
commit 1f578c5b8f
6 changed files with 85 additions and 33 deletions

View File

@ -483,12 +483,13 @@
// return
// }
} else {
// arrays= productSnData.map(item => item.productSn)
// if (productSnData.length != quantity) {
// $.modal.msgError(`产品选中数量应与发货数量一致,应发货数量为[${quantity}]`)
// return
// }
}
if (arrays.length<=0){
if (productSnData.length <= 0 && arrays.length <= 0) {
$.modal.msgError(`应发货数量应该大于0`)
return
}
@ -498,7 +499,7 @@
productSnList: arrays,
logisticsCode: $('#logisticsCode').val(),
productCode: productCode,
quantity: arrays.length,
quantity: productSnData.length <= 0 ? arrays.length : productSnData.length,
warehouseId: warehouseId,
logisticsCompany: $('#logisticsCompany').val(),
deliveryType: $('#deliveryType').val(),

View File

@ -25,7 +25,7 @@
<th style="min-width: 90px;width: 90px;max-width: 90px;" class="guidance-discount-column">指导折扣</th>
<th style="min-width: 94px;width: 94px;max-width: 94px;" class="discount-column">折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="price-column">单价(¥)</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >利润折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >商务折扣</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="all-price-column">总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="all-price-discount-column hide-column">折后总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="catalogue-all-price-column">目录总价(¥)</th>
@ -39,7 +39,7 @@
</table>
</div>
<div class="add-btn-div">
<h2>终端产品</h2>
<h2>硬件产品</h2>
<button type="button" class="add-btn" onclick="addProduct2({})">添加</button>
</div>
<div class="table-responsive">
@ -55,7 +55,7 @@
<th style="min-width: 90px;width: 90px;max-width: 90px;" class="guidance-discount-column">指导折扣</th>
<th style="min-width: 94px;width: 94px;max-width: 94px;" class="discount-column">折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="price-column">单价(¥)</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >利润折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >商务折扣</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="all-price-column">总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="all-price-discount-column hide-column">折后总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="catalogue-all-price-column">目录总价(¥)</th>
@ -85,7 +85,7 @@
<th style="min-width: 90px;width: 90px;max-width: 90px;" class="guidance-discount-column">指导折扣</th>
<th style="min-width: 94px;width: 94px;max-width: 94px;" class="discount-column">折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="price-column">单价(¥)</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >利润折扣</th>
<th style="min-width: 100px;width: 100px;max-width: 100px;" class="discount-column-zd hide-column discount-text" >商务折扣</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class=" all-price-column">总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="all-price-discount-column hide-column">折后总价(¥)</th>
<th style="min-width: 120px;width: 120px;max-width: 120px;" class="catalogue-all-price-column">目录总价(¥)</th>
@ -106,7 +106,7 @@
</style>
<!-- JS 函数引用或内联 -->
<script th:inline="javascript"> /*<![CDATA[*/
let canUpdateFlag=[[${canUpdate}]]
let canUpdateFlag=[[${canUpdate}]];
let calcFlag = false;
const updatePriceProductList=['8813A3YA','8813A3YB','8813A7U4','8813A7U2']
const quantityStep = ['3130A4TE']
@ -120,7 +120,7 @@
},{
name:'hardwareProjectProductInfoList',
type:'2',
title:'终端产品'
title:'硬件产品'
},{
name:'maintenanceProjectProductInfoList',
type:'11,22,99',
@ -192,7 +192,7 @@
if (actualPurchaseAmount.length>0 && !actualPurchaseAmount.val()){
let allPriceDiscount = preciseCurrencyRound(Number(discountFoldValue)*Number(allPrice));
actualPurchaseAmount.val(allPriceDiscount)
$('#displayactualPurchaseAmount').val(formatAmountNumber(allPriceDiscount))
$('#displayactualPurchaseAmount')?.val(formatAmountNumber(allPriceDiscount))
}
calculateAndDistributeCataloguePrice()
}
@ -203,24 +203,29 @@
}
let allPrice=0.00;
let allPriceDiscount=0.00;
$('.all-price-discount-column').find('.allPrice-discount').each(function (index) {
allPriceDiscount+=parseFloat($(this).val())
})
$('#productTable tbody').find('tr').find('.allPrice').each(function (index) {
// $('.all-price-discount-column').find('.allPrice-discount').each(function (index) {
// allPriceDiscount+=parseFloat($(this).val())
// })
$('.all-price-column').find('.allPrice').each(function (index) {
allPrice+=parseFloat($(this).val())
})
let softwarePrice=formatAmountNumber(allPrice);
let softwarePrice=0.00;
$('#productTable tbody').find('tr').find('.allPrice-discount').each(function (index) {
allPriceDiscount+=parseFloat($(this).val())
softwarePrice+=parseFloat($(this).val())
})
softwarePrice=formatAmountNumber(softwarePrice);
let softwareHtml=$( `<span class="total-price" style="
font-size: 20px;
font-weight: bold;
display: flex;
flex-direction: row;
justify-content: flex-end;
"><span style="padding-right: 10px">配置组小计</span> ${softwarePrice}</span>`)
"><span style="padding-right: 10px">软件折后小计</span> <span id="software-total-price">${softwarePrice}</span> </span>`)
$('#productTable').after(softwareHtml);
let hardwarePrice=0.00;
$('#productTable2 tbody').find('tr').find('.allPrice').each(function (index) {
allPrice+=parseFloat($(this).val())
$('#productTable2 tbody').find('tr').find('.allPrice-discount').each(function (index) {
allPriceDiscount+=parseFloat($(this).val())
hardwarePrice+=parseFloat($(this).val())
})
hardwarePrice=formatAmountNumber(hardwarePrice);
@ -230,12 +235,12 @@
display: flex;
flex-direction: row;
justify-content: flex-end;
"><span style="padding-right: 10px">配置组小计</span> ${hardwarePrice}</span>`)
"><span style="padding-right: 10px">硬件折后小计</span> <span id="hardware-total-price">${hardwarePrice}</span> </span>`)
$('#productTable2').after(hardwareHtml);
let maintenancePrice=0.00;
$('#productTable3 tbody').find('tr').find('.allPrice').each(function (index) {
allPrice+=parseFloat($(this).val())
$('#productTable3 tbody').find('tr').find('.allPrice-discount').each(function (index) {
allPriceDiscount+=parseFloat($(this).val())
maintenancePrice+=parseFloat($(this).val())
})
maintenancePrice=formatAmountNumber(maintenancePrice);
@ -245,7 +250,7 @@
display: flex;
flex-direction: row;
justify-content: flex-end;
"><span style="padding-right: 10px">配置组小计</span> ${maintenancePrice}</span>`)
"><span style="padding-right: 10px">服务折后小计</span> <span id="maintenance-total-price"> ${maintenancePrice}</span></span>`)
$('#productTable3').after(maintenanceHtml);
allPrice = formatAmountNumber(allPrice);
allPriceDiscount=formatAmountNumber(allPriceDiscount);
@ -259,7 +264,7 @@
background: #d7d7d7;
flex-direction: row;
justify-content: flex-end;
"><span style="padding-right: 10px">配置组总计</span> <span id="allPriceTotal"> ${allPrice}</span> </span>
"><span style="padding-right: 10px">价合</span> <span id="allPriceTotal"> ${allPrice}</span> </span>
<div class="total-price discount-all" style="
font-size: 20px;
font-weight: bold;
@ -268,28 +273,48 @@
border: 1px solid;
flex-direction: row;
justify-content: flex-end;
"><div style="width: 65svw;display: flex;justify-content: center;"><span ><span class="discount-text">利润折扣</span>,折扣<span id="allPriceCountValueSpan"></span>
"><div style="width: 65svw;display: flex;justify-content: center;"><span ><span class="discount-text">商务折扣</span>,折扣<span id="allPriceCountValueSpan"></span>
<select id="allPriceCountValue" onchange="changeAllPriceCount(${id})" >
<option value="1" ${(!discountFold || discountFold===1)?'selected':''} >100%</option>
<option value="0.988" ${discountFold===0.988?'selected':''} >98.8%</option>
<option value="0.985" ${discountFold===0.985?'selected':''} >98.5%</option>
</select>
</span> </div> <span style="border-left: 1px solid;padding-left: 100px;">折后总价<span id="allPriceCount" style="padding-left: 10px"> ${allPriceDiscount}</span></span></div>`)
</span> </div> <span style="border-left: 1px solid;padding-left: 100px;">折后总价合计<span id="allPriceCount" style="padding-left: 10px"> ${allPriceDiscount}</span></span></div>`)
$('.layui-tab').after(allPriceHtml);
}
function changeAllPriceCount(id) {
let discountFold = $('#allPriceCountValue').val();
let allPriceDiscount=0.00;
let softwarePrice=0.00;
let hardwarePrice=0.00;
let maintenancePrice=0.00;
$('.price-column').find('.price').each(function (index) {
let price = $(this).val();
let quantity = $(this)?.parent()?.parent()?.find('.quantity')?.val();
let discountPrice =preciseCurrencyRound( preciseCurrencyRound(price*discountFold)*quantity);
debugger
let parentTable = $(this)?.parents('table').first();
let attr = $(parentTable).attr("id");
if (attr==='productTable'){
softwarePrice+=discountPrice
}else if (attr==='productTable2'){
hardwarePrice+=discountPrice
}else if (attr==='productTable3'){
maintenancePrice+=discountPrice
}
$(this)?.parent()?.parent()?.find('.allPrice-discount').val(discountPrice)
$(this)?.parent()?.parent()?.find('.allPrice-discount-format').val(formatAmountNumber(discountPrice))
allPriceDiscount+=parseFloat(discountPrice)
// allPriceDiscount+=parseFloat($(this).val())
})
$('#software-total-price').text(formatAmountNumber(softwarePrice))
$('#hardware-total-price').text(formatAmountNumber(hardwarePrice))
$('#maintenance-total-price').text(formatAmountNumber(maintenancePrice))
$('#allPriceCount').text(formatAmountNumber(allPriceDiscount))
$('#displayactualPurchaseAmount')?.val(formatAmountNumber(allPriceDiscount))
$('#actualPurchaseAmount')?.val(allPriceDiscount)

View File

@ -825,7 +825,8 @@
}
let actualPurchaseAmount = [[${projectOrderInfo.actualPurchaseAmount}]] || ''
if (actualPurchaseAmount) {
document.getElementById('displayactualPurchaseAmount').value=actualPurchaseAmount.toLocaleString('en-US');
$('#displayactualPurchaseAmount')?.val(formatAmountNumber(actualPurchaseAmount))
// document.getElementById('displayactualPurchaseAmount')?.value=actualPurchaseAmount.toLocaleString('en-US');
}
// initProductList()

View File

@ -1,6 +1,8 @@
package com.ruoyi.framework.web.exception;
import javax.servlet.http.HttpServletRequest;
import com.ruoyi.common.utils.html.HTMLFilter;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -112,7 +112,9 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
item.setInnerCode(omsInventoryInner.getInnerCode());
item.setCreateBy(currentUserId);
item.setCreateTime(nowDate);
item.setInventoryStatus(InventoryInfo.InventoryStatusEnum.INNER.getCode());
if (StringUtils.isEmpty(item.getInventoryStatus())) {
item.setInventoryStatus(InventoryInfo.InventoryStatusEnum.INNER.getCode());
}
});
//校验sn是否重复
List<String> repeatSnList = inventoryInfoService.checkUnq(inventoryInfoList.stream().map(InventoryInfo::getProductSn).collect(Collectors.toList()));

View File

@ -1099,7 +1099,9 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
} else if (approveBtn.equals(1)) {
// 审批通过处理
if ("产品经理".equals(taskName)) {
handleProductManagerApproval(businessKey);
// handleProductManagerApproval(businessKey);
} else if (taskName.startsWith("商务")) {
handleBusinessApproval(businessKey);
}
}
@ -1141,7 +1143,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
private void handleProductManagerApproval(String businessKey) {
ProjectOrderInfo dbProjectOrderInfo = projectOrderInfoMapper.selectProjectOrderInfoByCode(businessKey);
// 查询商务和代理商邮箱
// 查询商务邮箱
List<String> emailList = new ArrayList<>();
// 查询商务邮箱
@ -1151,17 +1153,36 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toList()));
// 发送邮件
this.sendPartnerMail(emailList.stream().distinct().collect(Collectors.toList()), dbProjectOrderInfo,Collections.emptyList());
}
private void handleBusinessApproval(String businessKey) {
ProjectOrderInfo dbProjectOrderInfo = projectOrderInfoMapper.selectProjectOrderInfoByCode(businessKey);
// 查询代理商邮箱
if (StringUtils.isNotEmpty(dbProjectOrderInfo.getPartnerEmail())) {
List<String> emailList = new ArrayList<>();
if (ProjectOrderInfo.OrderChannelEnum.DIRECT_SIGNING.getCode().equals(dbProjectOrderInfo.getOrderChannel()) && StringUtils.isNotEmpty(dbProjectOrderInfo.getPartnerEmail())) {
//直签并且填写了代理商邮箱
emailList.add(dbProjectOrderInfo.getPartnerEmail());
} else {
//根据代理商编码查询 总代查总代 直签查直签
List<String> orderCodeList = getPartnerCodeByProcessTemplate(dbProjectOrderInfo);
List<PartnerInfo> partnerInfos = partnerInfoService.selectPartnerInfoByCode(orderCodeList);
emailList.addAll(partnerInfos.stream().map(PartnerInfo::getContactEmail).filter(StringUtils::isNotEmpty).collect(Collectors.toList()));
}
// 发送邮件
this.sendPartnerMail(emailList.stream().distinct().collect(Collectors.toList()), dbProjectOrderInfo);
List<String> cssMailList = new ArrayList<>(CSS_EMAIL_LIST);
//查询商务邮件
List<SysUser> sysUsers = userService.listByRoleId(businessRoleId);
cssMailList.addAll(sysUsers.stream()
.map(SysUser::getEmail)
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toList()));
this.sendPartnerMail(emailList.stream().distinct().collect(Collectors.toList()), dbProjectOrderInfo,cssMailList);
}
/**
@ -1202,7 +1223,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
return null;
}
public void sendPartnerMail(List<String> toEmail, ProjectOrderInfo projectOrderInfo){
public void sendPartnerMail(List<String> toEmail, ProjectOrderInfo projectOrderInfo,List<String> toCssEmail){
if (CollUtil.isEmpty(toEmail)){
log.info("发货邮件发送失败,收件人为空");
return;
@ -1217,7 +1238,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create());
}else{
TemplateMailUtil.sendTemplateMail(toEmail,title,
TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create(),CSS_EMAIL_LIST);
TemplateMailUtil.MailTemplate.ORDER_PARTNER,Dict.create(),toCssEmail);
}
}