Browse Source

原材料清单

master
han\hanst 4 weeks ago
parent
commit
26bba097c2
  1. 34
      src/api/erf/erf.js
  2. 510
      src/views/modules/erf/components/expRawMaterialList.vue
  3. 21
      src/views/modules/erf/expApplyList.vue

34
src/api/erf/erf.js

@ -151,3 +151,37 @@ export const getUserListByRole = data => createAPI(`/erf/triConfirm/getUserListB
* 样品确认
*/
export const confirmSample = data => createAPI(`/erf/expApply/confirmSample`, 'post', data)
// =====================================================
// 原材料清单 API接口定义
// =====================================================
/**
* 根据申请单号查询原材料清单列表
*/
export const getRawMaterialList = data => createAPI(`/erf/rawMaterial/getRawMaterialList`, 'post', data)
/**
* 根据ID查询单条原材料记录
*/
export const getRawMaterialById = data => createAPI(`/erf/rawMaterial/getRawMaterialById`, 'post', data)
/**
* 保存原材料记录新增或修改
*/
export const saveRawMaterial = data => createAPI(`/erf/rawMaterial/saveRawMaterial`, 'post', data)
/**
* 删除原材料记录
*/
export const deleteRawMaterial = data => createAPI(`/erf/rawMaterial/deleteRawMaterial`, 'post', data)
/**
* 批量删除原材料记录
*/
export const batchDeleteRawMaterial = data => createAPI(`/erf/rawMaterial/batchDeleteRawMaterial`, 'post', data)
/**
* 根据物料编码查询物料描述从part表
*/
export const getPartDescByPartNo = data => createAPI(`/erf/rawMaterial/getPartDescByPartNo`, 'post', data)

510
src/views/modules/erf/components/expRawMaterialList.vue

@ -0,0 +1,510 @@
<template>
<!-- 原材料清单组件 -->
<div class="raw-material-container">
<!-- 工具栏 -->
<div style="margin-bottom: 10px">
<el-button
type="primary"
size="small"
class="add-btn"
v-if="!disabled"
@click="openAddDialog">
新增物料
</el-button>
<el-button
type="primary"
size="small"
class="reset-btn"
v-if="!disabled"
:disabled="selectedRows.length === 0"
@click="batchDeleteRawMaterial">
批量删除
</el-button>
</div>
<!-- 数据表格 -->
<el-table
ref="rawMaterialTable"
:data="rawMaterialList"
v-loading="tableLoading"
border
:height="260"
@selection-change="handleSelectionChange"
style="width: 100%">
<!-- 多选框 -->
<el-table-column
type="selection"
width="55"
align="center"
v-if="!disabled">
</el-table-column>
<!-- 序号 -->
<el-table-column
type="index"
label="序号"
width="60"
align="center">
</el-table-column>
<!-- 物料编码 -->
<el-table-column
prop="partNo"
label="物料编码"
min-width="150"
align="left"
header-align="center"
show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.partNo || '-' }}
</template>
</el-table-column>
<!-- 物料描述 -->
<el-table-column
prop="partDesc"
label="物料描述"
min-width="200"
align="left"
header-align="center"
show-overflow-tooltip>
</el-table-column>
<!-- 数量 -->
<el-table-column
prop="quantity"
label="数量"
width="120"
align="center"
header-align="center">
</el-table-column>
<!-- 备注 -->
<el-table-column
prop="remark"
label="备注"
min-width="150"
align="left"
header-align="center"
show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.remark || '-' }}
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column
label="操作"
width="150"
align="center"
header-align="center"
v-if="!disabled">
<template slot-scope="scope">
<el-link
style="cursor:pointer; margin-right: 10px;"
@click="openEditDialog(scope.row)">
修改
</el-link>
<el-link
style="cursor:pointer; color: #F56C6C;"
@click="deleteRawMaterial(scope.row)">
删除
</el-link>
</template>
</el-table-column>
</el-table>
<!-- 新增/编辑弹窗 -->
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
width="420px"
append-to-body
:close-on-click-modal="false">
<el-form :model="formData" label-width="80px" size="small">
<el-form-item label="物料编码">
<el-input
v-model="formData.partNo"
placeholder="请输入物料编码(可为空)"
clearable
@blur="handlePartNoBlur"
@keyup.enter.native="handlePartNoBlur">
</el-input>
<div style="color: #909399; font-size: 12px; margin-top: -10px;">
输入物料编码后按回车或失去焦点自动查询物料描述
</div>
</el-form-item>
<el-form-item label="物料描述" required>
<el-input
v-model="formData.partDesc"
placeholder="请输入物料描述(必填)"
clearable>
</el-input>
</el-form-item>
<el-form-item label="数量" required>
<el-input
v-model="formData.quantity"
:precision="2"
:min="0.01"
:controls="true"
style="width: 100%">
</el-input>
</el-form-item>
<el-form-item label="备注">
<el-input
type="textarea"
v-model="formData.remark"
placeholder="请输入备注"
:autosize="{minRows: 2, maxRows: 3}"
clearable>
</el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer" style="margin-top: 10px">
<el-button type="primary" @click="saveRawMaterial" :loading="saveLoading">
{{ saveLoading ? '保存中...' : '保存' }}
</el-button>
<el-button @click="dialogVisible = false">关闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getRawMaterialList, saveRawMaterial, deleteRawMaterial, batchDeleteRawMaterial, getPartDescByPartNo } from '@/api/erf/erf'
export default {
name: 'ExpRawMaterialList',
props: {
//
applyNo: {
type: String,
required: true
},
//
site: {
type: String,
default: ''
},
// buNo
buNo: {
type: String,
default: ''
},
//
disabled: {
type: Boolean,
default: false
},
//
height: {
type: Number,
default: 300
}
},
data() {
return {
//
rawMaterialList: [],
//
tableLoading: false,
//
selectedRows: [],
//
dialogVisible: false,
//
dialogTitle: '新增物料',
//
formData: {
id: null,
applyNo: '',
site: '',
buNo: '',
partNo: '',
partDesc: '',
quantity: '',
remark: ''
},
//
saveLoading: false
}
},
mounted() {
this.loadRawMaterialList()
},
watch: {
applyNo(newVal) {
if (newVal) {
this.loadRawMaterialList()
}
}
},
methods: {
/**
* 加载原材料清单列表
*/
loadRawMaterialList() {
if (!this.applyNo) {
return
}
this.tableLoading = true
getRawMaterialList({ applyNo: this.applyNo }).then(({data}) => {
this.tableLoading = false
if (data && data.code === 0) {
this.rawMaterialList = data.list || []
} else {
this.rawMaterialList = []
this.$message.error(data.msg || '查询原材料清单失败')
}
}).catch(error => {
this.tableLoading = false
this.$message.error('查询原材料清单异常')
})
},
/**
* 打开新增弹窗
*/
openAddDialog() {
this.dialogTitle = '新增物料'
this.formData = {
id: null,
applyNo: this.applyNo,
site: this.site || this.$store.state.user.site,
buNo: this.buNo,
partNo: '',
partDesc: '',
quantity: '',
remark: ''
}
this.dialogVisible = true
},
/**
* 打开编辑弹窗
*/
openEditDialog(row) {
this.dialogTitle = '修改物料'
this.formData = {
id: row.id,
applyNo: row.applyNo,
site: row.site,
buNo: this.buNo,
partNo: row.partNo,
partDesc: row.partDesc,
quantity: row.quantity,
remark: row.remark
}
this.dialogVisible = true
},
/**
* 保存物料
*/
saveRawMaterial() {
//
if (!this.formData.partDesc) {
this.$message.warning('请输入物料描述')
return
}
const qty = Number(this.formData.quantity)
if (isNaN(qty) || qty <= 0) {
this.$message.warning('请输入有效数字(必须大于0)')
return
}
this.saveLoading = true
//
const saveData = {
id: this.formData.id,
applyNo: this.formData.applyNo,
site: this.formData.site,
partNo: this.formData.partNo || null,
partDesc: this.formData.partDesc,
quantity: this.formData.quantity,
remark: this.formData.remark
}
saveRawMaterial(saveData).then(({data}) => {
this.saveLoading = false
if (data && data.code === 0) {
this.$message.success('保存成功')
this.dialogVisible = false
this.loadRawMaterialList()
} else {
this.$message.error(data.msg || '保存失败')
}
}).catch(error => {
this.saveLoading = false
this.$message.error('保存异常')
})
},
/**
* 删除物料
*/
deleteRawMaterial(row) {
this.$confirm('确定删除该物料记录?', '操作提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteRawMaterial({ id: row.id }).then(({data}) => {
if (data && data.code === 0) {
this.$message.success('删除成功')
this.loadRawMaterialList()
} else {
this.$message.error(data.msg || '删除失败')
}
}).catch(error => {
this.$message.error('删除异常')
})
})
},
/**
* 批量删除物料
*/
batchDeleteRawMaterial() {
if (this.selectedRows.length === 0) {
this.$message.warning('请先选择要删除的物料')
return
}
this.$confirm(`确定删除选中的 ${this.selectedRows.length} 条物料记录?`, '操作提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const ids = this.selectedRows.map(row => row.id)
batchDeleteRawMaterial({ ids: ids }).then(({data}) => {
if (data && data.code === 0) {
this.$message.success('删除成功')
this.loadRawMaterialList()
this.selectedRows = []
} else {
this.$message.error(data.msg || '删除失败')
}
}).catch(error => {
this.$message.error('删除异常')
})
})
},
/**
* 物料编码失去焦点或回车时查询part表
*/
handlePartNoBlur() {
const partNo = this.formData.partNo
if (!partNo || !partNo.trim()) {
return
}
//
if (this.formData.partDesc) {
return
}
// part
getPartDescByPartNo({
partNo: partNo.trim(),
site: this.formData.site,
buNo: this.buNo
}).then(({data}) => {
if (data && data.code === 0 && data.partDesc) {
this.formData.partDesc = data.partDesc
} else {
this.$message.warning('未找到该物料编码,请手动填写物料描述')
}
}).catch(error => {
console.error('查询物料描述异常:', error)
})
},
/**
* 表格多选变化
*/
handleSelectionChange(selection) {
this.selectedRows = selection
}
}
}
</script>
<style scoped>
.raw-material-container {
padding: 10px;
background-color: #ffffff;
}
/* 按钮样式 - 与附件上传保持一致 */
.add-btn {
background-color: #F0F9FF;
border-color: #C0E6C7;
color: #67C23A;
}
.add-btn:hover:not(:disabled) {
background-color: #67C23A;
border-color: #67C23A;
color: #FFFFFF;
}
.reset-btn {
background-color: #F5F7FA;
border-color: #D3D4D6;
color: #606266;
}
.reset-btn:hover:not(:disabled) {
background-color: #909399;
border-color: #909399;
color: #FFFFFF;
}
.reset-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* 表格样式 */
.el-table >>> .el-table__header-wrapper th {
background-color: #F5F7FA;
color: #606266;
font-weight: 600;
font-size: 13px;
}
.el-table >>> .el-table__body-wrapper td {
font-size: 13px;
color: #606266;
}
/* 弹窗表单样式 */
.dialog-footer {
text-align: center;
}
</style>

21
src/views/modules/erf/expApplyList.vue

@ -391,6 +391,23 @@
<p style="font-size: 13px">请选择申请单查看审批状态</p>
</div>
</el-tab-pane>
<!-- Tab 5: 原材料清单 -->
<el-tab-pane label="原材料清单" name="rawMaterial">
<exp-raw-material-list
v-if="currentRow.applyNo"
ref="rawMaterialList"
:apply-no="currentRow.applyNo"
:site="currentRow.site || $store.state.user.site"
:buNo="currentRow.buNo"
:disabled="currentRow.status === '已完成' || currentRow.status === '已取消'"
:height="detailHeight">
</exp-raw-material-list>
<div v-else class="empty-tip">
<i class="el-icon-document" style="font-size: 40px; color: #C0C4CC; margin-bottom: 10px"></i>
<p style="font-size: 13px">请选择申请单查看原材料清单</p>
</div>
</el-tab-pane>
</el-tabs>
<!-- 新增/编辑弹窗 -->
@ -571,6 +588,7 @@ import ExpApplyForm from './components/expApplyForm.vue'
import ExpProjectDetail from './components/expProjectDetail.vue'
import ExpTriConfirm from './components/expTriConfirm.vue'
import ErfAttachmentManager from './components/erfAttachmentManager.vue'
import ExpRawMaterialList from './components/expRawMaterialList.vue'
export default {
name: 'ExpApplyList',
@ -579,7 +597,8 @@ export default {
ExpApplyForm,
ExpProjectDetail,
ExpTriConfirm,
ErfAttachmentManager
ErfAttachmentManager,
ExpRawMaterialList
},
data() {

Loading…
Cancel
Save