From 75a462f8ee30491f05d29ccac1b65d31e835957b Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 20 八月 2025 15:57:14 +0800 Subject: [PATCH] 档案管理调整 --- src/views/fileManagement/document/index.vue | 1262 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 1,262 insertions(+), 0 deletions(-) diff --git a/src/views/fileManagement/document/index.vue b/src/views/fileManagement/document/index.vue new file mode 100644 index 0000000..7cf352c --- /dev/null +++ b/src/views/fileManagement/document/index.vue @@ -0,0 +1,1262 @@ +<template> + <div class="app-container document-view"> + <div class="left"> + <div> + <el-input + v-model="search" + style="width: 210px" + placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�" + @change="searchFilter" + @clear="searchFilter" + clearable + prefix-icon="Search" + /> + <el-button + type="primary" + @click="openCategoryDia('addOne')" + style="margin-left: 10px" + >鏂板鍒嗙被</el-button + > + </div> + <div ref="containerRef"> + <el-tree + ref="tree" + v-loading="treeLoad" + :data="categoryList" + @node-click="handleNodeClick" + :expand-on-click-node="false" + default-expand-all + :default-expanded-keys="expandedKeys" + :draggable="true" + :filter-node-method="filterNode" + :props="{ children: 'children', label: 'category' }" + highlight-current + node-key="id" + style=" + height: calc(100vh - 190px); + overflow-y: scroll; + scrollbar-width: none; + margin-top: 10px; + " + > + <template #default="{ node, data }"> + <div class="custom-tree-node"> + <span class="tree-node-content"> + <el-icon class="orange-icon"> + <component :is="data.children && data.children.length > 0 + ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" /> + </el-icon> + {{ data.category }} + </span> + <div> + <el-button + type="primary" + link + @click="openCategoryDia('edit', data)" + > + 缂栬緫 + </el-button> + <el-button + type="primary" + link + @click="openCategoryDia('addSub', data)" + v-if="node.level < 2" + > + 娣诲姞瀛愬垎绫� + </el-button> + <el-button + v-if="!node.childNodes.length" + style="margin-left: 4px" + type="danger" + link + @click="removeCategory(node, data)" + > + 鍒犻櫎 + </el-button> + </div> + </div> + </template> + </el-tree> + </div> + </div> + <div class="right"> + <div style="margin-bottom: 10px" v-if="isShowButton"> + <el-button type="primary" @click="openDocumentDia('add')"> + 鏂板鏂囨。 + </el-button> + <el-button + type="danger" + @click="handleDelete" + style="margin-left: 10px" + plain + :disabled="selectedRows.length === 0" + > + 鍒犻櫎 ({{ selectedRows.length }}) + </el-button> + </div> + <div class="table-container"> + + <!-- PIMTable 缁勪欢 --> + <PIMTable + :table-data="documentList" + :column="tableColumns" + :is-selection="true" + :border="true" + :table-loading="tableLoading" + :page="{ + current: pagination.currentPage, + size: pagination.pageSize, + total: pagination.total, + layout: 'total, sizes, prev, pager, next, jumper' + }" + @selection-change="handleSelectionChange" + @pagination="handlePagination" + /> + </div> + </div> + + <!-- 鍒嗙被鏂板/淇敼瀵硅瘽妗� --> + <el-dialog v-model="categoryDia" title="鍒嗙被" width="400px" @keydown.enter.prevent> + <el-form + :model="categoryForm" + label-width="140px" + label-position="top" + :rules="categoryRules" + ref="categoryFormRef" + > + <el-row :gutter="30"> + <el-col :span="24" v-if="categoryOperationType === 'addSub'"> + <el-form-item label="鐖跺垎绫伙細" prop="parentName"> + <el-input + v-model="categoryForm.parentName" + placeholder="鐖跺垎绫诲悕绉�" + disabled + /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鍒嗙被鍚嶇О锛�" prop="category"> + <el-input + v-model="categoryForm.category" + placeholder="璇疯緭鍏ュ垎绫诲悕绉�" + clearable + @keydown.enter.prevent + /> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitCategoryForm">纭</el-button> + <el-button @click="closeCategoryDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + + <!-- 鏂囨。鏂板/淇敼瀵硅瘽妗� --> + <el-dialog + v-model="documentDia" + :title="documentOperationType === 'add' ? '鏂板鏂囨。' : '缂栬緫鏂囨。'" + width="600px" + @close="closeDocumentDia" + @keydown.enter.prevent + > + <el-form + :model="documentForm" + label-width="140px" + label-position="top" + :rules="documentRules" + ref="documentFormRef" + > + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。鍚嶇О锛�" prop="docName"> + <el-input v-model="documentForm.docName" placeholder="璇疯緭鍏�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="骞村害锛�" prop="year"> + <el-date-picker + v-model="documentForm.year" + type="year" + value-format="YYYY" + format="YYYY" + placeholder="閫夋嫨骞村害" + style="width: 100%" + /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。缂栧彿锛�" prop="docNumber"> + <el-input v-model="documentForm.docNumber" placeholder="璇疯緭鍏�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="璐d换浜猴細" prop="responsiblePerson"> + <el-input v-model="documentForm.responsiblePerson" placeholder="璇疯緭鍏�" /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。鍒嗙被锛�" prop="documentClassificationId"> + <el-select v-model="documentForm.documentClassificationId" placeholder="璇烽�夋嫨鏂囨。鍒嗙被" style="width: 100%"> + <el-option + v-for="item in categoryList" + :key="item.id" + :label="item.category" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鏂囨。鏀剧疆浣嶇疆锛�" prop="warehouseGoodsShelvesRowcolId"> + <el-tree-select + v-model="documentForm.warehouseGoodsShelvesRowcolId" + :data="locationTree" + placeholder="璇烽�夋嫨鏂囦欢鏀剧疆浣嶇疆" + clearable + check-strictly + :render-after-expand="false" + :props="{ children: 'children', label: 'label', value: 'value' }" + style="width: 100%" + @change="handleLocationChange" + /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。鏃ユ湡锛�" prop="docData"> + <el-date-picker + v-model="documentForm.docData" + type="date" + value-format="YYYY-MM-DD" + format="YYYY-MM-DD" + placeholder="閫夋嫨鏃ユ湡" + style="width: 100%" + /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="淇濈鏈熼檺锛�" prop="retentionPeriod"> + <el-select v-model="documentForm.retentionPeriod" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in retention_period" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="淇濆瘑绾у埆锛�" prop="securityLevel"> + <el-select v-model="documentForm.securityLevel" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in confidentiality_level" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鍒嗘暟锛�" prop="copyCount"> + <el-input v-model="documentForm.copyCount" placeholder="璇疯緭鍏�" /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="椤垫暟锛�" prop="pageCount"> + <el-input v-model="documentForm.pageCount" placeholder="璇疯緭鍏�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鏂囨。绫诲埆锛�" prop="docCategory"> + <el-select v-model="documentForm.docCategory" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in document_type" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。绉嶇被锛�" prop="docType"> + <el-select v-model="documentForm.docType" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in document_categories" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="绱ф�ョ▼搴︼細" prop="urgencyLevel"> + <el-select v-model="documentForm.urgencyLevel" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in document_urgency" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏂囨。鐘舵�侊細" prop="docStatus"> + <el-select v-model="documentForm.docStatus" placeholder="璇烽�夋嫨"> + <el-option + v-for="item in document_status" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="20"> + <el-col :span="24"> + <el-form-item label="澶囨敞锛�" prop="remark"> + <el-input + v-model="documentForm.remark" + type="textarea" + :rows="3" + placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" + /> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitDocumentForm">纭</el-button> + <el-button @click="closeDocumentDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + <AttachmentManager ref="attachmentManagerRef" /> + </div> + </template> + +<script setup> +import { ref, reactive, onMounted, getCurrentInstance, toRefs, watch } from "vue"; +import { ElMessageBox, ElMessage } from "element-plus"; +import { ArrowRight, Folder, FolderOpened, Tickets, Document } from '@element-plus/icons-vue'; +import PIMTable from '@/components/PIMTable/PIMTable.vue'; +import { getToken } from "@/utils/auth"; +import { getCategoryTree, addCategory, updateCategory, deleteCategory, getDocumentList, addDocument, updateDocument, deleteDocument, getDocumentDetail, searchDocument, getWarehouseStructure } from '@/api/fileManagement/document' +import { getWarehouseList } from '@/api/fileManagement/bookshelf' +import AttachmentManager from './attachmentManager.vue' +import { useDict } from '@/utils/dict' + +const { proxy } = getCurrentInstance(); +const tree = ref(null); +const containerRef = ref(null); + +// 浣跨敤瀛楀吀鏁版嵁 +const { confidentiality_level, document_urgency, document_status, document_type, document_categories, retention_period } = useDict('confidentiality_level', 'document_urgency', 'document_status', 'document_type', 'document_categories', 'retention_period') + +// 鐩戝惉瀛楀吀鏁版嵁鍙樺寲 +watch([confidentiality_level, document_urgency, document_status, document_type, document_categories, retention_period], () => { + // 瀛楀吀鏁版嵁宸叉洿鏂� +}, { immediate: true, deep: true }); + +const categoryDia = ref(false); +const documentDia = ref(false); +const categoryOperationType = ref(""); +const documentOperationType = ref(""); +const search = ref(""); +const currentId = ref(""); +const currentParentId = ref(""); +const treeLoad = ref(false); +const categoryList = ref([]); +const expandedKeys = ref([]); +const documentList = ref([]); +const isShowButton = ref(false); +const selectedRows = ref([]); +const selectAll = ref(false); +const isIndeterminate = ref(false); +const tableLoading = ref(false); +const attachmentManagerRef = ref(null); + +// 鏂囦欢涓婁紶閰嶇疆 +const upload = reactive({ + url: import.meta.env.VITE_APP_BASE_API + "/file/upload", + headers: { Authorization: "Bearer " + getToken() }, +}); + +// 浣嶇疆鏍戞暟鎹� +const locationTree = ref([]); + +// 琛ㄦ牸鍒楅厤缃� +const tableColumns = ref([ + { label: '鏂囨。鍚嶇О', prop: 'docName', width: '200' }, + { label: '鏂囨。缂栧彿', prop: 'docNumber', width: '120' }, + { label: '骞村害', prop: 'year', width: '80' }, + { label: '璐d换浜�', prop: 'responsiblePerson', width: '100' }, + { + label: '鏂囨。鏀剧疆浣嶇疆', + prop: 'warehouseGoodsShelvesRowcolId', + width: '150', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + return getLocationName(params); + } + }, + { label: '鏂囨。鏃ユ湡', prop: 'docData', width: '120' }, + { + label: '淇濈鏈熼檺', + prop: 'retentionPeriod', + width: '100', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!retention_period.value || retention_period.value.length === 0) { + return params; + } + const item = retention_period.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!retention_period.value || retention_period.value.length === 0) { + return 'info'; + } + const item = retention_period.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { + label: '淇濆瘑绾у埆', + prop: 'securityLevel', + width: '80', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!confidentiality_level.value || confidentiality_level.value.length === 0) { + return params; + } + const item = confidentiality_level.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!confidentiality_level.value || confidentiality_level.value.length === 0) { + return 'info'; + } + const item = confidentiality_level.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { label: '鍒嗘暟', prop: 'copyCount', width: '80' }, + { label: '椤垫暟', prop: 'pageCount', width: '80' }, + { + label: '鏂囨。绫诲埆', + prop: 'docCategory', + width: '100', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!document_type.value || document_type.value.length === 0) { + return params; + } + const item = document_type.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!document_type.value || document_type.value.length === 0) { + return 'info'; + } + const item = document_type.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { + label: '鏂囨。绉嶇被', + prop: 'docType', + width: '100', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!document_categories.value || document_categories.value.length === 0) { + return params; + } + const item = document_categories.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!document_categories.value || document_categories.value.length === 0) { + return 'info'; + } + const item = document_categories.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { + label: '绱ф�ョ▼搴�', + prop: 'urgencyLevel', + width: '100', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!document_urgency.value || document_urgency.value.length === 0) { + return params; + } + const item = document_urgency.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!document_urgency.value || document_urgency.value.length === 0) { + return 'info'; + } + const item = document_urgency.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { + label: '鏂囨。鐘舵��', + prop: 'docStatus', + width: '100', + dataType: 'tag', + formatData: (params) => { + if (params === null || params === undefined || params === '') return '-'; + if (!document_status.value || document_status.value.length === 0) { + return params; + } + const item = document_status.value.find(item => item.value == params); + return item ? item.label : params; + }, + formatType: (params) => { + if (params === null || params === undefined || params === '') return 'info'; + if (!document_status.value || document_status.value.length === 0) { + return 'info'; + } + const item = document_status.value.find(item => item.value == params); + const validTypes = ['success', 'warning', 'danger', 'info']; + return item && validTypes.includes(item.elTagType) ? item.elTagType : 'info'; + } + }, + { + dataType: "action", + label: "鎿嶄綔", + align: "center", + fixed: 'right', + width: '150', + operation: [ + { + name: "缂栬緫", + type: "text", + clickFun: (row) => { + openDocumentDia('edit', row) + }, + }, + { + name: "闄勪欢", + type: "text", + clickFun: (row) => { + openAttachment(row) + }, + }, + ], + } +]); + +// 鍒嗙被琛ㄥ崟 +const categoryForm = reactive({ + category: "", + parentId: "", + parentName: "", +}); + +const categoryRules = reactive({ + category: [{ required: true, message: "璇疯緭鍏ュ垎绫诲悕绉�", trigger: "blur" }], +}); + +// 鏂囨。琛ㄥ崟 +const documentForm = reactive({ + id: "", + documentClassificationId: "", + docName: "", + docNumber: "", + year: "", + responsiblePerson: "", + warehouseGoodsShelvesRowcolId: "", + docData: "", + retentionPeriod: "", + securityLevel: "", + copyCount: "", + pageCount: "", + docCategory: "", + docType: "", + urgencyLevel: "", + docStatus: "", + remark: "", + attachments: [], // 鏂板闄勪欢鏁扮粍 +}); + +const documentRules = reactive({ + docName: [{ required: true, message: "璇疯緭鍏ユ枃妗e悕绉�", trigger: "blur" }], + docNumber: [{ required: true, message: "璇疯緭鍏ユ枃妗g紪鍙�", trigger: "blur" }], + year: [{ required: true, message: "璇烽�夋嫨骞村害", trigger: "change" }], + documentClassificationId: [{ required: true, message: "璇烽�夋嫨鏂囨。鍒嗙被", trigger: "change" }], + warehouseGoodsShelvesRowcolId: [{ required: true, message: "璇烽�夋嫨鏂囨。鏀剧疆浣嶇疆", trigger: "change" }], +}); + +// 鍒嗛〉鐩稿叧 +const pagination = reactive({ + currentPage: 1, + pageSize: 10, + total: 0, +}); + +// 鍒濆鍖栧垎绫绘爲鏁版嵁 +const initCategoryTree = async() => { + try { + treeLoad.value = true; + const res = await getCategoryTree(); + if (res.code === 200) { + categoryList.value = res.data || []; + + // 璁剧疆灞曞紑鐨勮妭鐐� + expandedKeys.value = []; + categoryList.value.forEach((item) => { + if (item.id) { + expandedKeys.value.push(item.id); + } + }); + } else { + ElMessage.error(res.msg || "鑾峰彇鍒嗙被鏍戝け璐�"); + } + } catch (error) { + ElMessage.error("鑾峰彇鍒嗙被鏍戝け璐ワ紝璇烽噸璇�"); + } finally { + treeLoad.value = false; + } +}; + +// 鍒濆鍖栦粨搴撲綅缃暟鎹� +const initLocationTree = async() => { + try { + const res = await getWarehouseList(); + if (res.code === 200) { + // 杞崲鏁版嵁鏍煎紡锛岄�傞厤el-tree-select缁勪欢 + locationTree.value = transformWarehouseData(res.data || []); + } else { + ElMessage.error(res.msg || "鑾峰彇浠撳簱浣嶇疆澶辫触"); + } + } catch (error) { + ElMessage.error("鑾峰彇浠撳簱浣嶇疆澶辫触锛岃閲嶈瘯"); + } +}; + +// 杞崲浠撳簱鏁版嵁鏍煎紡 +const transformWarehouseData = (data) => { + return data.map(item => ({ + id: item.id, + label: item.name || item.warehouseName || item.label, + value: item.id, + children: item.children ? transformWarehouseData(item.children) : [] + })); +}; + +// 鏍规嵁ID鑾峰彇浣嶇疆鍚嶇О +const getLocationName = (locationId) => { + if (!locationId || !locationTree.value || locationTree.value.length === 0) { + return locationId || '-'; + } + + const findLocation = (tree, id) => { + for (let item of tree) { + if (item.value === locationId || item.id === locationId) { + return item.label; + } + if (item.children && item.children.length > 0) { + const result = findLocation(item.children, id); + if (result) return result; + } + } + return null; + }; + + const locationName = findLocation(locationTree.value, locationId); + return locationName || locationId; +}; + +// 杩囨护鍒嗙被鏍� +const searchFilter = () => { + if (proxy.$refs.tree) { + proxy.$refs.tree.filter(search.value); + } +}; + +// 鎵撳紑鍒嗙被寮规 +const openCategoryDia = (type, data) => { + categoryOperationType.value = type; + categoryDia.value = true; + categoryForm.category = ""; + categoryForm.parentId =""; + categoryForm.parentName = ""; + + if (type === "edit") { + categoryForm.category = data.category; + // 淇濆瓨褰撳墠缂栬緫鐨勫垎绫籌D + currentId.value = data.id; + } else if (type === "addSub") { + categoryForm.parentId = data.id; + categoryForm.parentName = data.category; + } +}; + +// 鎵撳紑鏂囨。寮规 +const openDocumentDia = (type, data) => { + documentOperationType.value = type; + documentDia.value = true; + + if (type === "edit") { + // 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹� + Object.assign(documentForm, data); + documentForm.retentionPeriod = String(documentForm.retentionPeriod) + documentForm.securityLevel = String(documentForm.securityLevel) + documentForm.docCategory = String(documentForm.docCategory) + documentForm.docType = String(documentForm.docType) + documentForm.urgencyLevel = String(documentForm.urgencyLevel) + documentForm.docStatus = String(documentForm.docStatus) + + // 鍔犺浇闄勪欢淇℃伅 + if (data.attachments) { + documentForm.attachments = [...data.attachments]; + } else { + documentForm.attachments = []; + } + } else { + // 鏂板妯″紡锛屾竻绌鸿〃鍗� + Object.keys(documentForm).forEach(key => { + documentForm[key] = ""; + }); + documentForm.attachments = []; // 鏂板妯″紡涓嬩篃娓呯┖闄勪欢 + // 璁剧疆榛樿鍊� - 浣跨敤瀛楀吀鏁版嵁鐨勭涓�涓�夐」浣滀负榛樿鍊� + if (document_status.value && document_status.value.length > 0) { + documentForm.docStatus = document_status.value[0].value; + } + if (document_urgency.value && document_urgency.value.length > 0) { + documentForm.urgencyLevel = document_urgency.value[0].value; + } + } +}; + +// 鎻愪氦鍒嗙被琛ㄥ崟 +const submitCategoryForm = () => { + proxy.$refs.categoryFormRef.validate(async (valid) => { + if (valid) { + try { + if (categoryOperationType.value === "addSub") { + // 娣诲姞瀛愬垎绫� + const res = await addCategory({ + category: categoryForm.category, + parentId: categoryForm.parentId + }); + if (res.code === 200) { + ElMessage.success("娣诲姞瀛愬垎绫绘垚鍔�"); + // 閲嶆柊鍔犺浇鍒嗙被鏍� + await initCategoryTree(); + } else { + ElMessage.error(res.msg || "娣诲姞瀛愬垎绫诲け璐�"); + } + } else if (categoryOperationType.value === "edit") { + // 缂栬緫鍒嗙被 + const res = await updateCategory({ + id: currentId.value, + category: categoryForm.category + }); + if (res.code === 200) { + ElMessage.success("缂栬緫鍒嗙被鎴愬姛"); + // 閲嶆柊鍔犺浇鍒嗙被鏍� + await initCategoryTree(); + } else { + ElMessage.error(res.msg || "缂栬緫鍒嗙被澶辫触"); + } + } else { + // 鏂板椤剁骇鍒嗙被 + const res = await addCategory({ + category: categoryForm.category, + parentId: null + }); + if (res.code === 200) { + ElMessage.success("鏂板鍒嗙被鎴愬姛"); + // 閲嶆柊鍔犺浇鍒嗙被鏍� + await initCategoryTree(); + } else { + ElMessage.error(res.msg || "鏂板鍒嗙被澶辫触"); + } + } + + closeCategoryDia(); + } catch (error) { + ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯"); + } + } + }); +}; + +// 鍏抽棴鍒嗙被寮规 +const closeCategoryDia = () => { + proxy.$refs.categoryFormRef.resetFields(); + categoryForm.parentId = ""; + categoryForm.parentName = ""; + categoryDia.value = false; +}; + +// 鍒犻櫎鍒嗙被 +const removeCategory = (node, data) => { + ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(async () => { + try { + const res = await deleteCategory([data.id]); + if (res.code === 200) { + ElMessage.success("鍒犻櫎鎴愬姛"); + // 閲嶆柊鍔犺浇鍒嗙被鏍� + await initCategoryTree(); + } else { + ElMessage.error(res.msg || "鍒犻櫎澶辫触"); + } + } catch (error) { + ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯"); + } + }) + .catch(() => { + ElMessage("宸插彇娑�"); + }); +}; + +// 閫夋嫨鍒嗙被 +const handleNodeClick = (val, node, el) => { + // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐� + isShowButton.value = true; + // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫 + currentId.value = val.id; + currentParentId.value = val.parentId; + + // 娓呯┖閫夋嫨鐘舵�� + selectedRows.value = []; + selectAll.value = false; + isIndeterminate.value = false; + + // 閲嶇疆鍒嗛〉 + pagination.currentPage = 1; + pagination.total = 0; + + // 鍔犺浇鏂囨。鍒楄〃 + if (isShowButton.value) { + loadDocumentList(); + } else { + // 濡傛灉涓嶆槸鍙跺瓙鑺傜偣锛屾竻绌烘枃妗e垪琛� + documentList.value = []; + } +}; + +// 鎻愪氦鏂囨。琛ㄥ崟 +const submitDocumentForm = () => { + proxy.$refs.documentFormRef.validate(async (valid) => { + if (valid) { + try { + // 鏋勫缓鎻愪氦鏁版嵁 + const submitData = { + ...documentForm, + // 璁剧疆褰撳墠閫変腑鐨勫垎绫籌D + documentClassificationId: currentId.value || documentForm.documentClassificationId, + // 娣诲姞闄勪欢淇℃伅 + // attachments: documentForm.attachments + }; + + if (documentOperationType.value === "edit") { + // 缂栬緫妯″紡锛屾洿鏂扮幇鏈夋暟鎹� + const res = await updateDocument(submitData); + if (res.code === 200) { + ElMessage.success("缂栬緫鎴愬姛"); + // 閲嶆柊鍔犺浇鏂囨。鍒楄〃 + await loadDocumentList(); + // 鍒锋柊闄勪欢鍒楄〃 + if (attachmentManagerRef.value && documentForm.id) { + attachmentManagerRef.value.loadAttachmentList(documentForm.id); + } + } else { + ElMessage.error(res.msg || "缂栬緫澶辫触"); + } + } else { + // 鏂板妯″紡锛屾坊鍔犳柊鏁版嵁 + const res = await addDocument(submitData); + if (res.code === 200) { + ElMessage.success("鏂板鎴愬姛"); + // 閲嶆柊鍔犺浇鏂囨。鍒楄〃 + await loadDocumentList(); + // 鍒锋柊闄勪欢鍒楄〃 + if (attachmentManagerRef.value && res.data && res.data.id) { + attachmentManagerRef.value.loadAttachmentList(res.data.id); + } + } else { + ElMessage.error(res.msg || "鏂板澶辫触"); + } + } + closeDocumentDia(); + } catch (error) { + ElMessage.error("鎿嶄綔澶辫触锛岃閲嶈瘯"); + } + } + }); +}; + +// 鍏抽棴鏂囨。寮规 +const closeDocumentDia = () => { + proxy.$refs.documentFormRef.resetFields(); + documentDia.value = false; + // 娓呯┖琛ㄥ崟鏁版嵁 + Object.keys(documentForm).forEach(key => { + documentForm[key] = ""; + }); + documentForm.attachments = []; // 鍏抽棴寮规鏃朵篃娓呯┖闄勪欢 +}; + +// 澶勭悊浣嶇疆閫夋嫨鍙樺寲 +const handleLocationChange = (value) => { + if (value) { + // 妫�鏌ラ�夋嫨鐨勬槸鍚︿负鍙跺瓙鑺傜偣 + const isLeafNode = checkIfLeafNode(locationTree.value, value); + if (!isLeafNode) { + ElMessage.warning("璇烽�夋嫨鏈�搴曞眰鐨勪綅缃紙濡傦細鏌滃眰锛�"); + documentForm.warehouseGoodsShelvesRowcolId = ""; + return; + } + } +}; + +// 妫�鏌ユ槸鍚︿负鍙跺瓙鑺傜偣 +const checkIfLeafNode = (tree, value) => { + for (let item of tree) { + if (item.value === value || item.id === value) { + // 濡傛灉娌℃湁瀛愯妭鐐癸紝鍒欎负鍙跺瓙鑺傜偣 + return !item.children || item.children.length === 0; + } + if (item.children && item.children.length > 0) { + const result = checkIfLeafNode(item.children, value); + if (result !== null) { + return result; + } + } + } + return null; +}; + +// 鍒犻櫎鏂囨。 +const handleDelete = () => { + if (selectedRows.value.length > 0) { + ElMessageBox.confirm(`纭畾瑕佸垹闄ら�変腑鐨� ${selectedRows.value.length} 鏉¤褰曞悧锛焋, "鍒犻櫎鎻愮ず", { + confirmButtonText: "纭", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(async () => { + try { + const selectedIds = selectedRows.value.map(row => row.id); + const res = await deleteDocument(selectedIds); + if (res.code === 200) { + ElMessage.success("鍒犻櫎鎴愬姛"); + // 閲嶆柊鍔犺浇鏂囨。鍒楄〃 + await loadDocumentList(); + } else { + ElMessage.error(res.msg || "鍒犻櫎澶辫触"); + } + } catch (error) { + ElMessage.error("鍒犻櫎澶辫触锛岃閲嶈瘯"); + } + }) + .catch(() => { + ElMessage("宸插彇娑�"); + }); + } else { + ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁"); + } +}; + +// PIMTable 閫夋嫨鍙樺寲浜嬩欢 +const handleSelectionChange = (selection) => { + selectedRows.value = selection; + + // 鏇存柊鍏ㄩ�夌姸鎬� + const selectedCount = selection.length; + const totalCount = documentList.value.length; + + if (selectedCount === 0) { + selectAll.value = false; + isIndeterminate.value = false; + } else if (selectedCount === totalCount) { + selectAll.value = true; + isIndeterminate.value = false; + } else { + selectAll.value = false; + isIndeterminate.value = true; + } +}; + +// 鍔犺浇鏂囨。鍒楄〃 +const loadDocumentList = async () => { + try { + tableLoading.value = true; + + // 鏋勫缓鏌ヨ鍙傛暟 + const query = { + page: pagination.currentPage, + size: pagination.pageSize, + documentClassificationId:currentId.value + }; + + const res = await getDocumentList(query); + if (res.code === 200) { + documentList.value = res.data.records || []; + pagination.total = res.data.total || 0; + } else { + ElMessage.error(res.msg || "鑾峰彇鏂囨。鍒楄〃澶辫触"); + documentList.value = []; + pagination.total = 0; + } + + // 閲嶇疆閫夋嫨鐘舵�� + selectedRows.value = []; + selectAll.value = false; + isIndeterminate.value = false; + } catch (error) { + ElMessage.error("鑾峰彇鏂囨。鍒楄〃澶辫触锛岃閲嶈瘯"); + documentList.value = []; + pagination.total = 0; + } finally { + tableLoading.value = false; + } +}; + +// 澶勭悊鍒嗛〉鍙樺寲 +const handlePagination = (current, size) => { + pagination.currentPage = current; + pagination.pageSize = size; + loadDocumentList(); +}; + +// 璋冪敤tree杩囨护鏂规硶 +const filterNode = (value, data, node) => { + if (!value) { + return true; + } + let val = value.toLowerCase(); + return chooseNode(val, data, node); +}; + +// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� +const chooseNode = (value, data, node) => { + if (data.category && data.category.toLowerCase().indexOf(value) !== -1) { + return true; + } + const level = node.level; + if (level === 1) { + return false; + } + let parentData = node.parent; + let index = 0; + while (index < level - 1) { + if (parentData.data.category && parentData.data.category.toLowerCase().indexOf(value) !== -1) { + return true; + } + parentData = parentData.parent; + index++; + } + return false; +}; + +// 鎵撳紑闄勪欢 +const openAttachment = (row) => { + attachmentManagerRef.value.open([], row.id); +}; + +onMounted(() => { + initCategoryTree(); + initLocationTree(); + + // 涓嶅湪鍒濆鍖栨椂鍔犺浇鏂囨。鍒楄〃锛岀瓑寰呯敤鎴烽�夋嫨鍒嗙被鍚庡啀鍔犺浇 +}); +</script> + +<style scoped> +.document-view { + display: flex; + height: 100%; +} + +.left { + width: 380px; + padding: 16px; + background: #ffffff; + border-right: 1px solid #e4e7ed; +} + +.right { + width: calc(100% - 380px); + padding: 16px; + background: #ffffff; +} + +.custom-tree-node { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + font-size: 14px; + padding-right: 8px; +} + +.tree-node-content { + display: flex; + align-items: center; + height: 100%; +} + +.orange-icon { + color: orange; + font-size: 18px; + margin-right: 8px; +} + +.table-container { + background: #ffffff; + border-radius: 8px; + overflow: hidden; + position: relative; +} + +.add-row { + display: flex; + align-items: center; + gap: 8px; + background-color: #f5f7fa; + cursor: pointer; + transition: background-color 0.2s ease; + padding: 12px 16px; + margin-bottom: 16px; + border-radius: 6px; + border: 1px dashed #d9d9d9; +} + +.add-row:hover { + background-color: #e4e7ed; + border-color: #c0c4cc; +} + +.add-icon { + color: #909399; + font-size: 16px; +} + +.add-row span { + color: #606266; + font-size: 14px; +} + +.empty-data { + text-align: center; + color: #909399; + padding: 40px; + font-size: 14px; +} + +.dialog-footer { + text-align: right; +} + +.operation-column { + position: absolute; + right: 0; + top: 0; + width: 120px; + background: #ffffff; + border-left: 1px solid #e4e7ed; + z-index: 1; + box-shadow: -2px 0 4px rgba(0, 0, 0, 0.1); +} + +.operation-header { + height: 40px; + line-height: 40px; + text-align: center; + background: #fafafa; + border-bottom: 1px solid #e4e7ed; + font-weight: 500; + color: #606266; +} + +.operation-cell { + height: 40px; + display: flex; + align-items: center; + justify-content: center; + border-bottom: 1px solid #e4e7ed; +} + +.operation-cell:last-child { + border-bottom: none; +} + +.attachment-section { + width: 100%; +} + +.attachment-list { + margin-bottom: 10px; +} + +.attachment-item { + display: flex; + align-items: center; + padding: 8px 12px; + background-color: #f5f7fa; + border-radius: 4px; + margin-bottom: 8px; +} + +.file-icon { + margin-right: 8px; + color: #409eff; +} + +.file-name { + flex: 1; + color: #606266; + font-size: 14px; +} +</style> -- Gitblit v1.9.3