543 lines
16 KiB
Vue
543 lines
16 KiB
Vue
<template>
|
||
<div v-loading="syncLoading">
|
||
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
|
||
<el-form-item label="母件编码">
|
||
<el-input v-model.trim="queryParams.invCode" placeholder="请输入物料编码" />
|
||
</el-form-item>
|
||
<el-form-item label="子件编码">
|
||
<el-input v-model.trim="queryParams.subInvCode" placeholder="请输入物料名称" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
|
||
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 工具区域 -->
|
||
<el-row :gutter="15" class="mb10">
|
||
<el-col :span="1.5">
|
||
<el-col :span="1.5">
|
||
<el-button class="tool-box" color="#626aef" icon="Download" @click="handleImport"> 导入
|
||
</el-button>
|
||
<el-button class="tool-box" color="#00aa00" icon="Upload" @click="handleDownload"> 导出 </el-button>
|
||
<el-button type="danger" icon="delete" @click="handleBatchDelete"
|
||
:disabled="ids.length === 0">批量删除</el-button>
|
||
</el-col>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<vxe-table border="inner" ref="tableRef" :column-config="{ resizable: true }" :expand-config="{
|
||
lazy: true,
|
||
loadMethod: loadContentMethod,
|
||
iconOpen: 'vxe-icon-square-minus-fill',
|
||
iconClose: 'vxe-icon-square-plus-fill'
|
||
}" :data="dataList" @checkbox-change="handleSelectionChange" @checkbox-all="handleSelectAll">
|
||
<vxe-column type="checkbox" width="60" fixed="left"></vxe-column>
|
||
<vxe-column type="seq" width="60"></vxe-column>
|
||
<vxe-column type="expand" width="80">
|
||
<template #content="{ row }">
|
||
<vxe-table border size="mini" stripe :data="row.children" @checkbox-change="handleSelectionChange2"
|
||
@checkbox-all="handleSelectAll2">
|
||
<vxe-column type="checkbox" width="60" fixed="left"></vxe-column>
|
||
<vxe-column type="seq" width="60"></vxe-column>
|
||
<vxe-column field="subInvCode" title="子件编码"></vxe-column>
|
||
<vxe-column field="subInvName" title="子件名称"></vxe-column>
|
||
<vxe-column field="iusequantity" title="使用数量"></vxe-column>
|
||
<vxe-column field="bomVersion" title="bom版本"></vxe-column>
|
||
<vxe-column field="iusequantity" title="操作">
|
||
<template #default="{ row }">
|
||
<el-button type="success" size="small" icon="edit" title="编辑" @click="handleSubEdit(row)"></el-button>
|
||
<el-button type="danger" @click="handleSubDelete(row)" size="small" icon="delete" title="删除" />
|
||
</template>
|
||
</vxe-column>
|
||
</vxe-table>
|
||
</template>
|
||
</vxe-column>
|
||
<vxe-column field="invCode" title="母件编码"></vxe-column>
|
||
<vxe-column field="invName" title="母件名称"></vxe-column>
|
||
<vxe-column field="bomVersion" title="bom版本"></vxe-column>
|
||
<vxe-column field="iusequantity" title="操作">
|
||
<template #default="{ row }">
|
||
<el-button type="success" size="small" icon="edit" title="编辑" @click="handleEdit(row)"></el-button>
|
||
<el-button type="danger" size="small" icon="delete" title="删除" @click="handleDelete(row)"></el-button>
|
||
</template>
|
||
</vxe-column>
|
||
</vxe-table>
|
||
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||
@pagination="getList" />
|
||
</div>
|
||
|
||
<!-- 主件编辑弹窗 -->
|
||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body draggable
|
||
:close-on-click-modal="false">
|
||
<el-form ref="editFormRef" :model="formData" :rules="rules" label-width="120px">
|
||
<el-form-item label="母件编码" prop="invCode">
|
||
<el-input v-model="formData.invCode" placeholder="请输入母件编码" />
|
||
</el-form-item>
|
||
<el-form-item label="母件名称" prop="invName">
|
||
<el-input v-model="formData.invName" placeholder="请输入母件名称" />
|
||
</el-form-item>
|
||
<el-form-item label="BOM版本" prop="bomVersion">
|
||
<el-input v-model="formData.bomVersion" placeholder="请输入BOM版本" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="cancel">{{ $t('btn.cancel') }}</el-button>
|
||
<el-button type="primary" @click="submitForm">{{ $t('btn.submit') }}</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- 子件编辑弹窗 -->
|
||
<el-dialog :title="subDialog.title" v-model="subDialog.visible" width="600px" append-to-body draggable
|
||
:close-on-click-modal="false">
|
||
<el-form ref="subEditFormRef" :model="subFormData" :rules="subRules" label-width="120px">
|
||
<el-form-item label="子件编码" prop="subInvCode">
|
||
<el-input v-model="subFormData.subInvCode" placeholder="请输入子件编码" />
|
||
</el-form-item>
|
||
<el-form-item label="子件名称" prop="subInvName">
|
||
<el-input v-model="subFormData.subInvName" placeholder="请输入子件名称" />
|
||
</el-form-item>
|
||
<el-form-item label="使用数量" prop="iusequantity">
|
||
<el-input-number v-model="subFormData.iusequantity" :min="0" :precision="2" placeholder="请输入使用数量" />
|
||
</el-form-item>
|
||
<el-form-item label="BOM版本" prop="bomVersion">
|
||
<el-input v-model="subFormData.bomVersion" placeholder="请输入BOM版本" />
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="cancelSub">{{ $t('btn.cancel') }}</el-button>
|
||
<el-button type="primary" @click="submitSubForm">{{ $t('btn.submit') }}</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- 导入对话框 -->
|
||
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body draggable
|
||
:close-on-click-modal="false">
|
||
<span v-if="show">数据正在导入中请稍等……</span>
|
||
<el-upload name="file" ref="uploadRef" :limit="1" accept=".xlsx,.xls" :headers="upload.headers"
|
||
:action="`${upload.url}`" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress"
|
||
:on-success="handleFileSuccess" :on-error="handleFileError" :auto-upload="false" drag>
|
||
<el-icon class="el-icon--upload">
|
||
<upload-filled />
|
||
</el-icon>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<template #tip>
|
||
<div class="el-upload__tip text-center">
|
||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline"
|
||
@click="importTemplate">下载模板</el-link>
|
||
</div>
|
||
</template>
|
||
</el-upload>
|
||
<template #footer>
|
||
<el-button @click="upload.open = false">{{ $t('btn.cancel') }}</el-button>
|
||
<el-button type="primary" @click="submitFileForm">{{ $t('btn.submit') }}</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup name="BaseMaterialBOM">
|
||
import { listBaseMaterialBom, GetMonterInvList, GetSonInvList, updateBaseMaterialBom } from '@/api/baseManagement/basematerialBOM.js'
|
||
import { addBaseMaterialBom, updateBaseMaterialBom as updateMainBom } from '@/api/baseManagement/basematerialBOM.js'
|
||
import useUserStore from '@/store/modules/user'
|
||
const userStore = useUserStore()
|
||
const userName = userStore.userName
|
||
const { proxy } = getCurrentInstance()
|
||
const ids = ref([])
|
||
const loading = ref(false)
|
||
const showSearch = ref(true)
|
||
|
||
// 弹窗相关数据
|
||
const dialog = reactive({
|
||
title: '',
|
||
visible: false,
|
||
isEdit: false
|
||
})
|
||
|
||
const subDialog = reactive({
|
||
title: '',
|
||
visible: false,
|
||
isEdit: false
|
||
})
|
||
|
||
const formData = ref({})
|
||
const subFormData = ref({})
|
||
|
||
const editFormRef = ref()
|
||
const subEditFormRef = ref()
|
||
|
||
const queryParams = reactive({
|
||
invCode: '',
|
||
subInvCode: '',
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
sort: 'createdTime',
|
||
sortType: 'desc'
|
||
})
|
||
|
||
const total = ref(0)
|
||
const dataList = ref([])
|
||
const tableRef = ref() // 添加表格引用
|
||
const queryRef = ref()
|
||
|
||
// 主件表单验证规则
|
||
const rules = {
|
||
invCode: [
|
||
{ required: true, message: '母件编码不能为空', trigger: 'blur' }
|
||
],
|
||
invName: [
|
||
{ required: true, message: '母件名称不能为空', trigger: 'blur' }
|
||
],
|
||
bomVersion: [
|
||
{ required: true, message: 'BOM版本不能为空', trigger: 'blur' }
|
||
]
|
||
}
|
||
|
||
// 子件表单验证规则
|
||
const subRules = {
|
||
subInvCode: [
|
||
{ required: true, message: '子件编码不能为空', trigger: 'blur' }
|
||
],
|
||
subInvName: [
|
||
{ required: true, message: '子件名称不能为空', trigger: 'blur' }
|
||
],
|
||
iusequantity: [
|
||
{ required: true, message: '使用数量不能为空', trigger: 'blur' },
|
||
{ type: 'number', message: '使用数量必须为数字值', trigger: 'blur' }
|
||
],
|
||
bomVersion: [
|
||
{ required: true, message: 'BOM版本不能为空', trigger: 'blur' }
|
||
]
|
||
}
|
||
|
||
// 初始化表单数据
|
||
function resetForm() {
|
||
formData.value = {
|
||
id: undefined,
|
||
invCode: '',
|
||
invName: '',
|
||
bomVersion: '',
|
||
createdBy: userName,
|
||
updatedBy: userName
|
||
}
|
||
editFormRef.value?.clearValidate()
|
||
}
|
||
|
||
function resetSubForm() {
|
||
subFormData.value = {
|
||
id: undefined,
|
||
subInvCode: '',
|
||
subInvName: '',
|
||
iusequantity: 0,
|
||
bomVersion: ''
|
||
}
|
||
subEditFormRef.value?.clearValidate()
|
||
}
|
||
|
||
// 获取数据列表
|
||
function getList() {
|
||
loading.value = true
|
||
GetMonterInvList(queryParams).then((res) => {
|
||
const { code, data } = res
|
||
if (code == 200) {
|
||
dataList.value = data.result
|
||
total.value = data.totalNum
|
||
loading.value = false
|
||
}
|
||
})
|
||
}
|
||
|
||
// 获取选中的行数据
|
||
function getSelectedRows() {
|
||
if (tableRef.value) {
|
||
const selectedRows = tableRef.value.getCheckboxRecords()
|
||
console.log('选中的行数据:', selectedRows)
|
||
return selectedRows
|
||
}
|
||
return []
|
||
}
|
||
|
||
// 处理单个复选框选中状态变化
|
||
function handleSelectionChange() {
|
||
const selectedRows = tableRef.value.getCheckboxRecords()
|
||
ids.value = selectedRows.map(row => row.id) // 假设有id字段
|
||
console.log('当前选中项ID:', ids.value)
|
||
}
|
||
|
||
// 处理全选/取消全选
|
||
function handleSelectAll({ records }) {
|
||
ids.value = records.map(row => row.id) // 假设有id字段
|
||
console.log('全选/取消全选后ID:', ids.value)
|
||
}
|
||
|
||
// 编辑主件
|
||
function handleEdit(row) {
|
||
resetForm()
|
||
const { id, invCode, invName, bomVersion } = row
|
||
formData.value = { id, invCode, invName, bomVersion }
|
||
dialog.title = '修改主件信息'
|
||
dialog.visible = true
|
||
dialog.isEdit = true
|
||
}
|
||
|
||
// 编辑子件
|
||
function handleSubEdit(row) {
|
||
resetSubForm()
|
||
const { id, subInvCode, subInvName, iusequantity, bomVersion } = row
|
||
subFormData.value = { id, subInvCode, subInvName, iusequantity, bomVersion }
|
||
subDialog.title = '修改子件信息'
|
||
subDialog.visible = true
|
||
subDialog.isEdit = true
|
||
}
|
||
|
||
// 提交主件表单
|
||
function submitForm() {
|
||
editFormRef.value.validate(valid => {
|
||
if (valid) {
|
||
if (dialog.isEdit) {
|
||
// 更新现有记录
|
||
updateBaseMaterialBom(formData.value).then(res => {
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('修改成功')
|
||
dialog.visible = false
|
||
resetForm()
|
||
getList()
|
||
}
|
||
})
|
||
} else {
|
||
// 添加新记录
|
||
addBaseMaterialBom(formData.value).then(res => {
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('新增成功')
|
||
dialog.visible = false
|
||
resetForm()
|
||
getList()
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 提交子件表单
|
||
function submitSubForm() {
|
||
subEditFormRef.value.validate(valid => {
|
||
if (valid) {
|
||
if (subDialog.isEdit) {
|
||
// 更新现有记录
|
||
updateBaseMaterialBom(subFormData.value).then(res => {
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('修改成功')
|
||
subDialog.visible = false
|
||
resetSubForm()
|
||
// 刷新父级数据
|
||
getList()
|
||
}
|
||
})
|
||
} else {
|
||
// 添加新记录
|
||
// 注意:这里可能需要不同的API接口,根据实际业务调整
|
||
addBaseMaterialBom(subFormData.value).then(res => {
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('新增成功')
|
||
subDialog.visible = false
|
||
resetSubForm()
|
||
getList()
|
||
}
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 取消主件编辑
|
||
function cancel() {
|
||
dialog.visible = false
|
||
resetForm()
|
||
}
|
||
|
||
// 取消子件编辑
|
||
function cancelSub() {
|
||
subDialog.visible = false
|
||
resetSubForm()
|
||
}
|
||
|
||
// 删除子件
|
||
function handleSubDelete(row) {
|
||
proxy.$modal.confirm('确认删除该子件数据?')
|
||
.then(() => {
|
||
// 实现删除逻辑
|
||
console.log('删除子件数据:', row.id)
|
||
// 示例API调用
|
||
// return deleteById(row.id)
|
||
})
|
||
.then(() => {
|
||
proxy.$modal.msgSuccess('删除成功')
|
||
getList()
|
||
})
|
||
}
|
||
|
||
|
||
|
||
// 删除单行
|
||
function handleDelete(row) {
|
||
proxy.$modal.confirm('确认删除该条数据?')
|
||
.then(() => {
|
||
// 实现删除逻辑
|
||
console.log('删除行数据:', row.id)
|
||
// 示例API调用
|
||
// return deleteById(row.id)
|
||
})
|
||
.then(() => {
|
||
proxy.$modal.msgSuccess('删除成功')
|
||
getList()
|
||
})
|
||
}
|
||
|
||
// 子数据懒加载
|
||
function loadContentMethod({ row }) {
|
||
return new Promise((resolve) => {
|
||
GetSonInvList({ invCode: row.invCode }).then((res) => {
|
||
if (res.code === 200) {
|
||
row.children = res.data
|
||
resolve()
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
function getToken() {
|
||
return localStorage.getItem('token') || '';
|
||
}
|
||
|
||
// 导入参数
|
||
const upload = reactive({
|
||
open: false,
|
||
title: '',
|
||
// isUploading: false,
|
||
updateSupport: 0,
|
||
uploadType: 1,
|
||
headers: { Authorization: 'Bearer ' + getToken() },
|
||
url: import.meta.env.VITE_APP_BASE_API + '/MasterDataManagement/Material/MaterialBom/importData'
|
||
})
|
||
|
||
function handleImport(type) {
|
||
upload.title = '导入'
|
||
upload.open = true
|
||
}
|
||
|
||
//导出
|
||
function handleDownload() {
|
||
proxy
|
||
.$confirm('是否确定要导出数据吗?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
await proxy.downFile('/MasterDataManagement/Material/MaterialBom/exportData', { ...queryParams })
|
||
})
|
||
}
|
||
|
||
function submitFileForm() {
|
||
proxy.$refs['uploadRef'].submit()
|
||
}
|
||
|
||
//下砸模版
|
||
function importTemplate() {
|
||
proxy.download('/MasterDataManagement/Material/MaterialBom/importTemplate', '物料类别导入模板')
|
||
}
|
||
|
||
/** 文件上传异常处理 */
|
||
const handleFileError = (error, file, fileList) => {
|
||
// 修复:使用正确的响应对象
|
||
if (error) {
|
||
proxy.$message.error('模板导入异常!')
|
||
return
|
||
}
|
||
}
|
||
|
||
const show = ref(false)
|
||
const handleFileUploadProgress = (event, file, fileList) => {
|
||
upload.isUploading = true,
|
||
show.value = true
|
||
}
|
||
|
||
const dialogVisibleActualAssembly = ref(false)
|
||
|
||
/** 文件上传成功处理 */
|
||
const handleFileSuccess = (response, file, fileList) => {
|
||
|
||
const { code, msg, data } = response
|
||
if (code === 500) {
|
||
proxy.$message.error('模板存在异常!')
|
||
upload.isUploading = false
|
||
proxy.$refs['uploadRef'].clearFiles()
|
||
return
|
||
}
|
||
if (data === -1) {
|
||
proxy.$message.error('模板不匹配!')
|
||
upload.isUploading = false
|
||
proxy.$refs['uploadRef'].clearFiles()
|
||
return
|
||
}
|
||
|
||
upload.open = false
|
||
getList()
|
||
show.value = false
|
||
upload.isUploading = false
|
||
proxy.$refs['uploadRef'].clearFiles()
|
||
dialogVisibleActualAssembly.value = true
|
||
}
|
||
|
||
// 查询
|
||
function handleQuery() {
|
||
queryParams.pageNum = 1
|
||
getList()
|
||
}
|
||
|
||
// 重置查询操作
|
||
function resetQuery() {
|
||
proxy.resetForm('queryRef')
|
||
handleQuery()
|
||
}
|
||
|
||
// 自定义排序
|
||
function sortChange(column) {
|
||
var sort = undefined
|
||
var sortType = undefined
|
||
|
||
if (column.prop != null && column.order != null) {
|
||
sort = column.prop
|
||
sortType = column.order
|
||
}
|
||
queryParams.sort = sort
|
||
queryParams.sortType = sortType
|
||
handleQuery()
|
||
}
|
||
|
||
/// ======================= 数据同步 =============================
|
||
import { SynchERPBOM } from '@/api/erp/baseInteractERP.js'
|
||
const throttle = ref(false)
|
||
const syncLoading = ref(false)
|
||
|
||
function handleSync() {
|
||
syncLoading.value = true
|
||
throttle.value = true
|
||
setTimeout(() => {
|
||
throttle.value = false
|
||
}, 1000 * 60)
|
||
SynchERPBOM().then((res) => {
|
||
if (res.code === 200) {
|
||
proxy.$modal.msgSuccess('同步成功')
|
||
handleQuery()
|
||
syncLoading.value = false
|
||
} else {
|
||
proxy.$message.error('同步失败')
|
||
}
|
||
})
|
||
}
|
||
/// =================================================================
|
||
|
||
handleQuery()
|
||
</script> |