You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1106 lines
28 KiB
1106 lines
28 KiB
<template>
|
|
<!-- 原材料清单组件 -->
|
|
<div class="raw-material-container">
|
|
<!-- 工具栏 -->
|
|
<div class="toolbar-row">
|
|
<div class="toolbar-left">
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
class="add-btn"
|
|
v-if="canEdit"
|
|
@click="openAddDialog">
|
|
新增物料
|
|
</el-button>
|
|
<el-button
|
|
type="primary"
|
|
size="small"
|
|
class="reset-btn"
|
|
v-if="canEdit"
|
|
:disabled="selectedRows.length === 0"
|
|
@click="batchDeleteRawMaterial">
|
|
批量删除
|
|
</el-button>
|
|
<span
|
|
v-if="!disabled && !canEdit"
|
|
style="margin-left: 8px; color: #909399; font-size: 12px;">
|
|
仅试验负责人可维护原材料清单
|
|
</span>
|
|
<span
|
|
v-if="canEdit && shouldRecordChangeLog"
|
|
style="margin-left: 8px; color: #E6A23C; font-size: 12px;">
|
|
当前为非草稿状态:原材料增删改将自动记录详细修改日志,可点击右上角“修改记录”查看
|
|
</span>
|
|
</div>
|
|
<div class="toolbar-right" v-if="applyNo">
|
|
<el-tooltip content="查看原材料修改记录" placement="top">
|
|
<el-badge
|
|
:value="changeLogList.length"
|
|
:max="99"
|
|
:hidden="changeLogList.length === 0"
|
|
class="change-log-badge">
|
|
<el-button
|
|
type="warning"
|
|
plain
|
|
size="small"
|
|
icon="el-icon-tickets"
|
|
@click="openChangeLogDrawer">
|
|
修改记录
|
|
</el-button>
|
|
</el-badge>
|
|
</el-tooltip>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 数据表格 -->
|
|
<el-table
|
|
ref="rawMaterialTable"
|
|
:key="`raw-material-${applyNo || 'empty'}-${canEdit ? 'edit' : 'view'}`"
|
|
: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="canEdit">
|
|
</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="center"
|
|
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="center"
|
|
header-align="center"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
|
|
<!-- 工序 -->
|
|
<el-table-column
|
|
prop="processStep"
|
|
label="工序"
|
|
min-width="140"
|
|
align="center"
|
|
header-align="center"
|
|
show-overflow-tooltip>
|
|
<template slot-scope="scope">
|
|
{{ scope.row.processStep || '-' }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<!-- 数量 -->
|
|
<el-table-column
|
|
prop="quantity"
|
|
label="数量"
|
|
width="120"
|
|
align="center"
|
|
header-align="center">
|
|
</el-table-column>
|
|
|
|
<!-- 单位 -->
|
|
<el-table-column
|
|
prop="umid"
|
|
label="单位"
|
|
width="80"
|
|
align="center"
|
|
header-align="center">
|
|
<template slot-scope="scope">
|
|
{{ scope.row.umid || '-' }}
|
|
</template>
|
|
</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="canEdit">
|
|
<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-drawer
|
|
title="原材料修改记录"
|
|
:visible.sync="changeLogDrawerVisible"
|
|
:append-to-body="true"
|
|
size="55%">
|
|
<div class="change-log-drawer-body">
|
|
<div class="change-log-drawer-toolbar">
|
|
<span class="change-log-count">共 {{ changeLogList.length }} 条</span>
|
|
<el-button
|
|
type="text"
|
|
size="small"
|
|
:loading="changeLogLoading"
|
|
@click="loadChangeLogList">
|
|
刷新
|
|
</el-button>
|
|
</div>
|
|
<el-table
|
|
:data="changeLogList"
|
|
v-loading="changeLogLoading"
|
|
border
|
|
size="small"
|
|
class="change-log-table"
|
|
height="68vh"
|
|
style="width: 100%">
|
|
|
|
<el-table-column type="expand" width="50">
|
|
<template slot-scope="scope">
|
|
<div class="log-detail-wrapper">
|
|
<div class="log-detail-item">
|
|
<span class="log-detail-label">详细说明:</span>
|
|
<pre class="log-detail-pre">{{ scope.row.detailContent || '-' }}</pre>
|
|
</div>
|
|
<!-- <div class="log-detail-item" v-if="scope.row.beforeContent">
|
|
<span class="log-detail-label">修改前快照:</span>
|
|
<pre class="log-detail-pre">{{ scope.row.beforeContent }}</pre>
|
|
</div>
|
|
<div class="log-detail-item" v-if="scope.row.afterContent">
|
|
<span class="log-detail-label">修改后快照:</span>
|
|
<pre class="log-detail-pre">{{ scope.row.afterContent }}</pre>
|
|
</div>-->
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="createdDate"
|
|
label="时间"
|
|
width="160"
|
|
align="center"
|
|
header-align="center">
|
|
<template slot-scope="scope">
|
|
{{ formatDateTime(scope.row.createdDate) }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="operationType"
|
|
label="操作类型"
|
|
width="90"
|
|
align="center"
|
|
class-name="operation-type-cell"
|
|
header-align="center">
|
|
<template slot-scope="scope">
|
|
<span
|
|
:class="['operation-type-pill', getOperationTypeClass(scope.row.operationType)]">
|
|
{{ formatOperationType(scope.row.operationType) || '-' }}
|
|
</span>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="operatorDisplayName"
|
|
label="操作人"
|
|
width="120"
|
|
align="center"
|
|
header-align="center">
|
|
<template slot-scope="scope">
|
|
{{ scope.row.operatorDisplayName || scope.row.operatorUserName || '-' }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="applyStatus"
|
|
label="单据状态"
|
|
width="90"
|
|
align="center"
|
|
header-align="center">
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
prop="operationDescDisplay"
|
|
label="操作摘要"
|
|
min-width="240"
|
|
show-overflow-tooltip>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</el-drawer>
|
|
|
|
<!-- 新增/编辑弹窗 -->
|
|
<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="工序" required>
|
|
<el-select
|
|
v-model="formData.processStep"
|
|
placeholder="请选择工序"
|
|
filterable
|
|
clearable
|
|
:loading="processOptionsLoading"
|
|
style="width: 100%">
|
|
<el-option
|
|
v-for="item in processOptions"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value">
|
|
</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<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
|
|
v-model="formData.umid"
|
|
placeholder="输入物料编码后自动带出"
|
|
clearable>
|
|
</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, getRawMaterialChangeLogList, saveRawMaterial, deleteRawMaterial, batchDeleteRawMaterial, getPartDescByPartNo } from '@/api/erf/erf'
|
|
import { searchStandardRoutingOperationList } from '@/api/part/standardRoutingOperation'
|
|
|
|
export default {
|
|
name: 'ExpRawMaterialList',
|
|
|
|
props: {
|
|
// 试验单号
|
|
applyNo: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
// 工厂编码
|
|
site: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// buNo
|
|
buNo: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 当前申请单状态
|
|
applyStatus: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 试验负责人(显示名)
|
|
projectLeader: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 试验负责人(用户名)
|
|
projectLeaderName: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
// 是否禁用编辑
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
// 原材料清单数据
|
|
rawMaterialList: [],
|
|
|
|
// 原材料修改记录
|
|
changeLogList: [],
|
|
|
|
// 表格加载状态
|
|
tableLoading: false,
|
|
|
|
// 修改记录加载状态
|
|
changeLogLoading: false,
|
|
|
|
// 修改记录抽屉
|
|
changeLogDrawerVisible: false,
|
|
|
|
// 已选中的行
|
|
selectedRows: [],
|
|
|
|
// 弹窗显示状态
|
|
dialogVisible: false,
|
|
|
|
// 弹窗标题
|
|
dialogTitle: '新增物料',
|
|
|
|
// 表单数据
|
|
formData: {
|
|
id: null,
|
|
applyNo: '',
|
|
site: '',
|
|
buNo: '',
|
|
processStep: '',
|
|
partNo: '',
|
|
partDesc: '',
|
|
quantity: '',
|
|
umid: '',
|
|
remark: ''
|
|
},
|
|
|
|
// 保存加载状态
|
|
saveLoading: false,
|
|
|
|
// 标准工序下拉选项
|
|
processOptions: [],
|
|
|
|
// 标准工序加载状态
|
|
processOptionsLoading: false
|
|
}
|
|
},
|
|
|
|
mounted() {
|
|
this.loadRawMaterialList()
|
|
this.loadChangeLogList()
|
|
},
|
|
|
|
watch: {
|
|
applyNo(newVal) {
|
|
if (newVal) {
|
|
this.loadRawMaterialList()
|
|
this.loadChangeLogList()
|
|
} else {
|
|
this.rawMaterialList = []
|
|
this.selectedRows = []
|
|
this.changeLogList = []
|
|
this.changeLogDrawerVisible = false
|
|
}
|
|
},
|
|
buNo(newVal, oldVal) {
|
|
if (newVal !== oldVal) {
|
|
if (this.canEdit) {
|
|
this.loadProcessOptions()
|
|
} else {
|
|
this.processOptions = []
|
|
}
|
|
}
|
|
},
|
|
canEdit(newVal) {
|
|
if (newVal) {
|
|
this.loadProcessOptions()
|
|
} else {
|
|
this.processOptions = []
|
|
}
|
|
this.selectedRows = []
|
|
this.refreshRawMaterialTableLayout()
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
/**
|
|
* 是否可编辑原材料清单(仅试验负责人)
|
|
*/
|
|
canEdit() {
|
|
if (this.disabled) {
|
|
return false
|
|
}
|
|
const currentUserName = (this.$store.state.user.name || '').trim()
|
|
const currentUserDisplay = (this.$store.state.user.userDisplay || '').trim()
|
|
const leaderList = [this.projectLeaderName, this.projectLeader]
|
|
.filter(item => item && item.trim())
|
|
.map(item => item.trim())
|
|
|
|
if (leaderList.length === 0) {
|
|
return false
|
|
}
|
|
|
|
return leaderList.some(item => item === currentUserName || item === currentUserDisplay)
|
|
},
|
|
/**
|
|
* 非草稿状态下需记录详细修改日志
|
|
*/
|
|
shouldRecordChangeLog() {
|
|
return !!this.applyStatus && this.applyStatus !== '草稿'
|
|
}
|
|
},
|
|
|
|
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 || []
|
|
this.refreshRawMaterialTableLayout()
|
|
} else {
|
|
this.rawMaterialList = []
|
|
this.$message.error(data.msg || '查询原材料清单失败')
|
|
}
|
|
}).catch(error => {
|
|
this.tableLoading = false
|
|
this.$message.error('查询原材料清单异常')
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 刷新原材料表格布局,避免列结构切换后错位
|
|
*/
|
|
refreshRawMaterialTableLayout() {
|
|
this.$nextTick(() => {
|
|
if (this.$refs.rawMaterialTable && this.$refs.rawMaterialTable.doLayout) {
|
|
this.$refs.rawMaterialTable.doLayout()
|
|
}
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 加载原材料修改记录
|
|
*/
|
|
loadChangeLogList() {
|
|
if (!this.applyNo) {
|
|
this.changeLogList = []
|
|
return
|
|
}
|
|
|
|
this.changeLogLoading = true
|
|
getRawMaterialChangeLogList({ applyNo: this.applyNo }).then(({data}) => {
|
|
this.changeLogLoading = false
|
|
if (data && data.code === 0) {
|
|
const logList = data.list || []
|
|
this.changeLogList = logList.map(item => {
|
|
const rowData = item || {}
|
|
return Object.assign({}, rowData, {
|
|
operationDescDisplay: this.buildOperationDescDisplay(rowData)
|
|
})
|
|
})
|
|
} else {
|
|
this.changeLogList = []
|
|
this.$message.error(data.msg || '查询原材料修改记录失败')
|
|
}
|
|
}).catch(() => {
|
|
this.changeLogLoading = false
|
|
this.changeLogList = []
|
|
this.$message.error('查询原材料修改记录异常')
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 打开修改记录抽屉
|
|
*/
|
|
openChangeLogDrawer() {
|
|
this.changeLogDrawerVisible = true
|
|
this.loadChangeLogList()
|
|
},
|
|
|
|
/**
|
|
* 按BU加载标准工序下拉
|
|
*/
|
|
loadProcessOptions() {
|
|
if (!this.buNo) {
|
|
this.processOptions = []
|
|
return
|
|
}
|
|
|
|
this.processOptionsLoading = true
|
|
const queryData = {
|
|
userName: this.$store.state.user.name,
|
|
site: this.site || this.$store.state.user.site,
|
|
buNo: this.buNo,
|
|
page: 1,
|
|
limit: 500
|
|
}
|
|
|
|
searchStandardRoutingOperationList(queryData).then(({data}) => {
|
|
this.processOptionsLoading = false
|
|
if (data && data.code === 0) {
|
|
const list = (data.page && data.page.list) ? data.page.list : []
|
|
const optionMap = {}
|
|
list.forEach(item => {
|
|
const processName = item.operationName ? item.operationName.trim() : ''
|
|
if (!processName) {
|
|
return
|
|
}
|
|
if (!optionMap[processName]) {
|
|
const hasOperationNo = item.operationNo !== null && item.operationNo !== undefined && item.operationNo !== ''
|
|
optionMap[processName] = {
|
|
value: processName,
|
|
label: hasOperationNo ? `${item.operationNo} - ${processName}` : processName
|
|
}
|
|
}
|
|
})
|
|
this.processOptions = Object.values(optionMap)
|
|
} else {
|
|
this.processOptions = []
|
|
this.$message.error(data.msg || '加载标准工序失败')
|
|
}
|
|
}).catch(() => {
|
|
this.processOptionsLoading = false
|
|
this.processOptions = []
|
|
this.$message.error('加载标准工序异常')
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 编辑场景兜底:已选工序不在下拉时补充显示
|
|
*/
|
|
ensureProcessOption(processStep) {
|
|
if (!processStep) {
|
|
return
|
|
}
|
|
const exists = this.processOptions.some(item => item.value === processStep)
|
|
if (!exists) {
|
|
this.processOptions.push({
|
|
value: processStep,
|
|
label: processStep
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 打开新增弹窗
|
|
*/
|
|
openAddDialog() {
|
|
this.loadProcessOptions()
|
|
this.dialogTitle = '新增物料'
|
|
this.formData = {
|
|
id: null,
|
|
applyNo: this.applyNo,
|
|
site: this.site || this.$store.state.user.site,
|
|
buNo: this.buNo,
|
|
processStep: '',
|
|
partNo: '',
|
|
partDesc: '',
|
|
quantity: '',
|
|
umid: '',
|
|
remark: ''
|
|
}
|
|
this.dialogVisible = true
|
|
},
|
|
|
|
/**
|
|
* 打开编辑弹窗
|
|
*/
|
|
openEditDialog(row) {
|
|
this.dialogTitle = '修改物料'
|
|
this.formData = {
|
|
id: row.id,
|
|
applyNo: row.applyNo,
|
|
site: row.site,
|
|
buNo: this.buNo,
|
|
processStep: row.processStep || '',
|
|
partNo: row.partNo,
|
|
partDesc: row.partDesc,
|
|
quantity: row.quantity,
|
|
umid: row.umid || '',
|
|
remark: row.remark
|
|
}
|
|
this.ensureProcessOption(this.formData.processStep)
|
|
this.dialogVisible = true
|
|
},
|
|
|
|
/**
|
|
* 保存物料
|
|
*/
|
|
saveRawMaterial() {
|
|
// 数据验证
|
|
if (!this.formData.partDesc) {
|
|
this.$message.warning('请输入物料描述')
|
|
return
|
|
}
|
|
|
|
if (!this.formData.processStep) {
|
|
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,
|
|
processStep: this.formData.processStep,
|
|
partNo: this.formData.partNo || null,
|
|
partDesc: this.formData.partDesc,
|
|
quantity: this.formData.quantity,
|
|
umid: this.formData.umid || null,
|
|
remark: this.formData.remark
|
|
}
|
|
|
|
saveRawMaterial(saveData).then(({data}) => {
|
|
this.saveLoading = false
|
|
if (data && data.code === 0) {
|
|
this.$message.success('保存成功')
|
|
this.dialogVisible = false
|
|
this.loadRawMaterialList()
|
|
this.loadChangeLogList()
|
|
} 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()
|
|
this.loadChangeLogList()
|
|
} 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.loadChangeLogList()
|
|
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
|
|
}
|
|
|
|
// 查询part表获取物料描述
|
|
getPartDescByPartNo({
|
|
partNo: partNo.trim(),
|
|
site: this.formData.site,
|
|
buNo: ''
|
|
}).then(({data}) => {
|
|
if (data && data.code === 0 && data.partDesc) {
|
|
this.formData.partDesc = data.partDesc
|
|
this.formData.umid = data.umid || ''
|
|
} else {
|
|
this.$message.warning('未找到该物料编码,请手动填写物料描述')
|
|
}
|
|
}).catch(error => {
|
|
console.error('查询物料描述异常:', error)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 表格多选变化
|
|
*/
|
|
handleSelectionChange(selection) {
|
|
this.selectedRows = selection
|
|
},
|
|
|
|
/**
|
|
* 格式化时间
|
|
*/
|
|
formatDateTime(dateValue) {
|
|
if (!dateValue) {
|
|
return '-'
|
|
}
|
|
if (typeof dateValue === 'string') {
|
|
return dateValue
|
|
}
|
|
const date = new Date(dateValue)
|
|
if (isNaN(date.getTime())) {
|
|
return '-'
|
|
}
|
|
const y = date.getFullYear()
|
|
const m = String(date.getMonth() + 1).padStart(2, '0')
|
|
const d = String(date.getDate()).padStart(2, '0')
|
|
const hh = String(date.getHours()).padStart(2, '0')
|
|
const mm = String(date.getMinutes()).padStart(2, '0')
|
|
const ss = String(date.getSeconds()).padStart(2, '0')
|
|
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
|
|
},
|
|
|
|
/**
|
|
* 操作类型对应样式
|
|
*/
|
|
getOperationTypeClass(operationType) {
|
|
const operation = this.formatOperationType(operationType)
|
|
const classMap = {
|
|
'新增': 'operation-type-add',
|
|
'删除': 'operation-type-delete',
|
|
'修改': 'operation-type-edit'
|
|
}
|
|
return classMap[operation] || 'operation-type-default'
|
|
},
|
|
|
|
/**
|
|
* 标准化操作类型
|
|
*/
|
|
formatOperationType(operationType) {
|
|
return operationType ? String(operationType).trim() : ''
|
|
},
|
|
|
|
/**
|
|
* 生成摘要展示文本(兼容历史“仅字段名”日志)
|
|
*/
|
|
buildOperationDescDisplay(logItem) {
|
|
const rowData = logItem || {}
|
|
const operationDesc = rowData.operationDesc ? String(rowData.operationDesc).trim() : ''
|
|
const operationType = this.formatOperationType(rowData.operationType)
|
|
const detailDesc = this.buildOperationDescFromDetail(rowData.detailContent)
|
|
|
|
if (operationType === '修改' && detailDesc) {
|
|
return detailDesc
|
|
}
|
|
return operationDesc || detailDesc || '-'
|
|
},
|
|
|
|
/**
|
|
* 从详细说明提取“旧值 -> 新值”明细并拼成摘要
|
|
*/
|
|
buildOperationDescFromDetail(detailContent) {
|
|
if (!detailContent) {
|
|
return ''
|
|
}
|
|
const diffList = String(detailContent)
|
|
.split('\n')
|
|
.map(item => item.trim())
|
|
.filter(item => /^\d+\.\s+.+\s+->\s+.+$/.test(item))
|
|
.map(item => item.replace(/^\d+\.\s*/, ''))
|
|
|
|
if (diffList.length === 0) {
|
|
return ''
|
|
}
|
|
return `非草稿状态修改原材料,变更明细:${diffList.join(';')}`
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.raw-material-container {
|
|
padding: 10px;
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
.toolbar-row {
|
|
margin-bottom: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
|
|
.toolbar-left {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
min-width: 0;
|
|
}
|
|
|
|
.toolbar-right {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.change-log-badge {
|
|
margin-right: 2px;
|
|
}
|
|
|
|
.change-log-drawer-body {
|
|
padding: 0 16px 12px 16px;
|
|
}
|
|
|
|
.change-log-drawer-toolbar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.change-log-count {
|
|
color: #606266;
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* 覆盖全局 .el-table .cell 固定14px,避免操作类型被上下裁切 */
|
|
.change-log-table >>> td.operation-type-cell .cell {
|
|
height: auto !important;
|
|
line-height: 20px !important;
|
|
overflow: visible !important;
|
|
padding-top: 2px;
|
|
padding-bottom: 2px;
|
|
}
|
|
|
|
.operation-type-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 44px;
|
|
min-height: 20px;
|
|
line-height: 16px;
|
|
padding: 0 8px;
|
|
box-sizing: border-box;
|
|
border-radius: 10px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.operation-type-add {
|
|
background: #f0f9eb;
|
|
color: #67c23a;
|
|
border: 1px solid #c2e7b0;
|
|
}
|
|
|
|
.operation-type-delete {
|
|
background: #fef0f0;
|
|
color: #f56c6c;
|
|
border: 1px solid #f5bcbc;
|
|
}
|
|
|
|
.operation-type-edit {
|
|
background: #fdf6ec;
|
|
color: #e6a23c;
|
|
border: 1px solid #f5dab1;
|
|
}
|
|
|
|
.operation-type-default {
|
|
background: #f4f4f5;
|
|
color: #909399;
|
|
border: 1px solid #e9e9eb;
|
|
}
|
|
|
|
.log-detail-wrapper {
|
|
padding: 8px 12px;
|
|
background: #fafafa;
|
|
}
|
|
|
|
.log-detail-item {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.log-detail-item:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.log-detail-label {
|
|
display: inline-block;
|
|
margin-bottom: 4px;
|
|
color: #606266;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.log-detail-pre {
|
|
margin: 0;
|
|
white-space: pre-wrap;
|
|
word-break: break-all;
|
|
background: #fff;
|
|
border: 1px solid #ebeef5;
|
|
border-radius: 2px;
|
|
padding: 6px 8px;
|
|
color: #606266;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
/* 按钮样式 - 与附件上传保持一致 */
|
|
.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: #FEF0F0;
|
|
border-color: #FAB6B6;
|
|
color: #F56C6C;
|
|
}
|
|
|
|
.reset-btn:hover:not(:disabled) {
|
|
background-color: #F56C6C;
|
|
border-color: #F56C6C;
|
|
color: #FFFFFF;
|
|
}
|
|
|
|
.reset-btn:hover:disabled {
|
|
background-color: #FEF0F0;
|
|
border-color: #FAB6B6;
|
|
color: #F56C6C;
|
|
}
|
|
|
|
.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>
|