Browse Source

附件上传功能对接

songxy 1 năm trước cách đây
mục cha
commit
53c45ed8fe

+ 25 - 0
client/src/utils/tree.ts

@@ -402,3 +402,28 @@ export const filterNodeMethod = (value, data) => {
   if (!data) return
   return data.name.includes(value)
 }
+
+export const treeValuePath = (treeData, nodeId) => {
+  function traverse(nodes) {
+    for (const node of nodes) {
+      if (node.id === nodeId) {
+        return [node.label]
+      }
+      if (node.children) {
+        const path = traverse(node.children)
+        if (path) {
+          return [node.label, ...path]
+        }
+      }
+    }
+    return null
+  }
+
+  for (const rootNode of treeData) {
+    const path = traverse([rootNode])
+    if (path) {
+      return path
+    }
+  }
+  return []
+}

+ 2 - 2
client/src/views/Login/components/LoginForm.vue

@@ -177,8 +177,8 @@ const loginData = reactive({
   tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,
   loginForm: {
     tenantName: '芋道源码',
-    username: 'admin',
-    password: 'admin123',
+    username: '',
+    password: '',
     captchaVerification: '',
     rememberMe: false
   }

+ 3 - 0
client/src/views/OaSystem/projectCenter/projectDetail/components/fjcl/index.scss

@@ -55,6 +55,9 @@
       }
     }
   }
+  :deep(.el-tree-node) {
+    padding: 5px 0px;
+  }
   :deep(.el-tree-node__content>.el-tree-node__expand-icon) {
     padding-left: 0px !important;
   }

+ 90 - 36
client/src/views/OaSystem/projectCenter/projectDetail/components/fjcl/index.vue

@@ -3,14 +3,38 @@
     <div class="treeBox">
       <h4>材料分类</h4>
       <div>
-        <el-tree
-          :data="treeData"
-          :render-content="renderContent"
-          :props="defaultProps"
-          @node-click="handleNodeClick"
-        />
+        <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick">
+          <template #default="{ data }">
+            <el-dropdown :hide-on-click="false" trigger="contextmenu">
+              <span class="custom-tree-node">
+                <el-icon
+                  style="
+                    margin-right: 5px;
+                    margin-top: -4px;
+                    vertical-align: middle;
+                    font-size: 18px;
+                  "
+                >
+                  <Document v-if="data.type == '3'" style="color: #2e77e6" />
+                  <Folder v-else style="color: #f9a527" />
+                </el-icon>
+                <span>{{ data.name }}</span>
+              </span>
+              <template #dropdown>
+                <el-dropdown-menu>
+                  <el-dropdown-item v-if="data.type !== 3" @click="uploadClick(data)"
+                    >上传</el-dropdown-item
+                  >
+                  <el-dropdown-item>下载</el-dropdown-item>
+                  <el-dropdown-item v-if="data.type === 3" divided>删除</el-dropdown-item>
+                </el-dropdown-menu>
+              </template>
+            </el-dropdown>
+          </template>
+        </el-tree>
       </div>
     </div>
+    <input type="file" ref="fileRef" style="display: none" @change="fileChageHandle" />
     <div class="previewBox">
       <div class="tools">
         <h4>{{ fileInfo?.['fileName'] }}</h4>
@@ -33,6 +57,7 @@ import { onMounted } from 'vue'
 import { useRoute } from 'vue-router'
 import request from '@/config/axios'
 import VueOfficePdf from '@vue-office/pdf'
+import { listToTree, treeValuePath } from '@/utils/tree'
 import '@vue-office/excel/lib/index.css'
 import '@vue-office/docx/lib/index.css'
 
@@ -74,45 +99,74 @@ interface Tree {
   children?: Array<Tree>
 }
 const treeData = ref<Tree[]>([])
+
+type MaterialPath = {
+  label: string
+  id: string
+  children: MaterialPath[]
+}
+const materialPathTree = ref<MaterialPath[]>([])
 const queryProjectMaterialByTree = (): void => {
-  const urlApi = `/project-material/tree`
-  request.post({ url: urlApi, data: { projectId: projectId } }, '/business').then((resultData) => {
-    treeData.value = resultData
+  const urlApi = `/project-material-tree`
+  request.get({ url: urlApi, params: { projectId: projectId } }, '/business').then((resultData) => {
+    materialPathTree.value = listToTree(
+      resultData
+        .map((item) => {
+          if (item.type !== 3) {
+            return {
+              label: item['extendData']['mark'],
+              id: item['id'],
+              pid: item['pid'],
+              children: []
+            }
+          }
+        })
+        .filter((item) => item)
+    )
+    treeData.value = listToTree(resultData)
   })
 }
 const queryProjectMaterial = (fileId): void => {
-  const urlApi = `/project-material?id=${fileId}`
+  const urlApi = `/project-material-get?id=${fileId}`
   request.get({ url: urlApi }, '/business').then((resultData) => {
     fileInfo.value = resultData
   })
 }
-const downloadFile = (): void => {}
-const renderContent = (h, { node, data, store }) => {
-  return h(
-    'span',
-    {
-      style: {
-        display: 'inline-block',
-        width: '100%'
-      }
-    },
-    [
-      h('span', [
-        h(resolveComponent(data['nodeType'] === 1 ? 'Document' : 'Folder'), {
-          style: {
-            marginRight: '5px',
-            marginTop: '-4px',
-            verticalAlign: 'middle',
-            width: '18px',
-            height: '18px',
-            color: data['nodeType'] === 1 ? '#2e77e6' : '#f9a527'
-          }
-        }),
-        h('span', data.name)
-      ])
-    ]
-  )
+
+/***
+ * 文件上传
+ */
+const fileRef = ref(null)
+const fileChageHandle = (evt) => {
+  const files = evt.target.files // 获取文件列表
+  uploadProjectMaterial(files[0])
+}
+const currentMaterialsId = ref<string>('')
+const currentMaterialPath = ref<string>()
+const uploadClick = (data) => {
+  currentMaterialsId.value = data.id as string
+  if (data.type !== 3) {
+    const arr: string[] = treeValuePath(materialPathTree.value, data.id)
+    if (arr && arr.length > 0) {
+      currentMaterialPath.value = arr.join('/')
+      currentMaterialsId.value = data.id
+      //@ts-ignore
+      fileRef.value.click()
+    }
+  }
 }
+const uploadProjectMaterial = (file): void => {
+  const urlApi = `/project-material-upload`
+  const formData = new FormData()
+  formData.append('projectId', projectId as string)
+  formData.append('file', file)
+  formData.append('prePath', currentMaterialPath.value as string)
+  formData.append('flowMaterialsId', currentMaterialsId.value as string)
+  request.upload({ url: urlApi, data: formData }, '/business').then((resultData) => {
+    fileInfo.value = resultData
+  })
+}
+const downloadFile = (): void => {}
 onMounted(() => {
   queryProjectMaterialByTree()
 })