提交基础采购
This commit is contained in:
201
klp-ui/src/views/erp/requirement/index.vue
Normal file
201
klp-ui/src/views/erp/requirement/index.vue
Normal file
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<div class="erp-requirement-page">
|
||||
<el-card shadow="never" class="panel-card">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>采购需求分析</span>
|
||||
<div class="panel-actions">
|
||||
<el-switch v-model="persistResult" active-text="写入建议表" inactive-text="仅计算" />
|
||||
<el-button type="primary" size="mini" @click="handleAnalyze" :loading="loading">执行分析</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="mappingRows" border size="small" class="mapping-table">
|
||||
<el-table-column label="产品ID" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productId" placeholder="产品ID" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原料ID" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rawMaterialId" placeholder="原料ID" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="转换率" width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-input-number v-model="scope.row.conversionRate" :min="0" :max="1" :step="0.01" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="removeMapping(scope.$index)" :disabled="mappingRows.length === 1">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button icon="el-icon-plus" size="mini" class="add-btn" @click="addMapping">新增映射</el-button>
|
||||
|
||||
<el-table
|
||||
:data="resultList"
|
||||
border
|
||||
size="small"
|
||||
v-loading="loading"
|
||||
show-summary
|
||||
:summary-method="summaryMethod"
|
||||
>
|
||||
<el-table-column label="产品" width="220">
|
||||
<template slot-scope="scope">
|
||||
<div class="title">{{ scope.row.productName || '-' }}</div>
|
||||
<div class="cell-sub">ID: {{ scope.row.productId || '-' }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="specification" label="规格" width="160" />
|
||||
<el-table-column prop="salesDemand" label="销售需求(吨)" width="140" />
|
||||
<el-table-column prop="productStockWeight" label="成品库存(吨)" width="140" />
|
||||
<el-table-column prop="rawStockConverted" label="原料折算(吨)" width="140" />
|
||||
<el-table-column prop="inTransitConverted" label="在途折算(吨)" width="140" />
|
||||
<el-table-column prop="pendingConverted" label="待下达折算(吨)" width="140" />
|
||||
<el-table-column prop="suggestedPurchase" label="建议采购(吨)" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span :class="scope.row.suggestedPurchase > 0 ? 'highlight' : ''">
|
||||
{{ scope.row.suggestedPurchase }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="panel-card">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>原料折算详情</span>
|
||||
</div>
|
||||
<el-table :data="rawDetailData" size="small" border height="320">
|
||||
<el-table-column prop="productName" label="产品" width="200" />
|
||||
<el-table-column prop="rawMaterialName" label="原料" width="200" />
|
||||
<el-table-column prop="conversionRate" label="转换率" width="120" />
|
||||
<el-table-column prop="stockWeight" label="库存重量" width="120" />
|
||||
<el-table-column prop="stockCoilCount" label="库存卷数" width="120" />
|
||||
<el-table-column prop="convertedStock" label="折算库存" width="120" />
|
||||
<el-table-column prop="convertedInTransit" label="折算在途" width="120" />
|
||||
<el-table-column prop="convertedPending" label="折算待下达" width="120" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { analyzePurchaseRequirement } from '@/api/erp/purchase'
|
||||
|
||||
export default {
|
||||
name: 'ErpPurchaseRequirement',
|
||||
data() {
|
||||
return {
|
||||
mappingRows: [{ productId: '', rawMaterialId: '', conversionRate: 1 }],
|
||||
persistResult: false,
|
||||
loading: false,
|
||||
resultList: [],
|
||||
rawDetailData: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addMapping() {
|
||||
this.mappingRows.push({ productId: '', rawMaterialId: '', conversionRate: 1 })
|
||||
},
|
||||
removeMapping(idx) {
|
||||
if (this.mappingRows.length === 1) return
|
||||
this.mappingRows.splice(idx, 1)
|
||||
},
|
||||
handleAnalyze() {
|
||||
if (!this.mappingRows.every(row => row.productId && row.rawMaterialId)) {
|
||||
this.$message.warning('请完善产品与原料映射')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
analyzePurchaseRequirement({
|
||||
persistResult: this.persistResult,
|
||||
mappings: this.mappingRows.map(row => ({
|
||||
productId: Number(row.productId),
|
||||
rawMaterialId: Number(row.rawMaterialId),
|
||||
conversionRate: Number(row.conversionRate || 0)
|
||||
}))
|
||||
})
|
||||
.then(res => {
|
||||
this.resultList = res || []
|
||||
this.buildRawDetail(res || [])
|
||||
this.$message.success('分析完成')
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
buildRawDetail(list) {
|
||||
const rows = []
|
||||
list.forEach(item => {
|
||||
(item.rawDetails || []).forEach(detail => {
|
||||
rows.push({
|
||||
productName: item.productName,
|
||||
rawMaterialName: detail.rawMaterialName,
|
||||
conversionRate: detail.conversionRate,
|
||||
stockWeight: detail.stockWeight,
|
||||
stockCoilCount: detail.stockCoilCount,
|
||||
convertedStock: detail.convertedStock,
|
||||
convertedInTransit: detail.convertedInTransit,
|
||||
convertedPending: detail.convertedPending
|
||||
})
|
||||
})
|
||||
})
|
||||
this.rawDetailData = rows
|
||||
},
|
||||
summaryMethod({ data }) {
|
||||
const sums = []
|
||||
const fields = ['salesDemand', 'productStockWeight', 'rawStockConverted', 'inTransitConverted', 'pendingConverted', 'suggestedPurchase']
|
||||
sums[0] = '总计'
|
||||
data.forEach(row => {
|
||||
fields.forEach((field, idx) => {
|
||||
sums[idx + 2] = (Number(sums[idx + 2]) || 0) + Number(row[field] || 0)
|
||||
})
|
||||
})
|
||||
return sums
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.erp-requirement-page {
|
||||
padding: 16px;
|
||||
background: #eef1f3;
|
||||
min-height: 100%;
|
||||
}
|
||||
.panel-card {
|
||||
margin-bottom: 18px;
|
||||
border: 1px solid #d0d5d8;
|
||||
}
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
color: #1f2d3d;
|
||||
}
|
||||
.panel-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.mapping-table {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.add-btn {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
.cell-sub {
|
||||
color: #7c8792;
|
||||
font-size: 12px;
|
||||
}
|
||||
.highlight {
|
||||
color: #c0392b;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user