feat(bid): 优化报价单页面并新增RFQ详情路由
1. 合并规格和型号列为规格型号字段,简化表单布局 2. 调整表格列宽适配页面显示,新增表格横向滚动容器 3. 更新PDF导出表格表头与表单对齐 4. 新增/bid/rfq/detail路由用于跳转RFQ详情页 5. 修正物料数据同步逻辑,统一规格型号赋值
This commit is contained in:
@@ -125,6 +125,20 @@ export const dynamicRoutes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/bid/rfq/detail',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
permissions: ['bid:rfq:query'],
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/bid/rfq/detail'),
|
||||
name: 'RfqDetail',
|
||||
meta: { title: '报价请求详情', activeMenu: '/bid/rfq' }
|
||||
}
|
||||
]
|
||||
},
|
||||
// ── 统计分析 路由 ──
|
||||
{
|
||||
path: '/bid/report/dashboard',
|
||||
|
||||
@@ -70,9 +70,10 @@
|
||||
<span><strong>报价明细</strong></span>
|
||||
<el-button style="float:right" type="primary" size="mini" icon="el-icon-plus" @click="addItem">添加行</el-button>
|
||||
</div>
|
||||
<div class="table-scroll-wrap">
|
||||
<el-table :data="form.items" border size="small">
|
||||
<el-table-column type="index" width="46" label="#" />
|
||||
<el-table-column label="物料名称" min-width="200">
|
||||
<el-table-column label="物料名称" width="200">
|
||||
<template slot-scope="s">
|
||||
<el-autocomplete
|
||||
v-model="s.row.materialName"
|
||||
@@ -104,57 +105,53 @@
|
||||
</el-autocomplete>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" width="120">
|
||||
<el-table-column label="规格型号" width="150">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.spec" size="mini" placeholder="规格" />
|
||||
<el-input v-model="s.row.spec" size="mini" placeholder="规格型号" @change="s.row.modelNo = s.row.spec" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="型号" width="120">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.modelNo" size="mini" placeholder="型号" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" width="70">
|
||||
<el-table-column label="单位" width="60">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.unit" size="mini" placeholder="单位" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" width="130">
|
||||
<el-table-column label="数量" width="80">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.quantity" :min="0" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价(元)" width="140">
|
||||
<el-table-column label="成本价(元)" width="100">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.costPrice" :min="0" :precision="2" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报价(元)" width="140">
|
||||
<el-table-column label="报价(元)" width="100">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.unitPrice" :min="0" :precision="2" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额(元)" width="120" align="right">
|
||||
<el-table-column label="金额(元)" width="100" align="right">
|
||||
<template slot-scope="s">
|
||||
<strong style="color:#409EFF">¥{{ s.row.totalPrice || '0.00' }}</strong>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="毛利率" width="80" align="center">
|
||||
<el-table-column label="毛利率" width="70" align="center">
|
||||
<template slot-scope="s">
|
||||
<span :style="{ color: marginColor(s.row) }">{{ calcMargin(s.row) }}%</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交货期(天)" width="90">
|
||||
<el-table-column label="交货期(天)" width="70">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.deliveryDays" :min="0" size="mini" controls-position="right" style="width:100%" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="60" align="center">
|
||||
<el-table-column label="操作" width="50" align="center">
|
||||
<template slot-scope="s">
|
||||
<el-button type="text" icon="el-icon-delete" style="color:#f56c6c" @click="removeItem(s.$index)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="total-bar">
|
||||
<span>合计:</span>
|
||||
@@ -193,14 +190,13 @@
|
||||
<div class="pdf-section-title">报价明细</div>
|
||||
<table class="pdf-items-table">
|
||||
<thead>
|
||||
<tr><th>#</th><th>物料名称</th><th>规格</th><th>型号</th><th>单位</th><th>数量</th><th>单价(元)</th><th>金额(元)</th><th>交货期(天)</th></tr>
|
||||
<tr><th>#</th><th>物料名称</th><th>规格型号</th><th>单位</th><th>数量</th><th>单价(元)</th><th>金额(元)</th><th>交货期(天)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(it, ii) in form.items" :key="ii">
|
||||
<td>{{ ii + 1 }}</td>
|
||||
<td>{{ it.materialName }}</td>
|
||||
<td>{{ it.spec || '-' }}</td>
|
||||
<td>{{ it.modelNo || '-' }}</td>
|
||||
<td>{{ it.unit }}</td>
|
||||
<td>{{ it.quantity }}</td>
|
||||
<td>{{ it.unitPrice }}</td>
|
||||
@@ -210,7 +206,7 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="7" style="text-align:right;font-weight:bold;padding:10px 8px">合计金额</td>
|
||||
<td colspan="6" style="text-align:right;font-weight:bold;padding:10px 8px">合计金额</td>
|
||||
<td class="amount-cell total-cell" colspan="2">¥{{ grandTotal }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
@@ -310,7 +306,7 @@ export default {
|
||||
row.materialId = item.materialId;
|
||||
row.materialName = item.materialName;
|
||||
row.spec = item.spec || '';
|
||||
row.modelNo = item.modelNo || item.spec || '';
|
||||
row.modelNo = item.spec || '';
|
||||
row.unit = item.unit || '件';
|
||||
},
|
||||
onMaterialChange(row) {
|
||||
@@ -383,14 +379,18 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cq-detail { padding-bottom: 40px; }
|
||||
.page-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:20px; padding:16px 0; border-bottom:1px solid #f0f2f5; flex-wrap:wrap; gap:10px; }
|
||||
.cq-detail { overflow: hidden; padding-bottom: 40px; }
|
||||
.page-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:20px; padding:16px 0; border-bottom:1px solid #f0f2f5; flex-wrap:wrap; gap:10px; overflow:hidden; }
|
||||
.page-header-left { display:flex; align-items:center; gap:12px; }
|
||||
.page-header-right { display:flex; gap:10px; }
|
||||
.page-title { font-size:18px; font-weight:700; color:#1a2c4e; }
|
||||
.info-card ::v-deep .el-card__body { padding: 20px; }
|
||||
.total-bar { display:flex; align-items:center; justify-content:flex-end; padding:16px 20px; border-top:1px solid #f0f2f5; background:#fafbfc; }
|
||||
|
||||
/* 表格滚动容器 - 窄屏时横向滚动 */
|
||||
.table-scroll-wrap { overflow-x: auto; }
|
||||
.table-scroll-wrap >>> .el-table { min-width: 900px; }
|
||||
|
||||
/* 物料搜索建议下拉 */
|
||||
/* 物料搜索下拉样式 - 加宽并优化展示 */
|
||||
>>> .el-autocomplete-suggestion {
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
<div class="items-table-wrap">
|
||||
<el-table :data="form.items" border size="small" class="items-table">
|
||||
<el-table-column type="index" width="44" label="#" />
|
||||
<el-table-column label="物料名称" min-width="200">
|
||||
<el-table-column label="物料名称" width="200">
|
||||
<template slot-scope="s">
|
||||
<el-autocomplete
|
||||
v-model="s.row.materialName"
|
||||
@@ -191,52 +191,47 @@
|
||||
</el-autocomplete>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格" width="120">
|
||||
<el-table-column label="规格型号" width="150">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.spec" size="mini" placeholder="规格" />
|
||||
<el-input v-model="s.row.spec" size="mini" placeholder="规格型号" @change="s.row.modelNo = s.row.spec" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="型号" width="120">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.modelNo" size="mini" placeholder="型号" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" width="70">
|
||||
<el-table-column label="单位" width="60">
|
||||
<template slot-scope="s">
|
||||
<el-input v-model="s.row.unit" size="mini" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" width="130">
|
||||
<el-table-column label="数量" width="80">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.quantity" :min="0" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价(元)" width="140">
|
||||
<el-table-column label="成本价(元)" width="100">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.costPrice" :min="0" :precision="2" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="报价(元)" width="140">
|
||||
<el-table-column label="报价(元)" width="100">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.unitPrice" :min="0" :precision="2" size="mini" controls-position="right" style="width:100%" @change="calcRow(s.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额(元)" width="120" align="right">
|
||||
<el-table-column label="金额(元)" width="100" align="right">
|
||||
<template slot-scope="s">
|
||||
<strong style="color:#409EFF">¥{{ itemTotal(s.row) }}</strong>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="毛利率" width="80" align="center">
|
||||
<el-table-column label="毛利率" width="70" align="center">
|
||||
<template slot-scope="s">
|
||||
<span :style="{ color: marginColor(s.row) }">{{ calcMargin(s.row) }}%</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交期(天)" width="100">
|
||||
<el-table-column label="交期(天)" width="70">
|
||||
<template slot-scope="s">
|
||||
<el-input-number v-model="s.row.deliveryDays" :min="0" size="mini" controls-position="right" style="width:100%" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="60" align="center" fixed="right">
|
||||
<el-table-column label="操作" width="50" align="center">
|
||||
<template slot-scope="s">
|
||||
<el-button type="text" icon="el-icon-delete" style="color:#f56c6c" @click="form.items.splice(s.$index, 1)" />
|
||||
</template>
|
||||
@@ -300,21 +295,20 @@
|
||||
<div class="section-title">报价明细</div>
|
||||
<el-table :data="detailData.items || []" border size="small" style="margin-top:12px">
|
||||
<el-table-column type="index" width="46" label="#" />
|
||||
<el-table-column label="物料名称" prop="materialName" min-width="140" />
|
||||
<el-table-column label="规格" prop="spec" width="110" />
|
||||
<el-table-column label="型号" prop="modelNo" width="100" />
|
||||
<el-table-column label="单位" prop="unit" width="60" align="center" />
|
||||
<el-table-column label="数量" prop="quantity" width="80" align="right" />
|
||||
<el-table-column label="成本价" width="100" align="right">
|
||||
<el-table-column label="物料名称" prop="materialName" min-width="150" />
|
||||
<el-table-column label="规格型号" prop="spec" width="130" />
|
||||
<el-table-column label="单位" prop="unit" width="55" align="center" />
|
||||
<el-table-column label="数量" prop="quantity" width="70" align="right" />
|
||||
<el-table-column label="成本价" width="90" align="right">
|
||||
<template slot-scope="s">¥{{ s.row.costPrice | money }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" width="110" align="right">
|
||||
<el-table-column label="单价" width="90" align="right">
|
||||
<template slot-scope="s">¥{{ s.row.unitPrice | money }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" width="110" align="right">
|
||||
<el-table-column label="金额" width="90" align="right">
|
||||
<template slot-scope="s"><strong style="color:#409EFF">¥{{ s.row.totalPrice | money }}</strong></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交期(天)" prop="deliveryDays" width="80" align="center" />
|
||||
<el-table-column label="交期(天)" prop="deliveryDays" width="65" align="center" />
|
||||
</el-table>
|
||||
|
||||
<!-- ── 关联的RFQ列表 ── -->
|
||||
@@ -525,7 +519,7 @@ export default {
|
||||
}).then(res => {
|
||||
this.detailOpen = false;
|
||||
this.$modal.msgSuccess("RFQ已创建");
|
||||
this.$router.push({ path: '/bid/rfq', query: { rfqId: res.data.rfqId, rfqNo: res.data.rfqNo, action: 'edit' } });
|
||||
this.$router.push({ path: '/bid/rfq/detail', query: { rfqId: res.data.rfqId, rfqNo: res.data.rfqNo, edit: '1' } });
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
@@ -545,7 +539,7 @@ export default {
|
||||
},
|
||||
viewRfqDetail(rfq) {
|
||||
this.detailOpen = false;
|
||||
this.$router.push({ path: '/bid/rfq', query: { rfqId: rfq.rfqId, rfqNo: rfq.rfqNo, action: 'edit' } });
|
||||
this.$router.push({ path: '/bid/rfq/detail', query: { rfqId: rfq.rfqId } });
|
||||
},
|
||||
rfqStatusType(s) { return { draft:"info", published:"warning", closed:"", completed:"success" }[s] || ""; },
|
||||
rfqStatusLabel(s) { return { draft:"草稿", published:"已发布", closed:"已关闭", completed:"已完成" }[s] || s; },
|
||||
@@ -568,7 +562,7 @@ export default {
|
||||
row.materialId = item.materialId;
|
||||
row.materialName = item.materialName;
|
||||
row.spec = item.spec || '';
|
||||
row.modelNo = item.modelNo || item.spec || '';
|
||||
row.modelNo = item.spec || '';
|
||||
row.unit = item.unit || '件';
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user