管理员审批时可看到完整的利润公式推导(销售价-成本-回扣-运费-税费-其他=利润) 以及每个产品的数量、售价、成本、销售金额明细表格,辅助审批决策。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
202 lines
7.9 KiB
JavaScript
202 lines
7.9 KiB
JavaScript
/**
|
||
* 审批详情页面
|
||
* 职责:展示订单完整信息(含报价明细和分层价格),支持审批通过/驳回操作。
|
||
*/
|
||
|
||
function mapOrderStatus(status) {
|
||
var app = getApp();
|
||
return app.mapOrderStatus(status);
|
||
}
|
||
|
||
function getStatusBadge(status) {
|
||
var map = {
|
||
pending_approve: "badge-orange", cancel_pending: "badge-orange",
|
||
approved: "badge-green", rejected: "badge-red",
|
||
pending_factory: "badge-blue", delivered: "badge-green", canceled: "badge-red",
|
||
};
|
||
return map[status] || "badge-gray";
|
||
}
|
||
|
||
Page({
|
||
data: {
|
||
statusBarHeight: 20,
|
||
taskId: null,
|
||
loading: true,
|
||
actionLoading: false,
|
||
message: "",
|
||
approveOpinion: "",
|
||
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) {
|
||
var app = getApp();
|
||
this.setData({
|
||
statusBarHeight: app.globalData.statusBarHeight || 20,
|
||
taskId: Number(options.id || 0),
|
||
});
|
||
await this.loadDetail();
|
||
},
|
||
|
||
async loadDetail() {
|
||
var app = getApp();
|
||
this.setData({ loading: true, message: "" });
|
||
try {
|
||
var data = await app.request({ url: "/api/orders/" + this.data.taskId, method: "GET" });
|
||
var sale = Number(data.sale_price_total || 0);
|
||
var cost = Number(data.cost_price_total || 0);
|
||
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) {
|
||
for (var j = 0; j < ci.surcharge_items.length; j++) {
|
||
surchargeItems.push({ key: ci.surcharge_items[j].key, name: ci.surcharge_items[j].name, amount: Number(ci.surcharge_items[j].amount || 0).toFixed(2) });
|
||
}
|
||
}
|
||
var totalSurcharge = 0;
|
||
for (var k = 0; k < surchargeItems.length; k++) { totalSurcharge += Number(surchargeItems[k].amount); }
|
||
var tierPrices = [];
|
||
if (data.sale_price_tier) {
|
||
var tierNames = { special: "特批价", tier1: "一级经销", tier2: "二级经销", default: "默认" };
|
||
var tierKeys = Object.keys(data.sale_price_tier);
|
||
for (var t = 0; t < tierKeys.length; t++) {
|
||
tierPrices.push({ code: tierKeys[t], name: tierNames[tierKeys[t]] || tierKeys[t], price: Number(data.sale_price_tier[tierKeys[t]] || 0).toFixed(2) });
|
||
}
|
||
}
|
||
pricingItems.push({
|
||
product_name: ci.product_name, pricing_type: ci.pricing_type,
|
||
length_m: ci.length_m, width_m: ci.width_m,
|
||
area_sqm: ci.area_sqm ? Number(ci.area_sqm).toFixed(4) : null,
|
||
baseCost: Number(ci.cost_amount || 0).toFixed(2),
|
||
surchargeItems: surchargeItems, totalSurcharge: totalSurcharge.toFixed(2),
|
||
costPrice: (Number(ci.cost_amount || 0) + totalSurcharge).toFixed(2),
|
||
formula_detail: ci.pricing_type ? ci.product_name + " " + (ci.length_m ? ci.length_m + "m × " + ci.width_m + "m" : "") + " 成本¥" + Number(ci.cost_amount || 0).toFixed(2) : "",
|
||
tierPrices: tierPrices,
|
||
});
|
||
}
|
||
|
||
this.setData({
|
||
orderInfo: Object.assign({}, data, {
|
||
statusText: mapOrderStatus(data.order_status), badgeClass: getStatusBadge(data.order_status),
|
||
salePriceTotalText: sale.toFixed(2), costPriceTotalText: cost.toFixed(2),
|
||
rebateTotalText: Number(data.rebate_total || 0).toFixed(2),
|
||
freightTotalText: Number(data.freight_total || 0).toFixed(2),
|
||
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 || "加载失败" });
|
||
} finally {
|
||
this.setData({ loading: false });
|
||
}
|
||
},
|
||
|
||
handleOpinionInput: function (event) {
|
||
this.setData({ approveOpinion: event.detail.value });
|
||
},
|
||
|
||
handleApprove: function (event) {
|
||
var that = this;
|
||
var result = event.currentTarget.dataset.result;
|
||
var orderInfo = this.data.orderInfo;
|
||
if (!orderInfo) return;
|
||
var isCancelFlow = ["cancel_pending", "cancel_fulfillment_pending"].indexOf(orderInfo.order_status) >= 0;
|
||
var targetUrl = isCancelFlow
|
||
? "/api/orders/" + orderInfo.order_id + "/cancel-approve"
|
||
: "/api/orders/" + orderInfo.order_id + "/approve";
|
||
var confirmMsg = result === "pass"
|
||
? (isCancelFlow ? "确认同意取消此订单?" : "确认审批通过?")
|
||
: (isCancelFlow ? "确认驳回取消申请?" : "确认退回此订单?");
|
||
|
||
wx.showModal({
|
||
title: "确认操作",
|
||
content: confirmMsg,
|
||
confirmColor: result === "pass" ? "#2563eb" : "#be123c",
|
||
success: function (res) {
|
||
if (!res.confirm) return;
|
||
var app = getApp();
|
||
that.setData({ actionLoading: true, message: "" });
|
||
var opinion = that.data.approveOpinion || (result === "pass" ? "同意" : "退回");
|
||
app.request({
|
||
url: targetUrl, method: "POST",
|
||
data: { approve_result: result, approve_opinion: opinion },
|
||
}).then(function () {
|
||
wx.showToast({ title: result === "pass" ? "审批通过" : "已退回", icon: "success" });
|
||
return that.loadDetail();
|
||
}).catch(function (error) {
|
||
that.setData({ message: error.message || "操作失败" });
|
||
}).finally(function () {
|
||
that.setData({ actionLoading: false });
|
||
});
|
||
},
|
||
});
|
||
},
|
||
|
||
handleBack: function () { wx.navigateBack({ delta: 1 }); },
|
||
|
||
handlePreviewAttachment: function (event) {
|
||
var url = event.currentTarget.dataset.url;
|
||
var urls = this.data.orderAttachments.map(function (a) { return a.file_url; });
|
||
wx.previewImage({ current: url, urls: urls });
|
||
},
|
||
});
|