From 2cef58b7041dcbd94e0c385ca690bd6adfebdefc Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期四, 18 九月 2025 11:39:00 +0800
Subject: [PATCH] 设备管理-备件管理,-缺陷管理页面

---
 src/views/equipmentManagement/spareParts/index.vue       |  417 ++++++++++++++++++++++++++++++++
 src/api/equipmentManagement/spareParts.js                |   58 ++++
 src/api/equipmentManagement/defectManagement.js          |   44 +++
 src/views/equipmentManagement/defectManagement/index.vue |  221 +++++++++++++++++
 4 files changed, 740 insertions(+), 0 deletions(-)

diff --git a/src/api/equipmentManagement/defectManagement.js b/src/api/equipmentManagement/defectManagement.js
new file mode 100644
index 0000000..c52eff9
--- /dev/null
+++ b/src/api/equipmentManagement/defectManagement.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request';
+
+// 鐧昏缂洪櫡
+export function registerDefect(data) {
+  return request({
+    url: '/defect/add',
+    method: 'post',
+    data
+  });
+}
+
+// 鑾峰彇缂洪櫡鍒楄〃
+export function getDefectList() {
+  return request({
+    url: '/defect/page',
+    method: 'get'
+  });
+}
+
+// 娑堥櫎缂洪櫡-淇敼鐘舵��
+export function eliminateDefect(data) {
+  return request({
+    url: '/defect/update',
+    method: 'post',
+    data
+  });
+}
+//鍒犻櫎
+export function deleteDefect(id) {
+  return request({
+    url: '/defect/delete',
+    method: 'delete',
+    id
+  });
+}
+
+
+// 鑾峰彇缂洪櫡璁惧鍙拌处
+export function getDefectLedger(deviceLedgerId) {
+  return request({
+    url: '/defect//find/' + deviceLedgerId,
+    method: 'get'
+  });
+}
\ No newline at end of file
diff --git a/src/api/equipmentManagement/spareParts.js b/src/api/equipmentManagement/spareParts.js
new file mode 100644
index 0000000..2b64689
--- /dev/null
+++ b/src/api/equipmentManagement/spareParts.js
@@ -0,0 +1,58 @@
+import request from "@/utils/request";
+/**
+ *  澶囦欢鍒嗙被-鏍戝垪琛�
+ */
+export const getSparePartsTree = (params) => {
+  return request({
+    url: "/spareParts/getTree",
+    method: "get",
+    params,
+  });
+};
+/**
+ *  澶囦欢鍒嗙被-鍒嗛〉鏌ヨ鍒楄〃
+ */
+export const getSparePartsList = (params) => {
+  return request({
+    url: "/spareParts/listPage",
+    method: "get",
+    params,
+  });
+};
+
+/**
+ * @desc 鏂板
+ */
+export const addSparePart = (data) => {
+  return request({
+    url: "/spareParts/add",
+    method: "post",
+    data,
+  });
+};
+
+/**
+ * @desc 缂栬緫
+ */
+export const editSparePart = (data) => {
+  return request({
+    url: "/spareParts/update",
+    method: "post",
+    data,
+  });
+};
+
+/**
+ * @desc 鍒犻櫎鎶ヤ慨
+ * @param {缂栧彿} ids
+ * @returns
+ */
+export const delSparePart = (id) => {
+  return request({
+    url: '/spareParts/delete/'+id,
+    method: "delete",
+
+  });
+};
+
+
diff --git a/src/views/equipmentManagement/defectManagement/index.vue b/src/views/equipmentManagement/defectManagement/index.vue
new file mode 100644
index 0000000..f35454f
--- /dev/null
+++ b/src/views/equipmentManagement/defectManagement/index.vue
@@ -0,0 +1,221 @@
+<template>
+  <div class="defect-management">
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <div class="actions">
+      <el-button type="primary" @click="showRegisterDialog = true">鐧昏缂洪櫡</el-button>
+    </div>
+
+    <!-- 缂洪櫡鍒楄〃 -->
+    <el-table :data="defectList" style="width: 100%; margin-top: 10px;" border>
+      <el-table-column prop="deviceName" label="璁惧鍚嶇О" width="180"></el-table-column>
+      <el-table-column prop="defectDescription" label="缂洪櫡鎻忚堪" win-width="300"></el-table-column>
+      <el-table-column prop="status" label="鐘舵��" width="220">
+        <template #default="{ row }">
+          <el-tag :type="row.status === '涓ラ噸缂洪櫡' ? 'danger' : 'success'">
+            {{ row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" width="220">
+        <template #default="{ row }">
+          <el-button
+            v-if="row.status === '涓ラ噸缂洪櫡' || row.status === '涓�鑸己闄�'"
+            type="text"
+            @click="eliminateDefect(row)"
+          >
+            娑堥櫎缂洪櫡
+          </el-button>
+          <!-- <el-button
+            v-if="row.status === '涓ラ噸缂洪櫡'"
+            type="text"
+            @click="transferToRepairOrder(row.id)"
+          >
+            杞淮淇崟
+          </el-button> -->
+          <el-button type="text" @click="getLedger(row.deviceLedgerId)">
+            鏌ョ湅鍙拌处
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 缂洪櫡鐧昏瀵硅瘽妗� -->
+    <el-dialog title="鐧昏璁惧缂洪櫡" v-model="showRegisterDialog" width="50%">
+      <el-form :model="defectForm" :rules="defectRules" ref="defectFormRef" label-width="100px">
+        <el-form-item label="璁惧鍚嶇О" prop="deviceName">
+          <el-select v-model="defectForm.deviceLedgerId" @change="setDeviceModel">
+            <el-option
+              v-for="(item, index) in deviceOptions"
+              :key="index"
+              :label="item.deviceName"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="缂洪櫡鎻忚堪" prop="defectDescription">
+          <el-input type="textarea" v-model="defectForm.defectDescription"></el-input>
+        </el-form-item>
+        <el-form-item label="璁惧鐘舵��" prop="status">
+          <el-radio-group v-model="defectForm.status">
+            <el-radio label="姝e父">姝e父</el-radio>
+            <el-radio label="涓�鑸己闄�">涓�鑸己闄�</el-radio>
+            <el-radio label="涓ラ噸缂洪櫡">涓ラ噸缂洪櫡</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="showRegisterDialog = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitDefectForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 缂洪櫡璁惧鍙拌处瀵硅瘽妗� -->
+    <el-dialog title="缂洪櫡璁惧鍙拌处" v-model="showLedgerDialog" width="80%">
+      <el-table :data="ledgerList" style="width: 100%; margin-top: 10px;" border>
+        <el-table-column prop="deviceName" label="璁惧鍚嶇О"></el-table-column>
+        <el-table-column prop="defectDescription" label="缂洪櫡鎻忚堪"></el-table-column>
+        <el-table-column prop="status" label="鐘舵��"></el-table-column>
+        <el-table-column prop="eliminateTime" label="娑堢己鏃堕棿"></el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+// 鍋囪浠ヤ笅鏄悗绔帴鍙�
+import {
+  registerDefect,
+  getDefectList,
+  eliminateDefect as apiEliminateDefect, 
+  getDefectLedger,
+  deleteDefect
+} from '@/api/equipmentManagement/defectManagement';
+
+// 缂洪櫡鍒楄〃
+const defectList = ref([]);
+// 鐧昏瀵硅瘽妗嗘樉绀虹姸鎬�
+const showRegisterDialog = ref(false);
+// 鍙拌处瀵硅瘽妗嗘樉绀虹姸鎬�
+const showLedgerDialog = ref(false);
+// 缂洪櫡琛ㄥ崟
+const defectForm = reactive({
+  deviceLedgerId: '',
+  defectDescription: '',
+  status: '',
+});
+const deviceOptions = ref([]);
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const defectRules = reactive({
+  deviceLedgerId: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
+  defectDescription: [{ required: true, message: '璇疯緭鍏ョ己闄锋弿杩�', trigger: 'blur' }]
+});
+// 琛ㄥ崟寮曠敤
+const defectFormRef = ref(null);
+// 鍙拌处鍒楄〃
+const ledgerList = ref([]);
+
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  // console.log(data);
+  deviceOptions.value = data;
+};
+
+// 鑾峰彇缂洪櫡鍒楄〃
+const fetchDefectList = async () => {
+  try {
+    const res = await getDefectList();
+    if (res.code === 200) {
+      defectList.value = res.data.records;
+    } else {
+      ElMessage.error(res.message || '鑾峰彇缂洪櫡鍒楄〃澶辫触');
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇缂洪櫡鍒楄〃澶辫触');
+  }
+};
+
+// 鎻愪氦缂洪櫡鐧昏琛ㄥ崟
+const submitDefectForm = async () => {
+  if (!defectFormRef.value) return;
+  try {
+    await defectFormRef.value.validate();
+    const res = await registerDefect(defectForm);
+    if (res.code === 200) {
+      ElMessage.success('缂洪櫡鐧昏鎴愬姛');
+      showRegisterDialog.value = false;
+      fetchDefectList();
+    } else {
+      ElMessage.error(res.message || '缂洪櫡鐧昏澶辫触');
+    }
+  } catch (error) {
+    ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�');
+  }
+};
+
+// 娑堥櫎缂洪櫡
+const eliminateDefect = async (row) => {
+
+  try {
+    const res = await apiEliminateDefect(row);
+    if (res.code === 200) {
+      ElMessage.success('缂洪櫡娑堥櫎鎴愬姛');
+      fetchDefectList();
+    } else {
+      ElMessage.error(res.message || '缂洪櫡娑堥櫎澶辫触');
+    }
+  } catch (error) {
+    ElMessage.error('缂洪櫡娑堥櫎澶辫触');
+  }
+};
+
+// // 杞淮淇伐鍗�
+// const transferToRepairOrder = async (id) => {
+//   try {
+//     const res = await transferToRepair(id);
+//     if (res.code === 200) {
+//       ElMessage.success('杞淮淇伐鍗曟垚鍔�');
+//     } else {
+//       ElMessage.error(res.message || '杞淮淇伐鍗曞け璐�');
+//     }
+//   } catch (error) {
+//     ElMessage.error('杞淮淇伐鍗曞け璐�');
+//   }
+// };
+
+// 鑾峰彇缂洪櫡璁惧鍙拌处
+const getLedger = async (deviceLedgerId) => {
+  try {
+    const res = await getDefectLedger(deviceLedgerId);
+    if (res.code === 200) {
+      ledgerList.value = res.data.records;
+      showLedgerDialog.value = true;
+    } else {
+      ElMessage.error(res.message || '鑾峰彇缂洪櫡璁惧鍙拌处澶辫触');
+    }
+  } catch (error) {
+    ElMessage.error('鑾峰彇缂洪櫡璁惧鍙拌处澶辫触');
+  }
+};
+
+// 缁勪欢鎸傝浇鏃惰幏鍙栫己闄峰垪琛�
+const onMounted = () => {
+  fetchDefectList();
+  loadDeviceName();
+};
+onMounted();
+</script>
+
+<style scoped>
+.defect-management {
+  padding: 20px;
+}
+
+.actions {
+  margin-bottom: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
new file mode 100644
index 0000000..f91d76f
--- /dev/null
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -0,0 +1,417 @@
+<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="姝e父" value="姝e父"></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>
\ No newline at end of file

--
Gitblit v1.9.3