zhang_12370
3 天以前 3e1fb69d30b38230988a102b651b464c05283675
src/views/archiveManagement/index.vue
@@ -5,23 +5,22 @@
        <div class="tree-header">
          <h3>文档管理</h3>
          <el-button icon="Plus" size="small" type="primary" @click="append('')"
          >新增
          </el-button
          >
            >新增
          </el-button>
        </div>
        <!-- 搜索框 -->
        <div class="search-box">
          <el-input
              v-model="filterText"
              clearable
              placeholder="输入关键字进行搜索"
              size="small"
              @input="handleFilter"
            v-model="filterText"
            clearable
            placeholder="输入关键字进行搜索"
            size="small"
            @input="handleFilter"
          >
            <template #prefix>
              <el-icon>
                <Search/>
                <Search />
              </el-icon>
            </template>
          </el-input>
@@ -29,62 +28,63 @@
        <div class="tree-container">
          <el-tree
              ref="treeRef"
              :data="treeData"
              :default-expand-all="false"
              :expand-on-click-node="false"
              :filter-node-method="filterNode"
              :props="props"
              class="custom-tree"
              node-key="id"
              @node-click="handleNodeClick"
            ref="treeRef"
            :data="treeData"
            :default-expand-all="false"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            :props="props"
            class="custom-tree"
            node-key="id"
            @node-click="handleNodeClick"
          >
            <template #default="{ node, data }">
              <div class="tree-node-content" @dblclick="headerDbClick(node,data)">
              <div
                class="tree-node-content"
                @dblclick="headerDbClick(node, data)"
              >
                <div class="node-icon">
                  <el-icon
                      v-if="!node.isLeaf"
                      :class="{ expanded: node.expanded }"
                    v-if="!node.isLeaf"
                    :class="{ expanded: node.expanded }"
                  >
                    <Folder/>
                    <Folder />
                  </el-icon>
                  <el-icon v-else>
                    <Document/>
                    <Document />
                  </el-icon>
                </div>
                <div class="node-label">
                  <span v-if="!data.isEdit" class="label-text">{{
                      node.label
                    }}</span>
                    node.label
                  }}</span>
                  <el-input
                      v-else
                      :ref="(el) => setInputRef(el, data)"
                      v-model="newName"
                      autofocus
                      class="tree-input"
                      placeholder="请输入节点名称"
                      size="small"
                      @blur="(event) => handleInputBlur(event, data, node)"
                      @keyup.enter="
                      (event) => handleInputBlur(event, data, node)
                    "
                    v-else
                    :ref="(el) => setInputRef(el, data)"
                    v-model="newName"
                    autofocus
                    class="tree-input"
                    placeholder="请输入节点名称"
                    size="small"
                    @blur="(event) => handleInputBlur(event, data, node)"
                    @keyup.enter="(event) => handleInputBlur(event, data, node)"
                  />
                </div>
                <div v-show="!data.isEdit" class="node-actions">
                  <el-button
                      icon="Plus"
                      link
                      size="small"
                      title="新增子节点"
                      @click.stop="append(data)"
                    icon="Plus"
                    link
                    size="small"
                    title="新增子节点"
                    @click.stop="append(data)"
                  ></el-button>
                  <el-button
                      icon="Delete"
                      link
                      size="small"
                      title="删除"
                      @click.stop="remove(node, data)"
                    icon="Delete"
                    link
                    size="small"
                    title="删除"
                    @click.stop="remove(node, data)"
                  ></el-button>
                </div>
              </div>
@@ -95,65 +95,104 @@
    </div>
    <div class="right">
      <el-row :gutter="24">
        <el-col :offset="20" :span="2"
        >
          <el-button :icon="Delete" type="danger" @click="delHandler">删除</el-button>
        </el-col
        >
        <el-col :span="2"
        >
          <el-button
              :disabled="!tableSwitch"
              :icon="Plus"
              type="primary"
              @click="add"
          >新增
          </el-button
        <el-col :span="10">
          <div>
            <el-input
              style="float: left; width: 50%"
              v-model="searchText"
              placeholder="请输入关键字查询文件"
              clearable
              @input="handleSearch"
              @clear="handleSearch"
            >
              <template #prefix>
                <el-icon>
                  <Search />
                </el-icon>
              </template>
              <template #suffix>
                <el-button @click="handleSearch" link style="border: none">
                  <span>搜索</span>
                </el-button>
              </template>
            </el-input>
          </div>
        </el-col>
        <el-col :offset="8" :span="3">
          <el-button :icon="Delete" type="danger" @click="delHandler"
            >删除</el-button
          >
        </el-col
        >
        </el-col>
        <el-col :span="3">
          <el-button
            :disabled="!tableSwitch"
            :icon="Plus"
            type="primary"
            @click="add"
            >新增
          </el-button>
        </el-col>
      </el-row>
      <ETable
          :border="true"
          :columns="columns"
          :loading="loading"
          :maxHeight="1200"
          :show-selection="true"
          :table-data="tableData"
          @edit="handleEdit"
          @selection-change="handleSelectionChange"
        :border="true"
        :columns="columns"
        :loading="loading"
        :maxHeight="1200"
        :show-selection="true"
        :table-data="tableData"
        @edit="handleEdit"
        @selection-change="handleSelectionChange"
        style="height: calc(65vh);"
      >
      </ETable>
      <Pagination
          :layout="'total, prev, pager, next, jumper'"
          :limit="queryParams.pageSize"
          :page="queryParams.current"
          :show-total="true"
          :total="total"
          @pagination="handlePageChange"
        :layout="'total, prev, pager, next, jumper'"
        :limit="queryParams.pageSize"
        :page="queryParams.current"
        :show-total="true"
        :total="total"
        @pagination="handlePageChange"
      ></Pagination>
    </div>
    <archiveDialog
        ref="archiveDialogs"
        v-model:centerDialogVisible="dialogVisible"
        :row="row"
        @centerDialogVisible="centerDialogVisible"
        @submitForm="submitForm"
      ref="archiveDialogs"
      v-model:centerDialogVisible="dialogVisible"
      :row="row"
      @centerDialogVisible="centerDialogVisible"
      @submitForm="submitForm"
    >
    </archiveDialog>
  </el-card>
</template>
<script setup>
import {nextTick, onMounted, reactive, ref} from "vue";
import { nextTick, onMounted, reactive, ref } from "vue";
import ETable from "@/components/Table/ETable.vue";
import {ElButton, ElIcon, ElInput, ElMessage, ElMessageBox} from "element-plus";
import {
  ElButton,
  ElIcon,
  ElInput,
  ElMessage,
  ElMessageBox,
} from "element-plus";
import archiveDialog from "./mould/archiveDialog.vue";
import Pagination from "@/components/Pagination/index.vue";
import {Delete, Document, Folder, Plus, Search,} from "@element-plus/icons-vue";
import {addOrEditTree, delArchive, delTree, getArchiveList, getTree,} from "@/api/archiveManagement";
import {
  Delete,
  Document,
  Folder,
  Plus,
  Search,
} from "@element-plus/icons-vue";
import {
  addOrEditTree,
  delArchive,
  delTree,
  getArchiveList,
  getTree,
} from "@/api/archiveManagement";
// ===== 响应式状态管理 =====
const searchText = ref("");
const dialogVisible = ref(false);
const loading = ref(false);
const tableData = ref([]);
@@ -171,9 +210,9 @@
// ===== 配置常量 =====
const columns = [
  {prop: "name", label: "名称", minWidth: 180},
  {prop: "type", label: "类型", minWidth: 120},
  {prop: "status", label: "状态", minWidth: 100},
  { prop: "name", label: "名称", minWidth: 180 },
  { prop: "type", label: "类型", minWidth: 120 },
  { prop: "status", label: "状态", minWidth: 100 },
];
const queryParams = reactive({
@@ -199,11 +238,18 @@
  ElMessage.success(msg);
};
// 搜索查询函数
const handleSearch = () => {
  queryParams.searchAll = searchText.value;
  queryParams.current = 1; // 重置到第一页
  getArchiveListData();
};
const showConfirm = (message, title = "确认操作") => {
  return ElMessageBox.confirm(message, title, {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  });
};
@@ -228,7 +274,8 @@
const getList = async () => {
  try {
    const res = await getTree();
    treeData.value = res.code === 200 ? (res.data?.records || res.data || []) : [];
    treeData.value =
      res.code === 200 ? res.data?.records || res.data || [] : [];
  } catch (error) {
    handleError(error, "获取树结构数据失败");
    treeData.value = [];
@@ -242,6 +289,7 @@
      treeId: queryParams.treeId,
      current: queryParams.current,
      size: queryParams.pageSize,
      searchAll: queryParams.searchAll,
    });
    if (res.code !== 200) {
@@ -250,10 +298,10 @@
      total.value = 0;
      return;
    }
    tableData.value = res.data?.records || res.data || [];
    total.value = res.data?.total || 0;
    if (res.data?.current) {
      queryParams.current = res.data.current;
    }
@@ -306,17 +354,17 @@
    row.value = isEdit ? { ...rowData } : {};
    newName.value = "";
    dialogVisible.value = true;
    nextTick(() => {
      if (archiveDialogs.value) {
        const method = isEdit ? 'editForm' : 'initForm';
        if (typeof archiveDialogs.value[method] === 'function') {
        const method = isEdit ? "editForm" : "initForm";
        if (typeof archiveDialogs.value[method] === "function") {
          archiveDialogs.value[method](isEdit ? rowData : rowClickData.value);
        }
      }
    });
  } catch (error) {
    handleError(error, `打开${isEdit ? '编辑' : '新增'}界面失败`);
    handleError(error, `打开${isEdit ? "编辑" : "新增"}界面失败`);
  }
};
@@ -331,11 +379,14 @@
  }
  try {
    await showConfirm(`确定要删除选中的 ${selectedRows.length} 条记录吗?`, '删除确认');
    await showConfirm(
      `确定要删除选中的 ${selectedRows.length} 条记录吗?`,
      "删除确认"
    );
    const ids = selectedRows.map((row) => row.id);
    const { code, msg } = await delArchive(ids);
    if (code !== 200) {
      ElMessage.error("删除失败: " + msg);
      return;
@@ -344,9 +395,8 @@
    showSuccess("删除成功");
    await getArchiveListData();
    selectedRows.splice(0, selectedRows.length);
  } catch (error) {
    if (error !== 'cancel') {
    if (error !== "cancel") {
      handleError(error, "删除操作失败");
    }
  }
@@ -359,10 +409,10 @@
  }
  try {
    await showConfirm(`确定要删除节点 "${data.name}" 吗?`, '删除确认');
    await showConfirm(`确定要删除节点 "${data.name}" 吗?`, "删除确认");
    const { code, msg } = await delTree([data.id]);
    if (code !== 200) {
      ElMessage.error("删除失败: " + msg);
      return;
@@ -370,9 +420,8 @@
    showSuccess("删除成功");
    await getList();
  } catch (error) {
    if (error !== 'cancel') {
    if (error !== "cancel") {
      handleError(error, "删除节点失败");
    }
  }
@@ -405,37 +454,38 @@
const handleInputBlur = async (event, comeTreeData, node) => {
  try {
    if (!comeTreeData.isEdit || (event.relatedTarget?.tagName === "BUTTON")) return;
    if (!comeTreeData.isEdit || event.relatedTarget?.tagName === "BUTTON")
      return;
    comeTreeData.isEdit = false;
    const newValue = newName.value.trim();
    if (comeTreeData.name === newValue) return;
    if (!newValue) {
      newName.value = comeTreeData.name || "新节点";
      ElMessage.warning("节点名称不能为空");
      return;
    }
    const parentId = node?.parent?.data?.id || null;
    const result = await addOrEditTree({
      name: newValue,
      parentId,
      id: comeTreeData.id || null,
    });
    if (result.code === 200) {
      comeTreeData.name = newValue;
      if (!comeTreeData.id && result.data) {
        comeTreeData.id = result.data.id || result.data;
      }
      showSuccess("保存成功");
      const currentNodeId = comeTreeData.id;
      await getList();
      nextTick(() => {
        if (currentNodeId && treeRef.value) {
          const targetNode = treeRef.value.getNode(currentNodeId);
@@ -449,7 +499,6 @@
      comeTreeData.name = comeTreeData.name || "新节点";
      ElMessage.error("保存失败: " + (result.msg || "未知错误"));
    }
  } catch (error) {
    handleError(error, "保存节点失败");
    comeTreeData.name = comeTreeData.name || "新节点";
@@ -489,14 +538,14 @@
    const nodeKey = data.id || data;
    const node = treeRef.value?.getNode(nodeKey);
    const isExpanded = node?.expanded;
    // 如果有子级且未展开,先展开节点
    if (hasChildren && !isExpanded && treeRef.value?.store?.nodesMap[nodeKey]) {
      treeRef.value.store.nodesMap[nodeKey].expanded = true;
    }
    const newNode = createNewNode("新子节点");
    if (!data.children) {
      data.children = [];
    }
@@ -509,7 +558,10 @@
};
// ===== 生命周期 =====
onMounted(getList);
onMounted(()=>{
  getList();
  getArchiveListData();
});
</script>
<style lang="scss" scoped>
.custom-tree-node {