3 changed files with 564 additions and 1 deletions
-
34src/api/erf/erf.js
-
510src/views/modules/erf/components/expRawMaterialList.vue
-
21src/views/modules/erf/expApplyList.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> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue