修复采购和集成酸轧细节

This commit is contained in:
2026-06-29 10:18:26 +08:00
parent 59dad19296
commit 8c7cce90ba
18 changed files with 326 additions and 482 deletions

View File

@@ -46,7 +46,7 @@
<span>{{ (Number(p.progress) || 0).toFixed(0) }}%<i v-if="p.planStatus === '1'" class="pp-arch">已归档</i></span>
</div>
</li>
<li v-if="!loading && !planList.length" class="pp-empty">暂无采购计划</li>
<li v-if="!loading && !planList.length" class="pp-empty">暂无采购合同</li>
</ul>
<pagination
v-show="total > 0"
@@ -63,13 +63,13 @@
<section class="pp-col pp-detail">
<div v-if="mode === 'empty'" class="pp-placeholder">
<i class="el-icon-tickets"></i>
<p>从左侧选择一条采购计划或点击新增按销售合同创建</p>
<p>从左侧选择一条采购合同或点击新增</p>
</div>
<!-- 编辑 / 新增 -->
<div v-else-if="mode === 'edit'" class="pp-edit">
<div class="pp-d-head">
<span class="pp-d-title">{{ form.planId ? '编辑采购计划' : '新增采购计划' }}</span>
<span class="pp-d-title">{{ form.planId ? '编辑采购合同' : '新增采购合同' }}</span>
<div>
<el-button size="small" @click="cancelEdit">取消</el-button>
<el-button size="small" type="primary" :loading="buttonLoading" @click="submitForm">保存</el-button>
@@ -78,12 +78,20 @@
<el-form :model="form" :rules="rules" ref="form" label-width="80px" class="pp-form" size="small">
<div class="pp-section">基本信息</div>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="计划号" prop="planNo">
<el-col :span="8">
<el-form-item label="出卖方" prop="supplier">
<div class="pp-inline-pick">
<el-input v-model="form.supplier" placeholder="选择供应商" />
<el-button icon="el-icon-search" @click="openSupplierPicker">选择</el-button>
</div>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="合同号" prop="planNo">
<el-input v-model="form.planNo" placeholder="留空自动生成" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="采购日期" prop="purchaseDate">
<el-date-picker v-model="form.purchaseDate" type="date" value-format="yyyy-MM-dd" style="width:100%" placeholder="选择日期" />
</el-form-item>
@@ -110,42 +118,28 @@
</div>
<div class="pp-section">
采购明细
采购要求
<el-button type="text" size="mini" icon="el-icon-plus" class="pp-section-act" @click="addItem">加行</el-button>
<el-button type="text" size="mini" icon="el-icon-magic-stick" class="pp-section-act" @click="openBatchFill">批量填充</el-button>
<span class="pp-section-hint" v-if="form.items.length"> {{ form.items.length }} · {{ itemsWeight }} T</span>
<span class="pp-section-hint" v-if="form.items.length"> {{ form.items.length }} · {{ itemsWeight }} T</span>
</div>
<el-table :data="form.items" border size="mini" max-height="300">
<el-table-column label="#" type="index" width="40" align="center" />
<el-table-column label="产品" min-width="70">
<template slot-scope="s"><el-input v-model="s.row.productType" size="mini" placeholder="热轧卷板" /></template>
<el-table :data="form.items" border size="mini" max-height="340">
<el-table-column label="#" type="index" width="44" align="center" />
<el-table-column label="规格" min-width="220">
<template slot-scope="s"><el-input v-model="s.row.spec" size="mini" placeholder="如 3.00×1230" /></template>
</el-table-column>
<el-table-column label="材质" min-width="80">
<template slot-scope="s"><el-input v-model="s.row.material" size="mini" /></template>
</el-table-column>
<el-table-column label="牌号" min-width="75">
<template slot-scope="s"><el-input v-model="s.row.grade" size="mini" /></template>
</el-table-column>
<el-table-column label="宽度" min-width="75">
<template slot-scope="s"><el-input v-model="s.row.width" size="mini" /></template>
</el-table-column>
<el-table-column label="厚度" min-width="75">
<template slot-scope="s"><el-input v-model="s.row.thickness" size="mini" /></template>
</el-table-column>
<el-table-column label="宽公差" min-width="75">
<template slot-scope="s"><el-input v-model="s.row.widthTolerance" size="mini" /></template>
</el-table-column>
<el-table-column label="厚公差" min-width="75">
<template slot-scope="s"><el-input v-model="s.row.thicknessTolerance" size="mini" /></template>
</el-table-column>
<el-table-column label="重量(T)" min-width="80">
<el-table-column label="总重量(T)" min-width="120">
<template slot-scope="s"><el-input v-model="s.row.weight" size="mini" /></template>
</el-table-column>
<el-table-column label="数量" min-width="65">
<template slot-scope="s"><el-input v-model="s.row.quantity" size="mini" /></template>
</el-table-column>
<el-table-column label="供货商" min-width="90">
<template slot-scope="s"><el-input v-model="s.row.supplier" size="mini" /></template>
<el-table-column label="厂商" min-width="200">
<template slot-scope="s">
<el-autocomplete
v-model="s.row.manufacturer"
:fetch-suggestions="queryManufacturer"
size="mini"
placeholder="手填厂商"
style="width:100%"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="64" align="center" fixed="right">
<template slot-scope="s">
@@ -153,7 +147,7 @@
<i class="el-icon-delete pp-del" title="删除" @click="removeItem(s.$index)" />
</template>
</el-table-column>
<template slot="empty"><span>加行添加或在上方选择销售合同载入明细</span></template>
<template slot="empty"><span>加行添加采购要求</span></template>
</el-table>
<el-form-item label="备注" prop="remark" style="margin-top:14px">
@@ -183,10 +177,10 @@
</div>
<div class="pp-meta">
<div class="pp-meta-i"><label>供货商</label><span>{{ current.supplier || '—' }}</span></div>
<div class="pp-meta-i"><label>出卖方</label><span>{{ current.supplier || '—' }}</span></div>
<div class="pp-meta-i"><label>采购日期</label><span>{{ current.purchaseDate || '—' }}</span></div>
<div class="pp-meta-i"><label>关联合同</label><span>{{ (current.contractCodes || []).join('、') || '—' }}</span></div>
<div class="pp-meta-i"><label>计划重量</label><span>{{ current.planWeight }} T</span></div>
<div class="pp-meta-i"><label>关联销售合同</label><span>{{ (current.contractCodes || []).join('、') || '—' }}</span></div>
<div class="pp-meta-i"><label>要求总重量</label><span>{{ current.planWeight }} T</span></div>
<div class="pp-meta-i"><label>已到货</label><span>{{ current.arrivedWeight }} T</span></div>
<div class="pp-meta-i wide">
<label>到货进度</label>
@@ -215,22 +209,14 @@
</div>
<el-tabs v-model="activeTab" class="pp-tabs">
<el-tab-pane label="采购明细" name="items">
<el-tab-pane label="采购要求" name="items">
<el-table :data="current.items" border size="mini" max-height="340">
<el-table-column label="#" type="index" width="40" align="center" />
<el-table-column label="产品" prop="productType" min-width="70" show-overflow-tooltip />
<el-table-column label="材质" prop="material" min-width="80" show-overflow-tooltip />
<el-table-column label="牌号" prop="grade" min-width="75" />
<el-table-column label="宽度" prop="width" min-width="70" />
<el-table-column label="厚度" prop="thickness" min-width="70" />
<el-table-column label="宽公差" prop="widthTolerance" min-width="72" />
<el-table-column label="厚公差" prop="thicknessTolerance" min-width="72" />
<el-table-column label="重量(T)" prop="weight" min-width="78" align="right" />
<el-table-column label="数量" prop="quantity" min-width="60" align="right" />
<el-table-column label="供货商" prop="supplier" min-width="90" show-overflow-tooltip />
<template slot="empty"><span>无明细</span></template>
<el-table-column label="#" type="index" width="44" align="center" />
<el-table-column label="规格" prop="spec" min-width="200" show-overflow-tooltip />
<el-table-column label="总重量(T)" prop="weight" min-width="110" align="right" />
<el-table-column label="厂商" prop="manufacturer" min-width="180" show-overflow-tooltip />
<template slot="empty"><span>无采购要求</span></template>
</el-table>
<p class="pp-deliv-hint" v-if="current.auditStatus === '1'">到货上传与卷号比对请到到货记录页面</p>
</el-tab-pane>
</el-tabs>
</div>
@@ -321,38 +307,6 @@
/>
</el-dialog>
<!-- 批量填充明细设一次一键填满所有行留空不覆盖 -->
<el-dialog title="批量填充明细" :visible.sync="batchFillOpen" width="560px" append-to-body>
<p class="pp-batch-tip">下面填了值的字段会写入<b>全部明细行</b>留空的不覆盖常用于整批同产品/材质/规格</p>
<el-form :model="batchFill" label-width="72px" size="small">
<el-row :gutter="14">
<el-col :span="12"><el-form-item label="产品"><el-input v-model="batchFill.productType" placeholder="如 热轧卷板" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="材质"><el-input v-model="batchFill.material" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="牌号"><el-input v-model="batchFill.grade" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="宽度"><el-input v-model="batchFill.width" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="厚度"><el-input v-model="batchFill.thickness" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="宽公差"><el-input v-model="batchFill.widthTolerance" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="厚公差"><el-input v-model="batchFill.thicknessTolerance" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="重量(T)"><el-input v-model="batchFill.weight" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="数量"><el-input v-model="batchFill.quantity" /></el-form-item></el-col>
<el-col :span="12">
<el-form-item label="供货商">
<div class="pp-inline-pick">
<el-input v-model="batchFill.supplier" placeholder="选择或输入" />
<el-button icon="el-icon-search" @click="openSupplierPicker">选择</el-button>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="pp-batch-footer">
<el-checkbox v-model="batchFillNewRow">设为加行默认值</el-checkbox>
<span class="pp-batch-gen">生成 <el-input v-model="batchRows" size="mini" style="width:64px" /> </span>
<el-button @click="batchFillOpen = false">取消</el-button>
<el-button @click="applyBatchFill">应用到现有行</el-button>
<el-button type="primary" @click="generateRows">生成行并填充</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -361,12 +315,12 @@ import {
listPurchasePlan,
purchasePlanStatistics,
getPurchasePlan,
getItemsByOrders,
addPurchasePlan,
updatePurchasePlan,
delPurchasePlan,
submitPurchasePlan,
listContracts
listContracts,
listManufacturers
} from '@/api/erp/purchasePlan'
import { listSupplier } from '@/api/erp/purchase'
@@ -383,16 +337,12 @@ export default {
current: {},
activeTab: 'items',
form: {},
rules: {},
rules: {
supplier: [{ required: true, message: '请选择出卖方', trigger: 'change' }]
},
buttonLoading: false,
submitLoading: false,
selectedContracts: [],
// 批量填充
batchFillOpen: false,
batchFillNewRow: true,
batchRows: 0,
batchFill: { productType: '热轧卷板', material: '', grade: '', width: '', thickness: '', widthTolerance: '', thicknessTolerance: '', weight: '', quantity: '', supplier: '' },
newRowDefaults: null,
// 合同选择器
pickerOpen: false,
pickerLoading: false,
@@ -450,9 +400,6 @@ export default {
resetForm() {
this.form = { planId: null, planNo: '', supplier: '', purchaseDate: '', remark: '', items: [], orderIds: [], contractCodes: [] }
this.selectedContracts = []
this.newRowDefaults = null
this.batchFill = { productType: '热轧卷板', material: '', grade: '', width: '', thickness: '', widthTolerance: '', thicknessTolerance: '', weight: '', quantity: '', supplier: '' }
this.batchRows = 0
},
handleAdd() {
this.resetForm()
@@ -514,12 +461,10 @@ export default {
this.form.orderIds = this.pickerSelection.map(c => c.orderId)
this.form.contractCodes = []
this.pickerOpen = false
this.deriveItems(this.form.orderIds)
},
removeContract(orderId) {
this.selectedContracts = this.selectedContracts.filter(c => c.orderId !== orderId)
this.form.orderIds = this.form.orderIds.filter(id => id !== orderId)
this.deriveItems(this.form.orderIds)
},
// ---- 供应商选择器 ----
openSupplierPicker() {
@@ -540,39 +485,23 @@ export default {
})
},
chooseSupplier(row) {
// 供应商选择器服务于「批量填充」对话框
this.batchFill.supplier = row.name
// 出卖方 = 供应商
this.form.supplier = row.name
this.supplierPickerOpen = false
},
deriveItems(orderIds) {
if (!orderIds || !orderIds.length) { this.form.items = []; return }
getItemsByOrders(orderIds).then(res => {
this.form.items = (res.data || []).map(it => ({
productType: it.productType || '热轧卷板',
material: it.material || '',
grade: it.grade || '',
width: it.width || '',
thickness: it.thickness || '',
widthTolerance: it.widthTolerance || '0',
thicknessTolerance: it.thicknessTolerance || '0',
weight: it.weight,
quantity: it.quantity,
supplier: this.form.supplier || ''
}))
this.$modal.msgSuccess(`已载入 ${this.form.items.length} 条明细,可继续编辑`)
})
queryManufacturer(queryString, cb) {
listManufacturers(queryString).then(res => {
cb((res.data || []).map(v => ({ value: v })))
}).catch(() => cb([]))
},
blankItem() {
return { productType: '热轧卷板', material: '', grade: '', width: '', thickness: '', widthTolerance: '0', thicknessTolerance: '0', weight: '', quantity: '', supplier: '' }
return { spec: '', weight: '', manufacturer: '' }
},
addItem() {
// 优先用批量默认值,其次继承上一行,最后空行;重量每行不同故清
// 新行继承上一行的厂商(同批多为同厂),规格/重量留
const last = this.form.items[this.form.items.length - 1]
let row
if (this.newRowDefaults) row = { ...this.newRowDefaults }
else if (last) row = { ...last }
else row = this.blankItem()
row.weight = ''
const row = this.blankItem()
if (last) row.manufacturer = last.manufacturer || ''
this.form.items.push(row)
},
copyItem(index) {
@@ -581,50 +510,10 @@ export default {
removeItem(index) {
this.form.items.splice(index, 1)
},
openBatchFill() {
this.batchFillOpen = true
},
batchFillKeys() {
const f = this.batchFill
const keys = ['productType', 'material', 'grade', 'width', 'thickness', 'widthTolerance', 'thicknessTolerance', 'weight', 'quantity', 'supplier']
return keys.filter(k => f[k] !== '' && f[k] != null)
},
applyBatchFill() {
const f = this.batchFill
const filled = this.batchFillKeys()
if (!filled.length) { this.$modal.msgWarning('请至少填写一个要填充的字段'); return }
if (!this.form.items.length) { this.$modal.msgWarning('当前没有明细行,请用右侧「生成行并填充」'); return }
this.form.items.forEach(it => { filled.forEach(k => { it[k] = f[k] }) })
if (f.supplier) this.form.supplier = f.supplier
this.saveNewRowDefaults(filled)
this.batchFillOpen = false
this.$modal.msgSuccess(`已填充 ${this.form.items.length}`)
},
generateRows() {
const n = parseInt(this.batchRows, 10) || 0
if (n <= 0) { this.$modal.msgWarning('请填写要生成的行数'); return }
const f = this.batchFill
const filled = this.batchFillKeys()
for (let i = 0; i < n; i++) {
const row = this.blankItem()
filled.forEach(k => { row[k] = f[k] })
this.form.items.push(row)
}
if (f.supplier) this.form.supplier = f.supplier
this.saveNewRowDefaults(filled)
this.batchFillOpen = false
this.$modal.msgSuccess(`已生成 ${n}`)
},
saveNewRowDefaults(filled) {
if (!this.batchFillNewRow) return
const def = this.blankItem()
filled.forEach(k => { def[k] = this.batchFill[k] })
this.newRowDefaults = def
},
submitForm() {
this.$refs['form'].validate(valid => {
if (!valid) return
if (!this.form.orderIds.length) { this.$modal.msgWarning('请先选择销售合同'); return }
if (!this.form.items.length) { this.$modal.msgWarning('请至少添加一条采购要求'); return }
this.buttonLoading = true
const api = this.form.planId ? updatePurchasePlan : addPurchasePlan
const editedId = this.form.planId
@@ -644,7 +533,7 @@ export default {
})
},
submitForAudit() {
const tip = this.current.auditStatus === '2' ? '确认重新送审该计划?将再次进入审核' : '确认送审该计划?送审后将出现在采购审核页'
const tip = this.current.auditStatus === '2' ? '确认重新送审该合同?将再次进入审核' : '确认送审该合同?送审后将出现在采购审核页'
this.$modal.confirm(tip).then(() => {
this.submitLoading = true
return submitPurchasePlan(this.current.planId)
@@ -655,7 +544,7 @@ export default {
}).catch(() => {}).finally(() => { this.submitLoading = false })
},
handleDelete(row) {
this.$modal.confirm('确认删除采购计划「' + row.planNo + '」?').then(() => {
this.$modal.confirm('确认删除采购合同「' + row.planNo + '」?').then(() => {
return delPurchasePlan(row.planId)
}).then(() => {
this.$modal.msgSuccess('删除成功')
@@ -666,9 +555,6 @@ export default {
},
auditText(s) {
return { '0': '待审核', '1': '已通过', '2': '已驳回', '3': '待送审' }[s] || '—'
},
itemStatusText(s) {
return s === '2' ? '已到货' : '未到货'
}
}
}