<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 type="primary"
|
@click="submitForm"
|
:loading="formLoading">确定</el-button>
|
<el-button @click="dialogVisible = false"
|
:disabled="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>
|