提交基础采购

This commit is contained in:
2025-11-18 16:45:05 +08:00
parent cc9b1c0e92
commit 7c04e13198
77 changed files with 5733 additions and 0 deletions

View File

@@ -0,0 +1,214 @@
<template>
<div class="erp-receipt-page">
<el-card shadow="never" class="panel-card">
<div slot="header" class="panel-header">
<span>收货记录</span>
<el-button type="primary" size="mini" @click="openDialog()">新增收货</el-button>
</div>
<div class="toolbar">
<el-input v-model="query.orderId" placeholder="订单ID" size="small" clearable class="toolbar-input" />
<el-input v-model="query.itemId" placeholder="订单明细ID" size="small" clearable class="toolbar-input" />
<el-select v-model="query.quality" placeholder="质检结果" size="small" clearable class="toolbar-input">
<el-option label="合格" value="OK" />
<el-option label="不合格" value="NG" />
</el-select>
<el-button size="small" type="primary" @click="loadData">查询</el-button>
<el-button size="small" @click="resetQuery">重置</el-button>
</div>
<el-table :data="list" border size="small" v-loading="loading">
<el-table-column prop="receiptId" label="ID" width="80" />
<el-table-column prop="orderId" label="订单ID" width="120" />
<el-table-column prop="itemId" label="明细ID" width="120" />
<el-table-column prop="receivedQty" label="收货数量" width="120" />
<el-table-column prop="qualityResult" label="质检结果" width="120">
<template slot-scope="scope">
<el-tag :type="scope.row.qualityResult === 'NG' ? 'danger' : 'success'" size="mini">
{{ scope.row.qualityResult || 'OK' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="receiptTime" label="收货时间" width="160" />
<el-table-column label="备注" min-width="160" prop="remark" />
<el-table-column label="操作" width="140">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button>
<el-button type="text" size="mini" style="color:#c0392b" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="query.pageNum"
:limit.sync="query.pageSize"
@pagination="loadData"
/>
</el-card>
<el-card shadow="never" class="panel-card">
<div slot="header" class="panel-header">
<span>到货趋势</span>
</div>
<el-table :data="chartData" border size="small" height="300">
<el-table-column prop="date" label="日期" width="140" />
<el-table-column prop="totalQty" label="累计收货(吨)" />
<el-table-column prop="qualifiedQty" label="合格数量(吨)" />
<el-table-column prop="ngQty" label="不合格(吨)" />
</el-table>
</el-card>
<el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="480px">
<el-form :model="dialog.form" :rules="rules" ref="form" label-width="100px" size="small">
<el-form-item label="订单ID" prop="orderId">
<el-input v-model="dialog.form.orderId" />
</el-form-item>
<el-form-item label="明细ID" prop="itemId">
<el-input v-model="dialog.form.itemId" />
</el-form-item>
<el-form-item label="收货数量" prop="receivedQty">
<el-input-number v-model="dialog.form.receivedQty" :min="0" :precision="3" />
</el-form-item>
<el-form-item label="质检结果">
<el-select v-model="dialog.form.qualityResult" clearable>
<el-option label="合格" value="OK" />
<el-option label="不合格" value="NG" />
</el-select>
</el-form-item>
<el-form-item label="收货时间">
<el-date-picker v-model="dialog.form.receiptTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" />
</el-form-item>
<el-form-item label="备注">
<el-input type="textarea" v-model="dialog.form.remark" />
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialog.visible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
listPurchaseReceipt,
addPurchaseReceipt,
updatePurchaseReceipt,
delPurchaseReceipt
} from '@/api/erp/purchase'
export default {
name: 'ErpPurchaseReceipt',
data() {
return {
query: { pageNum: 1, pageSize: 10, orderId: null, itemId: null },
list: [],
total: 0,
loading: false,
chartData: [],
dialog: { visible: false, title: '', form: {} },
rules: {
orderId: [{ required: true, message: '请输入订单ID', trigger: 'blur' }],
itemId: [{ required: true, message: '请输入明细ID', trigger: 'blur' }],
receivedQty: [{ required: true, message: '请输入收货数量', trigger: 'blur' }]
}
}
},
created() {
this.loadData()
},
methods: {
loadData() {
this.loading = true
listPurchaseReceipt(this.query)
.then(res => {
this.list = res.rows || []
this.total = res.total || 0
this.buildChart()
})
.finally(() => {
this.loading = false
})
},
resetQuery() {
this.query = { pageNum: 1, pageSize: 10, orderId: null, itemId: null }
this.loadData()
},
openDialog(row) {
if (row) {
this.dialog.form = { ...row }
this.dialog.title = '编辑收货'
} else {
this.dialog.form = { orderId: '', itemId: '', receivedQty: 0, qualityResult: 'OK' }
this.dialog.title = '新增收货'
}
this.dialog.visible = true
this.$nextTick(() => this.$refs.form && this.$refs.form.clearValidate())
},
submit() {
this.$refs.form.validate(valid => {
if (!valid) return
const api = this.dialog.form.receiptId ? updatePurchaseReceipt : addPurchaseReceipt
api(this.dialog.form).then(() => {
this.$message.success('保存成功')
this.dialog.visible = false
this.loadData()
})
})
},
handleDelete(row) {
this.$confirm('确定删除该收货记录吗?', '提示').then(() => {
return delPurchaseReceipt(row.receiptId)
}).then(() => {
this.$message.success('删除成功')
this.loadData()
})
},
buildChart() {
const map = {}
this.list.forEach(item => {
const date = (item.receiptTime || '').slice(0, 10)
if (!map[date]) {
map[date] = { date, totalQty: 0, qualifiedQty: 0, ngQty: 0 }
}
map[date].totalQty += Number(item.receivedQty || 0)
if (item.qualityResult === 'NG') {
map[date].ngQty += Number(item.receivedQty || 0)
} else {
map[date].qualifiedQty += Number(item.receivedQty || 0)
}
})
this.chartData = Object.values(map).sort((a, b) => a.date.localeCompare(b.date))
}
}
}
</script>
<style lang="scss" scoped>
.erp-receipt-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;
}
.toolbar {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.toolbar-input {
width: 140px;
margin-right: 8px;
}
</style>