<template>
|
<div class="spare-part-category">
|
<div class="table_list">
|
<div class="actions">
|
<el-text class="mx-1" size="large">设备分类</el-text>
|
<div>
|
<el-button @click="fetchTreeData" :loading="loading">刷新</el-button>
|
<el-button type="primary" @click="addCategory" >新增</el-button>
|
</div>
|
</div>
|
<el-table
|
v-loading="loading"
|
:data="renderTableData"
|
style="width: 100%; margin-top: 10px;"
|
border
|
row-key="id"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
>
|
<el-table-column prop="name" label="分类名称" width="450">
|
<template #default="{ row }">
|
<span :style="{ paddingLeft: getIndentation(row) + 'px' }">
|
{{ row.name }}
|
</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="sparePartsNo" label="分类编号" width="200"></el-table-column>
|
<el-table-column prop="status" label="状态" width="100">
|
<template #default="{ row }">
|
<el-tag type="success" size="small">{{ row.status }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="description" label="描述" win-width="330"></el-table-column>
|
<el-table-column label="操作" width="180" fixed="right">
|
<template #default="{ row }">
|
<el-button
|
type="text"
|
size="small"
|
@click="() => editCategory(row)"
|
:disabled="loading"
|
>
|
编辑
|
</el-button>
|
<el-button
|
type="text"
|
size="small"
|
@click="() => deleteCategory(row.id)"
|
style="color: #f56c6c;"
|
:disabled="loading"
|
>
|
删除
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
<el-dialog title="分类管理" v-model="dialogVisible" width="60%">
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
|
<el-form-item label="分类名称" prop="name">
|
<el-input v-model="form.name"></el-input>
|
</el-form-item>
|
<el-form-item label="分类编号" prop="sparePartsNo">
|
<el-input v-model="form.sparePartsNo"></el-input>
|
</el-form-item>
|
<el-form-item label="状态" prop="status">
|
<el-select v-model="form.status" placeholder="请选择状态">
|
<el-option label="正常" value="正常"></el-option>
|
<el-option label="禁用" value="禁用"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="描述" prop="description">
|
<el-input v-model="form.description"></el-input>
|
</el-form-item>
|
<el-form-item label="上级分类" prop="parentId">
|
<el-select v-model="form.parentId" placeholder="请选择上级分类">
|
<el-option label="无上级分类" :value="null"></el-option>
|
<el-option
|
v-for="(item, index) in categories"
|
:key="index"
|
:label="item.name"
|
:value="item.id"
|
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="dialogVisible = false" :disabled="formLoading">取消</el-button>
|
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, computed, onMounted, reactive, watch } from 'vue';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { getSparePartsList, addSparePart, editSparePart, delSparePart,getSparePartsTree } from "@/api/equipmentManagement/spareParts";
|
|
// 加载状态
|
const loading = ref(false);
|
const formLoading = ref(false);
|
// 对话框显示状态
|
const dialogVisible = ref(false);
|
// 编辑 ID
|
const editId = ref(null);
|
// 表格数据
|
const categories = ref([]);
|
// 渲染用的表格数据
|
// const renderTableData = computed(() => buildTree(categories.value));
|
const renderTableData = ref([]);
|
const operationType = ref('add')
|
// 表单引用
|
const formRef = ref(null);
|
// 表单数据
|
const form = reactive({
|
id:'',
|
name: '',
|
sparePartsNo: '',
|
status: '',
|
description: '',
|
parentId: null
|
});
|
|
// 表单验证规则
|
const rules = reactive({
|
name: [
|
{ required: true, message: '请输入分类名称', trigger: 'blur' }
|
],
|
sparePartsNo: [
|
{ required: true, message: '请输入分类编号', trigger: 'blur' }
|
],
|
status: [
|
{ required: true, message: '请选择状态', trigger: 'change' }
|
]
|
});
|
// 获取缩进量
|
const getIndentation = (row) => {
|
// 这里简单返回 20,可根据实际需求实现层级缩进逻辑
|
return 20;
|
};
|
// 定义 buildTree 函数
|
const buildTree = (flatData) => {
|
const map = {};
|
const result = [];
|
if(flatData){
|
return result;
|
}
|
flatData.forEach(item => {
|
map[item.id] = { ...item, children: [] };
|
});
|
flatData.forEach(item => {
|
if (item.parentId === null || !map[item.parentId]) {
|
result.push(map[item.id]);
|
} else {
|
map[item.parentId].children.push(map[item.id]);
|
}
|
});
|
return result;
|
};
|
//获取树形结构
|
const fetchTreeData = async () => {
|
fetchCategories();
|
try {
|
const res = await getSparePartsTree();
|
if (res.code === 200) {
|
renderTableData.value = res.data;
|
} else {
|
ElMessage.error(res.message || '获取分类列表失败');
|
}
|
}catch (error) {
|
ElMessage.error('获取分类列表失败');
|
}
|
}
|
|
// 获取分类列表
|
const fetchCategories = async () => {
|
loading.value = true;
|
try {
|
const res = await getSparePartsList();
|
if (res.code === 200) {
|
categories.value = res.data.records;
|
} else {
|
ElMessage.error(res.message || '获取分类列表失败');
|
}
|
} catch (error) {
|
ElMessage.error('获取分类列表失败');
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
// 新增分类
|
const addCategory = () => {
|
form.id = '';
|
form.name = '';
|
form.sparePartsNo = '';
|
form.status = '';
|
form.description = '';
|
form.parentId = null;
|
operationType.value = 'add'
|
dialogVisible.value = true;
|
console.log('dialogVisible 更新为', dialogVisible.value);
|
};
|
|
// 编辑分类
|
const editCategory = (row) => {
|
Object.assign(form, row);
|
operationType.value = 'edit'
|
dialogVisible.value = true;
|
};
|
|
// 删除分类
|
const deleteCategory = async (id) => {
|
try {
|
await ElMessageBox.confirm('此操作将永久删除该分类,是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
});
|
loading.value = true;
|
const res = await delSparePart(id);
|
if (res.code === 200) {
|
ElMessage.success('删除成功');
|
fetchTreeData();
|
} else {
|
ElMessage.error(res.message || '删除失败');
|
}
|
} catch (error) {
|
if (error !== 'cancel') {
|
ElMessage.error('删除失败');
|
}
|
} finally {
|
loading.value = false;
|
}
|
};
|
|
// 提交表单
|
const submitForm = async () => {
|
if (!formRef.value) return;
|
try {
|
await formRef.value.validate();
|
formLoading.value = true;
|
if (operationType.value === 'edit') {
|
let res = await editSparePart(form);
|
if (res.code === 200) {
|
ElMessage.success('编辑成功');
|
dialogVisible.value = false;
|
fetchTreeData();
|
}
|
} else {
|
let res = await addSparePart(form);
|
if (res.code === 200) {
|
ElMessage.success('编辑成功');
|
dialogVisible.value = false;
|
fetchTreeData();
|
}
|
}
|
} catch (error) {
|
ElMessage.error('请填写完整表单信息');
|
} finally {
|
formLoading.value = false;
|
}
|
};
|
|
// 组件挂载时获取分类列表
|
onMounted(() => {
|
fetchCategories();
|
fetchTreeData();
|
});
|
</script>
|
|
<style scoped>
|
.spare-part-category {
|
padding: 20px;
|
}
|
.table_list {
|
margin-top: unset;
|
}
|
.actions {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
align-items: center;
|
}
|
|
/* 嵌套树形结构样式 */
|
.nested-tree-node {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
width: 100%;
|
padding: 0 4px;
|
height: 30px;
|
line-height: 30px;
|
}
|
|
.category-code {
|
color: #606266;
|
font-size: 12px;
|
margin-left: 8px;
|
}
|
|
.tree-actions {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
margin-left: auto;
|
}
|
|
/* 表格样式调整 */
|
.el-table {
|
font-size: 14px;
|
}
|
|
.el-table__header-wrapper th {
|
background-color: #f5f7fa;
|
font-weight: 600;
|
}
|
|
.el-table__row:hover > td {
|
background-color: #fafafa;
|
}
|
|
/* 嵌套树形结构特定样式 */
|
.nested-tree {
|
background-color: transparent;
|
}
|
|
.nested-tree .el-tree-node__content {
|
height: auto;
|
background-color: transparent;
|
}
|
|
/* 搜索框样式调整 */
|
.actions .el-input {
|
margin-right: 10px;
|
width: 200px;
|
}
|
|
/* 按钮组样式 */
|
.actions > div {
|
display: flex;
|
gap: 10px;
|
}
|
|
/* 确保表格中的操作按钮不会被截断 */
|
.el-table-column--fixed-right .el-button {
|
margin: 0 2px;
|
}
|
|
/* 树形节点内容样式 */
|
.nested-tree .el-tree-node__expand-icon {
|
font-size: 12px;
|
margin-right: 4px;
|
}
|
|
/* 空状态样式 */
|
.el-table .cell:empty::before {
|
content: '-';
|
color: #c0c4cc;
|
}
|
|
/* 展开/折叠功能样式 */
|
.expand-icon {
|
display: inline-block;
|
width: 20px;
|
height: 20px;
|
text-align: center;
|
line-height: 20px;
|
cursor: pointer;
|
font-size: 12px;
|
color: #909399;
|
}
|
|
.expand-icon.expanded {
|
color: #409eff;
|
}
|
|
/* 展开内容样式 */
|
.expand-content {
|
padding: 10px 20px;
|
}
|
|
/* 子级内容样式 */
|
.child-content {
|
padding-left: 40px;
|
}
|
|
/* 无子分类提示样式 */
|
.no-children {
|
padding: 10px 20px;
|
color: #909399;
|
font-size: 14px;
|
}
|
|
/* 确保展开的表格样式正确 */
|
.el-table .el-table__expanded-cell {
|
background-color: #fafafa;
|
}
|
|
/* 展开的子表格样式 */
|
.el-table .el-table {
|
border-top: none;
|
border-bottom: none;
|
}
|
|
/* 展开的子表格单元格样式 */
|
.expand-content .el-table__body-wrapper .el-table__row {
|
background-color: #ffffff;
|
}
|
|
.expand-content .el-table__body-wrapper .el-table__row:hover > td {
|
background-color: #fafafa;
|
}
|
</style>
|