¶Ô±ÈÐÂÎļþ |
| | |
| | | <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="责任人ï¼" 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: '责任人', 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: "请è¾å
¥ææ¡£åç§°", trigger: "blur" }], |
| | | docNumber: [{ required: true, message: "请è¾å
¥ææ¡£ç¼å·", 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; |
| | | // ä¿åå½åç¼è¾çåç±»ID |
| | | 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 { |
| | | // 妿䏿¯å¶åèç¹ï¼æ¸
ç©ºææ¡£å表 |
| | | documentList.value = []; |
| | | } |
| | | }; |
| | | |
| | | // æäº¤ææ¡£è¡¨å |
| | | const submitDocumentForm = () => { |
| | | proxy.$refs.documentFormRef.validate(async (valid) => { |
| | | if (valid) { |
| | | try { |
| | | // æå»ºæäº¤æ°æ® |
| | | const submitData = { |
| | | ...documentForm, |
| | | // 设置å½åéä¸çåç±»ID |
| | | 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> |