You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

470 lines
16 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="p-2">
<el-row :gutter="20">
<!-- bom结构树 -->
<el-col :lg="4" :xs="24" style="" v-loading="treeLoading">
<el-card shadow="hover">
<el-input v-model="materialTypeName" placeholder="请输入物料类型名称" prefix-icon="Search" clearable/>
<el-tree
ref="structureBomTreeRef"
class="mt-2"
node-key="id"
:data="structureBomOptions"
:props="{ label: 'label', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</el-card>
</el-col>
<el-col :lg="20" :xs="24" v-loading="loading">
<el-divider content-position="left">物料类型</el-divider>
<el-form ref="parentStructureBomFormRef" label-width="120px">
<el-row>
<el-form-item label="父级物料类型">
{{ parentParentMaterialTypeName }}
</el-form-item>
<el-form-item label="物料类型">
{{ parentMaterialTypeName }}
</el-form-item>
</el-row>
</el-form>
<el-divider content-position="left">子级物料类型</el-divider>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="物料类型编号" prop="materialTypeCode" label-width="120px">
<el-input v-model="queryParams.materialTypeCode" placeholder="请输入物料类型编号" clearable
@keyup.enter="handleQuery"/>
</el-form-item>
<el-form-item label="物料类型名称" prop="materialTypeName" label-width="120px">
<el-input v-model="queryParams.materialTypeName" placeholder="请输入物料类型名称" clearable
@keyup.enter="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="hover">
<template #header>
<el-row :gutter="10">
<el-col :span="1.5">
<el-button v-has-permi="['mes:baseStructureBom:add']" type="primary" plain icon="Plus"
@click="handleAdd()">新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-has-permi="['mes:baseStructureBom:edit']" type="success" plain :disabled="single"
icon="Edit" @click="handleUpdate()">
修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-has-permi="['mes:baseStructureBom:remove']" type="danger" plain :disabled="multiple"
icon="Delete" @click="handleDelete()">
删除
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true"
@query-table="getList"></right-toolbar>
</el-row>
</template>
<el-table :data="structureBomList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center"/>
<el-table-column v-if="columns[0].visible" key="structureBomId" label="BOM结构编号" align="center"
prop="structureBomId"/>
<el-table-column v-if="columns[1].visible" key="materialTypeCode" label="物料类型编号" align="center"
prop="materialTypeCode" :show-overflow-tooltip="true"/>
<el-table-column v-if="columns[2].visible" key="materialTypeName" label="物料类型名称" align="center"
prop="materialTypeName" :show-overflow-tooltip="true"/>
<el-table-column v-if="columns[3].visible" label="创建时间" align="center" prop="createTime" width="160">
<template #default="scope">
<span>{{ scope.row.createTime }}</span>
</template>
</el-table-column>
<el-table-column v-if="columns[3].visible" label="更新时间" align="center" prop="updateTime" width="160">
<template #default="scope">
<span>{{ scope.row.updateTime }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button v-hasPermi="['mes:baseStructureBom:edit']" link type="primary" icon="Edit"
@click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button v-hasPermi="['mes:baseStructureBom:remove']" link type="primary" icon="Delete"
@click="handleDelete(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<!-- <pagination-->
<!-- v-show="total > 0"-->
<!-- v-model:page="queryParams.pageNum"-->
<!-- v-model:limit="queryParams.pageSize"-->
<!-- :total="total"-->
<!-- @pagination="getList"-->
<!-- />-->
</el-card>
</el-col>
</el-row>
<!-- 添加或修改物料类型bom结构树配置对话框 -->
<el-dialog ref="formDialogRef" v-model="dialog.visible" :title="dialog.title" width="600px" append-to-body
@close="closeDialog">
<el-form ref="structureBomFormRef" :model="form" :rules="rules" label-width="90px">
<el-form-item label="物料类型">
{{ parentMaterialTypeName }}
</el-form-item>
<el-form-item label="子物料类型">
<el-select v-model="form.materialTypeId" placeholder="请选择">
<el-option
v-for="item in materialTypeOptions"
:key="item.matrialTypeId"
:label="item.matrialTypeName"
:value="item.matrialTypeId"
:disabled="item.activeFlag == '0' || item.matrialTypeId === form.parentId"
></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm" :loading="submitLoading"> </el-button>
<el-button @click="cancel()"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="BaseStructureBom" lang="ts">
import {
structureBomTreeSelect,
listBaseStructureBom,
getBaseStructureBom,
delBaseStructureBom,
addBaseStructureBom,
updateBaseStructureBom, getMaterialTypeList
} from "@/api/mes/baseStructureBom";
import {BaseStructureBomVO, BaseStructureBomTreeVO,BaseStructureBomQuery, BaseStructureBomForm} from '@/api/mes/baseStructureBom/types';
import {BaseMaterialTypeVO} from '@/api/mes/baseMaterialType/types';
import {to} from 'await-to-js';
import {nextTick} from "vue";
const router = useRouter();
const {proxy} = getCurrentInstance() as ComponentInternalInstance;
const {sys_normal_disable, sys_user_sex} = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
const structureBomList = ref<BaseStructureBomVO[]>();
const treeLoading = ref(false);
const loading = ref(false);
const submitLoading = ref(false);
const showSearch = ref(true);
const ids = ref<Array<number | string>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
const materialTypeName = ref('');
const structureBomOptions = ref<BaseStructureBomTreeVO[]>([]);
const materialTypeOptions = ref<BaseMaterialTypeVO[]>([]);
const parentMaterialTypeName = ref('');
const parentParentMaterialTypeName = ref('');
// 列显隐信息
const columns = ref<FieldOption[]>([
{key: 0, label: `BOM结构编号`, visible: true, children: []},
{key: 1, label: `物料类型编号`, visible: true, children: []},
{key: 2, label: `物料类型名称`, visible: true, children: []},
{key: 3, label: `创建时间`, visible: true, children: []},
{key: 4, label: `更新时间`, visible: true, children: []}
]);
const structureBomTreeRef = ref<ElTreeInstance>();
const queryFormRef = ref<ElFormInstance>();
const structureBomFormRef = ref<ElFormInstance>();
const formDialogRef = ref<ElDialogInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: BaseStructureBomForm = {
structureBomId: undefined,
parentId: undefined,
materialTypeId: undefined,
materialTypeName: undefined,
structureBomDesc: undefined,
structureBomVersion: undefined,
ancestors: undefined,
level: undefined,
topFlag: undefined,
activeFlag: '1',
remark: undefined,
}
const data = reactive<PageData<BaseStructureBomForm, BaseStructureBomQuery>>({
form: {...initFormData},
queryParams: {
structureBomId: undefined,
parentId: undefined,
materialTypeId: undefined,
materialTypeName: undefined,
structureBomDesc: undefined,
structureBomVersion: undefined,
ancestors: undefined,
level: undefined,
topFlag: undefined,
activeFlag: undefined,
materialTypeCode: undefined,
params: {}
},
rules: {
materialTypeId: [
{required: true, message: "物料类型不能为空", trigger: "blur"}
]
}
});
const {queryParams, form, rules} = toRefs(data);
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
structureBomTreeRef.value?.filter(materialTypeName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发此属性控制在DOM元素更新后运行
}
);
/** 查询物料类型bom结构树下拉树结构 */
const getTreeSelect = async () => {
treeLoading.value = true;
loading.value = true;
const res = await structureBomTreeSelect();
// structureBomOptions.value = res.data;
structureBomOptions.value = [];
const initialTree: BaseStructureBomTreeVO = {
id: 1,
parentId: -1,
materialTypeId: 0,
label: "制造BOM结构",
children: res.data
};
structureBomOptions.value.push(initialTree);
console.log(structureBomOptions);
if (queryParams.value.parentId === null || queryParams.value.parentId === undefined) {
const topStructureBom = structureBomOptions.value.find(item => item.parentId === -1);
if (topStructureBom != null){
parentMaterialTypeName.value = topStructureBom.label;
}
queryParams.value.parentId = 1;
parentParentMaterialTypeName.value = "顶级";
}
nextTick(function () {
structureBomTreeRef.value?.setCurrentKey(queryParams.value.parentId, true);
handleQuery();
})
// const dd = {"id":"1","parentId":-1,"label":"dd"};
// alert(materialTypeOptions.value[0])
// materialTypeOptions.value[0].children.push(dd);
};
/** 查询用户列表 */
const getList = async () => {
loading.value = true;
const res = await listBaseStructureBom(queryParams.value);
// alert(JSON.stringify(res))
structureBomList.value = res.data;
loading.value = false;
treeLoading.value = false;
// total.value = res.total;
};
/** 节点单击事件 */
const handleNodeClick = (data: BaseStructureBomTreeVO) => {
queryParams.value.parentId = data.id;
parentMaterialTypeName.value = data.label;
if (data.parentId === -1) {
parentParentMaterialTypeName.value = "顶级";
} else if (data.parentId === 1) {
parentParentMaterialTypeName.value = "制造BOM结构";
} else {
const findMaterialType = materialTypeOptions.value.find(item => item.matrialTypeId === data.parentId);
parentParentMaterialTypeName.value = findMaterialType.matrialTypeName;
}
handleQuery();
};
/** 搜索按钮操作 */
const handleQuery = () => {
// queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
// dateRange.value = ['', ''];
queryFormRef.value?.resetFields();
// queryParams.value.pageNum = 1;
// queryParams.value.parentId = undefined;
// structureBomTreeRef.value?.setCurrentKey(undefined);
handleQuery();
};
/** 删除按钮操作 */
const handleDelete = async (row?: BaseStructureBomVO) => {
const structureBomIds = row?.structureBomId || ids.value;
const [err] = await to(proxy?.$modal.confirm('是否确认删除BOM结构编号为"' + structureBomIds + '"的数据项?') as any);
if (!err) {
await delBaseStructureBom(structureBomIds)
await getTreeSelect();
handleQuery();
proxy?.$modal.msgSuccess('删除成功');
}
};
/** 选择条数 */
const handleSelectionChange = (selection: BaseStructureBomVO[]) => {
ids.value = selection.map((item) => item.structureBomId);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 初始化物料类型数据 */
const initMaterialTypeData = async () => {
// 判断物料类型结构树的数据是否存在,存在不获取,不存在则获取
// alert(JSON.stringify(materialTypeOptions))
// alert(materialTypeOptions.value)
if (materialTypeOptions.value === undefined || materialTypeOptions.value.length <= 0) {
const {data} = await getMaterialTypeList();
// alert(JSON.stringify(data))
materialTypeOptions.value = data;
}
};
/** 重置操作表单 */
const reset = () => {
form.value = {...initFormData};
structureBomFormRef.value?.resetFields();
};
/** 取消按钮 */
const cancel = () => {
dialog.visible = false;
reset();
};
/** 新增按钮操作 */
const handleAdd = async () => {
reset();
// alert(JSON.stringify(data))
dialog.visible = true;
dialog.title = '新增';
await initMaterialTypeData();
form.value.parentId = queryParams.value.parentId;
};
/** 修改按钮操作 */
const handleUpdate = async (row?: BaseStructureBomForm) => {
reset();
const structureBomId = row?.structureBomId || ids.value[0];
const res = await getBaseStructureBom(structureBomId);
await initMaterialTypeData();
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = "修改";
// alert(JSON.stringify(res.data))
// form.value.materialTypeId = res.data.matrialTypeId;
};
/** 提交按钮 */
const submitForm = () => {
structureBomFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
submitLoading.value = true;
// alert(JSON.stringify(materialTypeOptions.value))
const findMaterialType = materialTypeOptions.value.find(item => item.matrialTypeId === form.value.materialTypeId);
form.value.materialTypeName = findMaterialType.matrialTypeName;
try {
form.value.structureBomId ? await updateBaseStructureBom(form.value) : await addBaseStructureBom(form.value);
proxy?.$modal.msgSuccess('操作成功');
await getTreeSelect();
handleQuery();
dialog.visible = false;
submitLoading.value = false;
} catch {
submitLoading.value = false;
}
// const child = {"id":"1","parentId":-1,"label":"dd"};
// alert(materialTypeOptions.value[0])
// materialTypeOptions.value[0].children.push(dd);
}
});
};
/**
* 关闭用户弹窗
*/
const closeDialog = () => {
dialog.visible = false;
resetForm();
};
/**
* 重置表单
*/
const resetForm = () => {
structureBomFormRef.value?.resetFields();
structureBomFormRef.value?.clearValidate();
form.value.structureBomId = undefined;
form.value.activeFlag = '1';
};
onMounted(() => {
getTreeSelect(); // 初始化物料类型结构bom数据
initMaterialTypeData();
});
// async function handleDeptChange(value: number | string) {
// const response = await optionselect(value);
// materialTypeOptions.value = response.data;
// form.value.postIds = [];
// }
</script>
<style lang="scss" scoped></style>