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