fix: 优化定价管理页面标签清晰度和修复产品选项显示

- 修复产品下拉选项 /undefined 问题:展平 specifications 嵌套结构
- 页面标题"定价规则管理"→"产品定价管理",副标题更直白
- "基准售价"→"售价(元/单位)",去掉"基准"修饰
- "计价类型"→"计费方式","计价单位"→"单价单位"
- "公式说明"→"价格说明","含税方式"→"是否含税"
- 同步更新帮助弹窗、表格表头、操作按钮、确认弹窗中的所有文案

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
taiyi 2026-06-04 17:58:31 +08:00
parent 9c34cc3745
commit 4ed74dccb0

View File

@ -1,15 +1,15 @@
<!--
PricingRulesPage.vue - 定价规则管理页面
职责管理产品的定价公式供应商成本和价格层级
列表模式展示所有定价规则编辑/新增模式下可配置计价类型基准售价
PricingRulesPage.vue - 产品定价管理页面
职责管理产品的售价供应商成本和价格层级
列表模式展示所有定价规则编辑/新增模式下可配置计费方式售价
公式表达式供应商成本明细和价格层级支持 CRUD 操作
-->
<template>
<section class="page pricing-page">
<div class="page-header">
<div>
<h2>定价规则管理</h2>
<p class="subline">管理产品的定价公式供应商成本和价格层级配置后业务员下单时自动报价</p>
<h2>产品定价管理</h2>
<p class="subline">配置产品的售价和计费方式配置后业务员下单时自动计算报价</p>
</div>
<button class="help-btn" @click="showHelp = !showHelp" :class="{ active: showHelp }">?</button>
</div>
@ -28,15 +28,15 @@
</div>
<div class="help-section">
<h4>如何新增一条定价规则</h4>
<h4>如何新增一条定价</h4>
<ol>
<li>点击<strong>"新增定价规则"</strong>按钮</li>
<li>点击<strong>"新增定价"</strong>按钮</li>
<li><strong>选择产品</strong>从下拉框选择要定价的产品</li>
<li><strong>价类型</strong>选择按面积()按公斤(kg)或按件 选好后系统自动填好公式和单位</li>
<li><strong>基准售价</strong>填写每单位的对外销售价格//kg </li>
<li><strong>费方式</strong>选择按面积()按公斤(kg)或按件 选好后系统自动填好公式和单位</li>
<li><strong>售价/单位</strong>填写每单位的对外销售价格//kg </li>
<li>如有附加费包边印刷等在下方<strong>"附加费用"</strong>区点 + 添加</li>
<li>下方绿色<strong>预览卡片</strong>会实时显示业务员看到的效果</li>
<li>点击<strong>"保存定价规则"</strong>完成</li>
<li>点击<strong>"保存定价"</strong>完成</li>
</ol>
</div>
@ -46,10 +46,10 @@
<thead><tr><th>字段</th><th>说明</th><th>示例</th></tr></thead>
<tbody>
<tr><td>选择产品</td><td>要定价的产品选好后自动填充产品名称</td><td>高温布-9018AJ</td></tr>
<tr><td>价类型</td><td>决定按什么维度计算价格选好后自动填好公式</td><td>按面积() 适合板材布料</td></tr>
<tr><td>基准售价</td><td>每单位的对外销售价格系统用这个乘以用量得出客户报价</td><td>28 表示对客户报 28 /</td></tr>
<tr><td>价单位</td><td>配合计价类型使用切换类型时自动更新</td><td>kg</td></tr>
<tr><td>公式说明</td><td>显示给业务员看的计算说明文字切换类型时自动生成</td><td>××单价</td></tr>
<tr><td>费方式</td><td>决定按什么维度计算价格选好后自动填好公式</td><td>按面积() 适合板材布料</td></tr>
<tr><td>售价/单位</td><td>每单位的对外销售价格系统用这个乘以用量得出客户报价</td><td>28 表示对客户报 28 /</td></tr>
<tr><td>价单位</td><td>配合计费方式使用切换计费方式时自动更新</td><td>kg</td></tr>
<tr><td>价格说明</td><td>显示给业务员看的计算说明文字切换计费方式时自动生成</td><td>××单价</td></tr>
<tr><td>状态</td><td>启用=正常显示可用停用=隐藏不出现在选择列表</td><td>一般选"启用"</td></tr>
</tbody>
</table>
@ -62,16 +62,16 @@
<thead><tr><th>页面显示</th><th>英文字段名</th><th>含义</th></tr></thead>
<tbody>
<tr><td>产品名称</td><td><code>product_name</code></td><td>关联的产品</td></tr>
<tr><td>价类型</td><td><code>pricing_type</code></td><td>area=按面积, kg=按公斤, unit=按件</td></tr>
<tr><td>基准售价</td><td><code>base_unit_price</code></td><td>每单位的对外销售基础价格</td></tr>
<tr><td>价单位</td><td><code>pricing_unit</code></td><td>kg</td></tr>
<tr><td>费方式</td><td><code>pricing_type</code></td><td>area=按面积, kg=按公斤, unit=按件</td></tr>
<tr><td>售价/单位</td><td><code>base_unit_price</code></td><td>每单位的对外销售价格</td></tr>
<tr><td>价单位</td><td><code>pricing_unit</code></td><td>kg</td></tr>
<tr><td>公式表达式</td><td><code>formula_expr</code></td><td>计算公式自动填好</td></tr>
<tr><td>公式常量</td><td><code>formula_constants</code></td><td>公式中用到的固定数值JSON</td></tr>
<tr><td>输入字段配置</td><td><code>pricing_inputs</code></td><td>业务员下单时的输入项JSON</td></tr>
<tr><td>附加费配置</td><td><code>surcharge_json</code></td><td>可选附加费JSON由附加费行自动生成</td></tr>
<tr><td>公式说明</td><td><code>formula_note</code></td><td>显示给业务员的说明文字</td></tr>
<tr><td>价格说明</td><td><code>formula_note</code></td><td>显示给业务员的说明文字</td></tr>
<tr><td>税率</td><td><code>tax_rate</code></td><td>税率百分比0=不收税</td></tr>
<tr><td>含税方式</td><td><code>tax_inclusive</code></td><td>0=不含税正算, 1=含税反算</td></tr>
<tr><td>是否含税</td><td><code>tax_inclusive</code></td><td>0=不含税正算, 1=含税反算</td></tr>
<tr><td>状态</td><td><code>status</code></td><td>1=启用, 0=停用</td></tr>
</tbody>
</table>
@ -98,8 +98,8 @@
<thead><tr><th>字段</th><th>说明</th><th>需要改吗</th></tr></thead>
<tbody>
<tr><td>税率(%)</td><td>如需含税报价填写税率百分比</td><td>需要才填</td></tr>
<tr><td>含税方式</td><td>不含税=正算基础+含税=反算总价反推不含税价</td><td>一般选"不含税"</td></tr>
<tr><td>公式表达式</td><td>系统根据计价类型自动生成的计算公式</td><td>不需要改</td></tr>
<tr><td>是否含税</td><td>不含税=正算+含税=反算总价反推不含税价</td><td>一般选"不含税"</td></tr>
<tr><td>公式表达式</td><td>系统根据计费方式自动生成的计算公式</td><td>不需要改</td></tr>
<tr><td>公式常量</td><td>公式中用到的固定数值JSON格式</td><td>不需要改</td></tr>
<tr><td>输入字段配置</td><td>定义业务员下单时需要填写哪些参数</td><td>不需要改</td></tr>
</tbody>
@ -113,7 +113,7 @@
<div class="help-section">
<h4>供应商成本是什么</h4>
<p>保存定价规则页面下方会出现<strong>"供应商成本"</strong>区域在这里记录不同供应商给你的进货价系统会自动对比成本和售价帮你算利润</p>
<p>保存定价页面下方会出现<strong>"供应商成本"</strong>区域在这里记录不同供应商给你的进货价系统会自动对比成本和售价帮你算利润</p>
<ul>
<li><strong>供应商ID</strong>对应系统中供应商的编号</li>
<li><strong>采购单价</strong>你从这个供应商拿货的单价</li>
@ -136,7 +136,7 @@
<h4>常见问题</h4>
<ul>
<li><strong>Q: 新增后列表里看不到</strong><br>A: 确认状态选的是"启用"并点击了"查询"刷新列表</li>
<li><strong>Q: 切换计价类型后之前的单价被覆盖了</strong><br>A: 切换类型会自动更新公式和单位<strong>不会清空单价</strong>需要手动填新的单</li>
<li><strong>Q: 切换计费方式后之前的单价被覆盖了</strong><br>A: 切换计费方式会自动更新公式和单位<strong>不会清空售价</strong>需要手动填新的售</li>
<li><strong>Q: 附加费填错了</strong><br>A: 直接改对应的行或点"删除"去掉不需要的行保存时会自动同步</li>
<li><strong>Q: 高级设置里的公式被改坏了</strong><br>A: 删除这条规则重新创建公式会自动生成或者手动恢复为<code>round($input.length_m * $input.width_m * $rule.base_unit_price, 2)</code></li>
<li><strong>Q: 删错了怎么办</strong><br>A: 点击"删除"是软删除可恢复如果确认不要了再点"永久删除"</li>
@ -147,20 +147,20 @@
</div>
<section class="panel" v-if="!editMode">
<div class="panel-header">
<h3>定价规则列表</h3>
<button class="primary-btn" @click="openCreateRule">新增定价规则</button>
<h3>产品定价列表</h3>
<button class="primary-btn" @click="openCreateRule">新增定价</button>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>产品名称</th>
<th>价类型</th>
<th>基准售价</th>
<th>价单位</th>
<th>费方式</th>
<th>售价</th>
<th>价单位</th>
<th>税率</th>
<th>含税方式</th>
<th>公式说明</th>
<th>是否含税</th>
<th>价格说明</th>
<th>状态</th>
<th>操作</th>
</tr>
@ -180,16 +180,16 @@
<button class="link-btn danger" @click="handleDeleteRule(rule)">删除</button>
</td>
</tr>
<tr v-if="!rules.length"><td colspan="9" class="empty-cell">暂无定价规则</td></tr>
<tr v-if="!rules.length"><td colspan="9" class="empty-cell">暂无定价数据</td></tr>
</tbody>
</table>
</div>
</section>
<!-- 编辑/新增定价规则 -->
<!-- 编辑/新增定价 -->
<section v-if="editMode" class="panel">
<div class="panel-header">
<h3>{{ editingRule.id ? '编辑' : '新增' }}定价规则</h3>
<h3>{{ editingRule.id ? '编辑' : '新增' }}定价</h3>
<button class="ghost-btn" @click="cancelEdit">返回列表</button>
</div>
@ -208,7 +208,7 @@
<input v-model="editingRule.product_name" type="text" placeholder="自动填充或手动输入" />
</label>
<label>
<span>价类型 <em class="required">*</em></span>
<span>费方式 <em class="required">*</em></span>
<select v-model="editingRule.pricing_type" @change="onPricingTypeChange">
<option value="area">按面积()</option>
<option value="kg">按公斤(kg)</option>
@ -216,11 +216,11 @@
</select>
</label>
<label>
<span>基准售价() <em class="required">*</em></span>
<span>售价/单位 <em class="required">*</em></span>
<input v-model.number="editingRule.base_unit_price" type="number" min="0" step="0.01" :placeholder="pricingUnitHint" />
</label>
<label>
<span>价单位</span>
<span>价单位</span>
<select v-model="editingRule.pricing_unit">
<option value="㎡"></option>
<option value="kg">kg</option>
@ -236,7 +236,7 @@
</select>
</label>
<label>
<span>公式说明给业务员看</span>
<span>价格说明给业务员看</span>
<input v-model="editingRule.formula_note" type="text" :placeholder="formulaNoteHint" />
</label>
</div>
@ -266,7 +266,7 @@
<input v-model.number="editingRule.tax_rate" type="number" min="0" max="100" step="0.01" placeholder="如 13 表示 13%" />
</label>
<label>
<span>默认含税方式</span>
<span>是否含税</span>
<select v-model.number="editingRule.tax_inclusive">
<option :value="0">不含税正算</option>
<option :value="1">含税反算</option>
@ -309,7 +309,7 @@
<div class="action-row">
<button class="ghost-btn" @click="cancelEdit">取消</button>
<button class="primary-btn" :disabled="saving" @click="handleSaveRule">{{ saving ? '保存中...' : '保存定价规则' }}</button>
<button class="primary-btn" :disabled="saving" @click="handleSaveRule">{{ saving ? '保存中...' : '保存定价' }}</button>
</div>
<!-- 供应商成本管理 -->
@ -568,10 +568,13 @@ async function loadProductOptions() {
try {
const data = await apiRequest("/api/products?page_size=200");
const list = data.list || [];
productOptions.value = list.map(p => ({
value: p.product_id, label: `${p.product_name} / ${p.specification}`,
product_name: p.product_name,
}));
productOptions.value = list.flatMap(p =>
(p.specifications || []).map(spec => ({
value: spec.product_id,
label: `${p.product_name} / ${spec.specification}`,
product_name: p.product_name,
})),
);
} catch (e) { /* ignore */ }
}
@ -612,7 +615,7 @@ async function handleSaveRule() {
}
async function handleDeleteRule(rule) {
if (!confirm(`确认删除「${rule.product_name}」的定价规则`)) return;
if (!confirm(`确认删除「${rule.product_name}」的定价`)) return;
try {
await apiRequest(`/api/pricing-rules/${rule.id}`, { method: "DELETE" });
toast.success("删除成功");