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/bookshelf/index.vue |  688 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 688 insertions(+), 0 deletions(-)

diff --git a/src/views/fileManagement/bookshelf/index.vue b/src/views/fileManagement/bookshelf/index.vue
new file mode 100644
index 0000000..2689900
--- /dev/null
+++ b/src/views/fileManagement/bookshelf/index.vue
@@ -0,0 +1,688 @@
+<template>
+  <div class="sample">
+    <div class="main-content" v-if="!isDetail">
+      <div class="search">
+                 <div class="search_thing">
+           <div class="search_label">浠撳簱鍚嶇О锛�</div>
+           <div class="search_input">
+             <el-select v-model="entity.warehouseId" placeholder="閫夋嫨浠撳簱" size="small" @change="warehouseChange">
+               <el-option v-for="item in warehouse" :key="item.id" :label="item.label" :value="item.id">
+               </el-option>
+             </el-select>
+           </div>
+         </div>
+        <div class="search_thing">
+          <div class="search_label">璐ф灦锛�</div>
+          <div class="search_input">
+            <el-select v-model="entity.shelfId" placeholder="閫夋嫨璐ф灦" size="small" @change="handleShelf">
+              <el-option v-for="item in shelf" :key="item.id" :label="item.label" :value="item.id">
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+          <!-- <div class="search_thing">
+           <el-button size="small" @click="handleShelf(entity.shelfId,'')">閲嶇疆</el-button>
+           <el-button size="small" type="primary" @click="handleShelf(entity.shelfId)">鏌ヨ</el-button>
+         </div> -->
+        <div class="btns">
+          <el-button size="small" style="color:#3A7BFA" @click="keepVisible=true">缁存姢</el-button>
+          <el-button size="small" style="color:#3A7BFA" @click="warehouseVisible=true,isEdit=false">娣诲姞浠撳簱</el-button>
+          <el-button size="small" style="color:#3A7BFA" @click="shelvesVisible=true,isEdit=false"
+            :disabled="entity.warehouseId==null">娣诲姞璐ф灦</el-button>
+        </div>
+      </div>
+      <div class="table" v-loading="tableLoading">
+        <table class="tables" style="table-layout:fixed;" v-if="tableList.length>0">
+          <tbody>
+            <tr v-for="(item,index) in tableList" :key="index">
+              <td v-for="(m,i) in item" :key="i" class="content">
+                <h4 v-if="m.row!=undefined">{{ m.row }} - {{ m.col }}</h4>
+                <ul>
+                  <el-tooltip
+                  effect="dark"
+                  placement="top"
+                  v-for="(n,j) in m.documentationDtoList"
+                  :key="j">
+                    <template #content><span>{{ n.docName }}</span>
+                      <span>&nbsp;[{{ n.docNumber }}]</span></template>
+                    <li class="green"
+                      @click="handelDetail(n)">
+                      <i></i>
+                      <span>{{ n.docName }}</span>
+                      <span>&nbsp;[{{ n.docNumber }}] <span :style="{ color: getStatusColor(n.docStatus) }">锛坽{ n.docStatus }}锛�</span></span>
+                    </li>
+                  </el-tooltip>
+                </ul>
+              </td>
+            </tr>
+            <tr>
+              <td v-for="(item,index) in rowList" :key="index" style="background: ghostwhite;height: 20px;">{{ item }}
+              </td>
+            </tr>
+          </tbody>
+        </table>
+        <span v-else style="color: rgb(144, 147, 153);display: inline-block;position: absolute;top: 60%;left: 50%;transform: translate(-50%,-50%);">鏆傛棤鏁版嵁</span>
+      </div>
+    </div>
+    <Detail v-else @hanldeBack="isDetail=false" :current="current" />
+    
+    <!-- 搴撲綅缁存姢瀵硅瘽妗� -->
+    <el-dialog v-model="keepVisible" title="搴撲綅缁存姢" width="350px" :append-to-body="true">
+                                                       <el-tree :data="warehouse" ref="tree" node-key="id"
+           highlight-current v-if="keepVisible"
+           empty-text="鏆傛棤鏁版嵁">
+        <template #default="{ node, data }">
+          <div class="custom-tree-node" style="width: 100%;">
+            <el-row style="width: 100%;display: flex;align-items: center;">
+              <el-col :span="14">
+                <span>
+                  <el-icon v-if="node.level < 2" class="folder-icon">
+                    <FolderOpened />
+                  </el-icon>
+                  <el-icon v-else class="file-icon">
+                    <Document />
+                  </el-icon>
+                  {{ data.label }}
+                </span>
+              </el-col>
+              <el-col :span="10" v-if="node.level<3">
+                <el-button type="link" size="small" :icon="Edit" @click.stop="handleEdit(data,node.level)">
+                </el-button>
+                <el-button type="danger" size="small" :icon="Delete" @click.stop="handleDelete(data,node.level)">
+                </el-button>
+              </el-col>
+            </el-row>
+          </div>
+        </template>
+      </el-tree>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="keepVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="keepVisible = false" >纭� 瀹�</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    
+    <!-- 浠撳簱鏂板/淇敼瀵硅瘽妗� -->
+    <el-dialog v-model="warehouseVisible" :title="isEdit?'浠撳簱淇敼':'浠撳簱鏂板'" width="350px">
+      <el-row>
+        <el-col class="search_thing" :span="24">
+          <div class="search_label"><span class="required-span">* </span>浠撳簱鍚嶇О锛�</div>
+          <div class="search_input">
+            <el-input v-model="name" size="small" @keyup.enter="confirmWarehouse"></el-input>
+          </div>
+        </el-col>
+      </el-row>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="warehouseVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="confirmWarehouse" :loading="upLoadWarehouse">纭� 瀹�</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    
+    <!-- 璐ф灦鏂板/淇敼瀵硅瘽妗� -->
+    <el-dialog v-model="shelvesVisible" :title="isEdit?'璐ф灦淇敼':'璐ф灦鏂板'" width="350px">
+      <el-row>
+        <el-col class="search_thing" :span="24">
+          <div class="search_label"><span class="required-span">* </span>璐ф灦鍚嶇О锛�</div>
+          <div class="search_input">
+            <el-input v-model="shelves.name" size="small"></el-input>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col class="search_thing" :span="24">
+          <div class="search_label"><span class="required-span">* </span>璐ф灦灞傛暟锛�</div>
+          <div class="search_input">
+            <el-input v-model="shelves.row" size="small"></el-input>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col class="search_thing" :span="24">
+          <div class="search_label"><span class="required-span">* </span>璐ф灦鍒楁暟锛�</div>
+          <div class="search_input">
+            <el-input v-model="shelves.col" size="small"></el-input>
+          </div>
+        </el-col>
+      </el-row>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="shelvesVisible = false">鍙� 娑�</el-button>
+          <el-button type="primary" @click="confirmShelves" :loading="upLoadShelves">纭� 瀹�</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    
+    
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, watch } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Edit, Delete, FolderOpened, Document } from '@element-plus/icons-vue'
+import { getWarehouseList, addWarehouse, updateWarehouse, deleteWarehouse, getWarehouseStructure, addShelf, updateShelf, deleteShelf } from '@/api/fileManagement/bookshelf'
+import Detail from './detail.vue'
+
+// 鍝嶅簲寮忔暟鎹�
+const entity = reactive({
+  warehouseId: null,
+  shelfId: null
+})
+
+const warehouse = ref([])
+const shelf = ref([])
+const keepVisible = ref(false)
+const warehouseVisible = ref(false)
+const shelvesVisible = ref(false)
+const upLoadWarehouse = ref(false)
+const upLoadShelves = ref(false)
+const tableList = ref([])
+const rowList = ref([])
+const value = ref('')
+const name = ref('')
+const shelves = reactive({})
+const isEdit = ref(false)
+const isDetail = ref(false)
+const currentEdit = ref(null)
+const tableLoading = ref(false)
+const current = ref({})
+
+// 妯℃澘寮曠敤
+const organization = ref(null)
+
+// 鐩戝惉鍣�
+watch(isEdit, (newVal) => {
+  if (!newVal) {
+    Object.keys(shelves).forEach(key => delete shelves[key])
+  }
+})
+
+// 鏂规硶
+
+const selectList = async () => {
+  // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
+  const res = await getWarehouseList()
+  warehouse.value = res.data
+  
+  if (warehouse.value.length == 0) {
+    entity.warehouseId = ''
+    entity.shelfId = ''
+    tableList.value = []
+  }
+  
+           
+  
+  if (!entity.warehouseId && warehouse.value.length > 0) {
+    entity.warehouseId = warehouse.value[0].id
+    warehouseChange(entity.warehouseId)
+    if (shelf.value.length > 0) {
+      entity.shelfId = shelf.value[0].id
+      handleShelf(entity.shelfId)
+    } else {
+      tableList.value = []
+    }
+  } else if (warehouse.value.length > 0) {
+    warehouseChange(entity.warehouseId)
+    if (shelf.value.length > 0) {
+      entity.shelfId = shelf.value[0].id
+      handleShelf(entity.shelfId)
+    } else {
+      tableList.value = []
+    }
+  }
+}
+
+const confirmWarehouse = () => {
+  if (!name.value) {
+    ElMessage.error('璇峰~鍐欎粨搴撳悕绉�')
+    return
+  }
+  upLoadWarehouse.value = true
+  
+  if (currentEdit.value && currentEdit.value.id) {
+    // 淇敼浠撳簱
+    // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
+    updateWarehouse({
+      id: currentEdit.value.id,
+      warehouseName: name.value
+    }).then(res => {
+      upLoadWarehouse.value = false
+      warehouseVisible.value = false
+      currentEdit.value = null
+      ElMessage.success('淇敼鎴愬姛')
+      selectList()
+      name.value = ''
+      warehouseChange(entity.warehouseId)
+    })
+    
+  } else {
+    // 鏂板浠撳簱
+    // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
+    addWarehouse({
+      warehouseName: name.value
+    }).then(res => {
+      upLoadWarehouse.value = false
+      warehouseVisible.value = false
+      ElMessage.success('娣诲姞鎴愬姛')
+      selectList()
+      name.value = ''
+      warehouseChange(entity.warehouseId)
+    })
+  }
+}
+
+const confirmShelves = () => {
+  if (!shelves.name) {
+    ElMessage.error('璇峰~鍐欒揣鏋跺悕绉�')
+    return
+  }
+  if (!shelves.row) {
+    ElMessage.error('璇峰~鍐欒揣鏋跺眰鏁�')
+    return
+  }
+  if (!shelves.col) {
+    ElMessage.error('璇峰~鍐欒揣鏋跺垪鏁�')
+    return
+  }
+  upLoadShelves.value = true
+  
+  if (currentEdit.value && currentEdit.value.id) {
+    // 淇敼
+    updateShelf({
+      id: currentEdit.value.id,
+      name: shelves.name,
+      row: Number(shelves.row),
+      col: Number(shelves.col),
+      warehouseId: entity.warehouseId
+    }).then(res => {
+      upLoadShelves.value = false
+      shelvesVisible.value = false
+      ElMessage.success('淇敼鎴愬姛')
+      selectList()
+      currentEdit.value = {}
+    }).catch(err => {
+      upLoadShelves.value = false
+      shelvesVisible.value = false
+      ElMessage.error('淇敼澶辫触')
+    })
+    
+  } else {
+    // 鏂板
+    // 杩欓噷闇�瑕佹浛鎹负瀹為檯鐨凙PI璋冪敤
+      addShelf({
+      name: shelves.name,
+      row: Number(shelves.row),
+      col: Number(shelves.col),
+      warehouseId: entity.warehouseId
+    }).then(res => {
+      upLoadShelves.value = false
+      shelvesVisible.value = false
+      ElMessage.success('娣诲姞鎴愬姛')
+      selectList()
+      Object.keys(shelves).forEach(key => delete shelves[key])
+    }).catch(err => {
+      upLoadShelves.value = false
+      shelvesVisible.value = false
+      ElMessage.error('娣诲姞澶辫触')
+    })
+  }
+  warehouseChange(entity.warehouseId)
+}
+
+
+
+const handleDelete = (row, level) => {
+  ElMessageBox.confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning"
+  }).then(() => {
+    if (level == 1) {
+      // 鍒犻櫎浠撳簱
+      deleteWarehouse([row.id]).then(res => {
+        ElMessage.success('鍒犻櫎鎴愬姛')
+        selectList()
+      })
+    } else {
+      // 鍒犻櫎璐ф灦
+      deleteShelf({
+        id: row.id
+      }).then(res => {
+        ElMessage.success('鍒犻櫎鎴愬姛')
+        selectList()
+      })
+    }
+    warehouseChange(entity.warehouseId)
+  }).catch(() => {})
+}
+
+const handleEdit = (data, level) => {
+  isEdit.value = true
+  if (level == 1) {
+    warehouseVisible.value = true
+    currentEdit.value = data
+    name.value = data.label
+  } else {
+    shelvesVisible.value = true
+    currentEdit.value = data
+    Object.assign(shelves, {
+      name: data.label,
+      row: data.row,
+      col: data.col,
+      warehouseId: data.warehouseId
+    })
+  }
+}
+
+const handelDetail = (row) => {
+  current.value = row
+  isDetail.value = true
+}
+
+// 鏍规嵁鏂囨。鐘舵�佽繑鍥炲搴旂殑棰滆壊
+const getStatusColor = (status) => {
+  if (status === '姝e父') {
+    return '#34BD66' // 缁胯壊
+  } else if (status === '鍊熷嚭') {
+    return '#F56C6C' // 绾㈣壊
+  }
+  return '#606266' // 榛樿棰滆壊
+}
+
+const warehouseChange = (val) => {
+tableList.value = []
+let map = warehouse.value.find(a => {
+  return a && a.id === val ? a : null
+})
+if (map && map.children) {
+  shelf.value = map.children
+  entity.shelfId = ''
+} else {
+  shelf.value = []
+}
+currentEdit.value = null
+}
+
+const handleShelf = async(e) => {
+  if (e) {
+    tableLoading.value = true
+    let data = []
+    const res = await getWarehouseStructure({warehouseGoodsShelvesId:e})
+    if(res.code == 200){
+      data = res.data.map(m=>{
+        m.books = m.documentationDtoList|[]
+        return m
+      })
+    }else{
+      ElMessage.error(res.message)
+    }
+    setTimeout(() => {
+      tableLoading.value = false
+      let set = new Set()
+      tableList.value = []
+      let arr = []
+      
+      if (data && data.length > 0) {
+        data.forEach(m => {
+          if (m && m.row && m.col) {
+            set.add(m.col)
+            if (arr.length > 0) {
+              if (arr.find(n => n.row == m.row)) {
+                arr.push(m)
+              } else {
+                tableList.value.push(arr)
+                arr = []
+                arr.push(m)
+              }
+            } else {
+              arr.push(m)
+            }
+          }
+        })
+        
+        if (arr.length > 0) {
+          tableList.value.push(arr)
+        }
+      }
+      
+      rowList.value = []
+      for (let i = 0; i < set.size; i++) {
+        rowList.value.push(`${i + 1} 鍒梎)
+      }
+      console.log(6666, tableList.value,rowList.value,data)
+    }, 1000)
+  }
+}
+
+
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  selectList()
+})
+</script>
+
+<style scoped>
+  .main-content {
+    width: 100%;
+    height: 100%;
+    padding: 20px;
+    box-sizing: border-box;
+  }
+
+  .title {
+    height: 20px;
+    line-height: 20px;
+    margin-bottom: 20px;
+  }
+
+  .search {
+    background-color: #fff;
+    height: 80px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 20px;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+    margin-bottom: 20px;
+  }
+
+  .search_thing {
+    display: flex;
+    align-items: center;
+    height: 50px;
+    margin-right: 20px;
+  }
+
+  .search_label {
+    width: 90px;
+    font-size: 14px;
+    text-align: right;
+    color: #606266;
+    font-weight: 500;
+    margin-right: 10px;
+  }
+
+  .search_input {
+    width: 200px;
+  }
+
+  .table {
+    background-color: #fff;
+    width: 100%;
+    height: calc(100% - 100px);
+    padding: 20px;
+    overflow-y: auto;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  }
+
+  .el-form-item {
+    margin-bottom: 16px;
+  }
+
+  .btns {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+  }
+
+  .tables {
+    width: 100%;
+    height: 100%;
+    border-collapse: collapse;
+    border: 1px solid #e4e7ed;
+  }
+
+  .tables th {
+    font-size: 14px;
+    border: 1px solid #e4e7ed;
+    background-color: #fafafa;
+    padding: 8px;
+    font-weight: 500;
+  }
+
+  .tables td {
+    font-size: 12px;
+    text-align: center;
+    vertical-align: top;
+    border: 1px solid #e4e7ed;
+    padding: 8px;
+    box-sizing: border-box;
+    height: 120px;
+    background-color: #fff;
+  }
+
+  .tables ul {
+    list-style-type: none;
+  }
+
+  .tables ul li {
+    border-radius: 3px;
+    padding: 4px 10px;
+    box-sizing: border-box;
+    margin-bottom: 5px;
+    font-size: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: start;
+    color: #333333;
+    cursor: pointer;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+
+  .tables h4 {
+    color: #999999;
+    font-size: 14px;
+    font-weight: 400;
+    padding: 6px 0;
+  }
+
+  .tables i {
+    display: inline-block;
+    width: 6px;
+    height: 6px;
+    border-radius: 50%;
+    margin-right: 6px;
+  }
+
+  li:hover {
+    background: rgba(58, 123, 250, 0.18);
+  }
+
+  li:hover i {
+    background: #3A7BFA;
+  }
+
+  li:hover .num {
+    color: #3A7BFA;
+  }
+
+  .green {
+    background: #E0F6EA;
+  }
+
+  .green i {
+    background: #34BD66;
+  }
+
+  .green .num {
+    color: #34BD66;
+  }
+
+  .el-dialog {
+    position: relative;
+  }
+
+  .shaoma {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    color: #3A7BFA;
+    position: absolute;
+    top: 23px;
+    right: 54px;
+    cursor: pointer;
+  }
+
+  .folder-icon {
+    color: #409eff;
+    font-size: 16px;
+    margin-right: 6px;
+  }
+
+  .file-icon {
+    color: #67c23a;
+    font-size: 16px;
+    margin-right: 6px;
+  }
+
+  .node_i {
+    color: orange;
+    font-size: 18px;
+  }
+
+  .custom-tree-node .el-button {
+    opacity: 0;
+  }
+
+  .custom-tree-node:hover .el-button {
+    opacity: 1;
+  }
+
+  :deep(.el-loading-mask) {
+    z-index: 10;
+  }
+
+  .required-span {
+    color: #f56c6c;
+  }
+
+  .table-row {
+    border-bottom: 1px solid #e4e7ed;
+  }
+
+  .table-row:last-child {
+    border-bottom: none;
+  }
+
+  .column-header {
+    background-color: #fafafa !important;
+    font-weight: 500;
+    color: #606266;
+  }
+
+  .content {
+    transition: background-color 0.2s ease;
+  }
+
+  .content:hover {
+    background-color: #f5f7fa;
+  }
+</style>

--
Gitblit v1.9.3