Compare commits

...

4 Commits

Author SHA1 Message Date
30d3104e76 Merge branch 'claude/charming-goldwasser-e6834c' 2026-06-06 19:06:31 +08:00
81e01eb113 fix: 审批详情利润计算和订单明细 text 改 view,修复 flex 布局值不显示
微信小程序中 <text> 是内联元素,在 flex 容器中无法正确作为 flex-item
分配宽度,导致右侧金额值被挤压不可见。改为 <view> 后布局正常。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 19:06:07 +08:00
33af235582 Merge branch 'claude/charming-goldwasser-e6834c' 2026-06-06 19:02:45 +08:00
20b3486512 feat: 小程序审批详情页增加利润计算过程和订单明细
管理员审批时可看到完整的利润公式推导(销售价-成本-回扣-运费-税费-其他=利润)
以及每个产品的数量、售价、成本、销售金额明细表格,辅助审批决策。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 18:43:52 +08:00
3 changed files with 146 additions and 0 deletions

View File

@ -28,6 +28,20 @@ Page({
orderInfo: null,
pricingItems: [],
orderAttachments: [],
// 利润计算过程
calcFormula: "",
calcRateFormula: "",
calcSaleTotal: "0.00",
calcCostTotal: "0.00",
calcRebateTotal: "0.00",
calcFreightTotal: "0.00",
calcTaxTotal: "0.00",
calcTaxDesc: "",
calcOtherFeeTotal: "0.00",
calcProfitTotal: "0.00",
calcProfitRate: "0.00",
// 订单明细行
orderItems: [],
},
async onLoad(options) {
@ -49,11 +63,33 @@ Page({
var profit = Number(data.profit_total || 0);
var profitRate = sale > 0 ? (profit / sale * 100).toFixed(1) + "%" : "-";
// 解析利润计算明细
var calcDetail = data.calculation_detail || {};
var calcItems = calcDetail.item_details || [];
// 计算过程汇总
var calcTaxDesc = "";
if (calcDetail.tax_detail) {
calcTaxDesc = calcDetail.tax_detail.desc || "";
}
// 报价明细(仅含 pricing_type 的行)
var pricingItems = [];
// 订单产品明细(所有行)
var orderItems = [];
for (var i = 0; i < calcItems.length; i++) {
var ci = calcItems[i];
// 订单明细:所有行都加入
orderItems.push({
product_name: ci.product_name,
quantity: Number(ci.quantity || 0),
sale_price: Number(ci.sale_price || 0).toFixed(2),
cost_price: Number(ci.cost_price || 0).toFixed(2),
sale_amount: Number(ci.sale_amount || 0).toFixed(2),
cost_amount: Number(ci.cost_amount || 0).toFixed(2),
tax_amount: Number(ci.tax_amount || 0).toFixed(2),
});
// 报价明细:仅有 pricing_type 的行
if (!ci.pricing_type) continue;
var surchargeItems = [];
if (ci.surcharge_items) {
@ -92,7 +128,20 @@ Page({
profitTotalText: profit.toFixed(2), profitRate: profitRate,
}),
pricingItems: pricingItems,
orderItems: orderItems,
orderAttachments: (data.attachments || []).filter(function (a) { return a.biz_type === "sales_order"; }),
// 利润计算过程
calcFormula: calcDetail.formula || "",
calcRateFormula: calcDetail.rate_formula || "",
calcSaleTotal: Number(calcDetail.sale_total || 0).toFixed(2),
calcCostTotal: Number(calcDetail.cost_total || 0).toFixed(2),
calcRebateTotal: Number(calcDetail.rebate_total || 0).toFixed(2),
calcFreightTotal: Number(calcDetail.freight_total || 0).toFixed(2),
calcTaxTotal: Number(calcDetail.tax_total || 0).toFixed(2),
calcTaxDesc: calcTaxDesc,
calcOtherFeeTotal: Number(calcDetail.other_fee_total || 0).toFixed(2),
calcProfitTotal: Number(calcDetail.profit_total || 0).toFixed(2),
calcProfitRate: Number(calcDetail.profit_rate || 0).toFixed(1),
});
} catch (error) {
this.setData({ message: error.message || "加载失败" });

View File

@ -89,6 +89,73 @@
</view>
</view>
<!-- 利润计算过程 -->
<view class="card calc-card">
<view class="section-title">利润计算</view>
<view wx:if="{{calcFormula}}" class="calc-formula">{{calcFormula}}</view>
<view wx:if="{{calcRateFormula}}" class="calc-formula calc-rate-formula">{{calcRateFormula}}</view>
<view class="calc-steps">
<view class="calc-step-row">
<view class="calc-step-label">销售价合计</view>
<view class="calc-step-value">¥{{calcSaleTotal}}</view>
</view>
<view class="calc-step-row calc-step-minus">
<view class="calc-step-label">- 成本价合计</view>
<view class="calc-step-value">¥{{calcCostTotal}}</view>
</view>
<view class="calc-step-row calc-step-minus">
<view class="calc-step-label">- 回扣合计</view>
<view class="calc-step-value">¥{{calcRebateTotal}}</view>
</view>
<view class="calc-step-row calc-step-minus">
<view class="calc-step-label">- 运费合计</view>
<view class="calc-step-value">¥{{calcFreightTotal}}</view>
</view>
<view class="calc-step-row calc-step-minus">
<view class="calc-step-label">- 税费合计</view>
<view class="calc-step-value">¥{{calcTaxTotal}}</view>
</view>
<view wx:if="{{calcTaxDesc}}" class="calc-tax-note">{{calcTaxDesc}}</view>
<view class="calc-step-row calc-step-minus">
<view class="calc-step-label">- 其他费用合计</view>
<view class="calc-step-value">¥{{calcOtherFeeTotal}}</view>
</view>
<view class="calc-step-row calc-step-result">
<view class="calc-step-label">= 利润</view>
<view class="calc-step-value">¥{{calcProfitTotal}}</view>
</view>
<view class="calc-step-row calc-step-rate">
<view class="calc-step-label">利润率</view>
<view class="calc-step-value">{{calcProfitRate}}%</view>
</view>
</view>
</view>
<!-- 订单明细 -->
<view wx:if="{{orderItems.length}}" class="card order-items-card">
<view class="section-title">订单明细</view>
<view class="order-items-scroll">
<view class="order-items-table">
<view class="order-items-header">
<view class="oi-col oi-product">产品</view>
<view class="oi-col oi-num">数量</view>
<view class="oi-col oi-num">售价</view>
<view class="oi-col oi-num">成本</view>
<view class="oi-col oi-num">销售金额</view>
<view class="oi-col oi-num">成本金额</view>
</view>
<view wx:for="{{orderItems}}" wx:key="index" class="order-items-row">
<view class="oi-col oi-product">{{item.product_name}}</view>
<view class="oi-col oi-num">{{item.quantity}}</view>
<view class="oi-col oi-num">¥{{item.sale_price}}</view>
<view class="oi-col oi-num">¥{{item.cost_price}}</view>
<view class="oi-col oi-num">¥{{item.sale_amount}}</view>
<view class="oi-col oi-num">¥{{item.cost_amount}}</view>
</view>
</view>
</view>
</view>
<view wx:if="{{orderAttachments.length}}" class="card attachment-card">
<view class="section-title">订单附件</view>
<view class="attachment-grid">

View File

@ -187,6 +187,36 @@
.tier-row { display: flex; flex-wrap: wrap; gap: 10rpx; margin-top: 10rpx; }
.tier-chip { background: #eff6ff; color: #1d4ed8; font-size: 20rpx; padding: 4rpx 14rpx; border-radius: 999rpx; font-weight: 600; }
/* 利润计算过程卡片 */
.calc-card { padding: 24rpx; }
.calc-formula { font-size: 22rpx; color: #6b7280; margin-bottom: 6rpx; }
.calc-rate-formula { margin-bottom: 16rpx; }
.calc-steps { background: #f0fdf4; border-radius: 14rpx; padding: 16rpx; }
.calc-step-row { display: flex; justify-content: space-between; padding: 8rpx 0; font-size: 26rpx; }
.calc-step-label { color: #374151; }
.calc-step-value { font-weight: 600; color: #0f172a; }
.calc-step-minus .calc-step-label { color: #64748b; }
.calc-step-minus .calc-step-value { color: #64748b; }
.calc-step-result { border-top: 2rpx solid #bbf7d0; padding-top: 12rpx; margin-top: 8rpx; }
.calc-step-result .calc-step-label { font-weight: 700; color: #059669; }
.calc-step-result .calc-step-value { font-weight: 800; color: #059669; font-size: 30rpx; }
.calc-step-rate { padding-top: 4rpx; }
.calc-step-rate .calc-step-label { color: #059669; font-weight: 600; }
.calc-step-rate .calc-step-value { color: #059669; font-weight: 700; }
.calc-tax-note { font-size: 20rpx; color: #94a3b8; padding: 2rpx 0 2rpx 16rpx; }
/* 订单明细卡片 */
.order-items-card { padding: 24rpx; }
.order-items-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.order-items-table { min-width: 900rpx; }
.order-items-header { display: flex; background: #f1f5f9; border-radius: 10rpx; padding: 14rpx 0; }
.order-items-header .oi-col { font-size: 22rpx; font-weight: 700; color: #475569; }
.order-items-row { display: flex; padding: 14rpx 0; border-bottom: 1rpx solid #f1f5f9; }
.order-items-row:last-child { border-bottom: none; }
.oi-col { padding: 0 8rpx; font-size: 24rpx; color: #334155; display: flex; align-items: center; }
.oi-product { flex: 3; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oi-num { flex: 2; text-align: right; justify-content: flex-end; }
/* 订单附件 */
.attachment-card { padding: 24rpx; }
.attachment-grid { display: flex; flex-wrap: wrap; gap: 16rpx; }