Pārlūkot izejas kodu

feat: 编辑页功能完善

lanjianrong 4 gadi atpakaļ
vecāks
revīzija
aae3fcfc9b

+ 4 - 4
.env.production

@@ -1,11 +1,11 @@
 # Whether to open mock
-VITE_USE_MOCK = true
+VITE_USE_MOCK = false
 
 # public path
 VITE_PUBLIC_PATH = /
 
 # Delete console
-VITE_DROP_CONSOLE = true
+VITE_DROP_CONSOLE = false
 
 # Whether to enable gzip or brotli compression
 # Optional: gzip | brotli | none
@@ -13,14 +13,14 @@ VITE_DROP_CONSOLE = true
 VITE_BUILD_COMPRESS = 'none'
 
 # Basic interface address SPA
-VITE_GLOB_API_URL=/basic-api
+VITE_GLOB_API_URL=http://ljr.com
 
 # File upload address, optional
 # It can be forwarded by nginx or write the actual address directly
 VITE_GLOB_UPLOAD_URL=/upload
 
 # Interface prefix
-VITE_GLOB_API_URL_PREFIX=
+VITE_GLOB_API_URL_PREFIX=/api
 
 # Whether to enable image compression
 VITE_USE_IMAGEMIN= true

+ 4 - 0
src/api/model/tree.ts

@@ -14,6 +14,7 @@ export interface TreeResultModel {
   code: string
   contractId: string
   createTime: string
+  code2: string
   children: TreeResultModel[]
 }
 
@@ -22,6 +23,9 @@ export interface SectionAddParams {
   name: string
 }
 
+export interface SectionUpdateParams extends SectionAddParams {
+  code2: string
+}
 export interface SectionFileParams {
   id: string
   contractId: string

+ 20 - 3
src/api/sys/tree.ts

@@ -1,6 +1,7 @@
 import {
   SectionAddParams,
   SectionFileParams,
+  SectionUpdateParams,
   TreeResfulParams,
   TreeResultModel
 } from '../model/tree'
@@ -12,10 +13,11 @@ enum Api {
   Section = '/contract/section',
   SectionAll = '/contract/section/all',
   AddSection = '/contract/section/add', // 新增项目节
-  UpdateSection = '/contract/section/update', // 更新项目节名称
+  UpdateSection = '/contract/section/save', // 更新项目节
   UpOrDownSection = '/contract/section/serial', // 上下移
   UpgradeOrRelegateSection = '/contract/section/depth', // 升降级
-  SaveSectionFile = '/contract/file' // 保存项目节附件
+  SaveSectionFile = '/contract/file', // 保存项目节附件
+  DeleteSection = '/contract/section' // 删除项目节
 }
 
 /**
@@ -83,7 +85,7 @@ export function sectionAddApi(params: SectionAddParams, mode: ErrorMessageMode =
 /**
  * @description 更新目录
  */
-export function sectionUpdateApi(params: SectionAddParams, mode: ErrorMessageMode = 'message') {
+export function sectionUpdateApi(params: SectionUpdateParams, mode: ErrorMessageMode = 'message') {
   return defHttp.post(
     {
       url: Api.UpdateSection,
@@ -109,3 +111,18 @@ export function saveSectionFileApi(params: SectionFileParams, mode: ErrorMessage
     }
   )
 }
+
+/**
+ * @description 删除项目节
+ */
+export function delSectionApi(params: { id: string }, mode: ErrorMessageMode = 'message') {
+  return defHttp.delete(
+    {
+      url: Api.DeleteSection,
+      params
+    },
+    {
+      errorMessageMode: mode
+    }
+  )
+}

+ 23 - 5
src/views/design-directive/catalog/index.vue

@@ -59,7 +59,13 @@
           </section>
         </header>
         <section class="h-11/12 border-gray-400 border">
-          <!-- <PreviewPdf v-show="!showExcel" :url="pdfUrl"></PreviewPdf> -->
+          <!-- <PreviewPdf v-show="!showExcel" :url="pdfUrl" /> -->
+          <iframe v-if="showPdf" :src="pdfUrl" frameborder="0" width="100%" height="100%"></iframe>
+          <div
+            v-if="detail.name && !detail.fid"
+            class="h-full flex justify-center items-center text-2xl"
+            >暂未上传数据表</div
+          >
         </section>
       </div>
     </div>
@@ -123,7 +129,7 @@
       const replaceFields = { children: 'children', title: 'name', key: 'id' }
 
       const onSelect = (selectedKeys: Event, { selectedNodes }) => {
-        if (selectedKeys.length) {
+        if (selectedKeys!.length) {
           const {
             id,
             parentId,
@@ -164,8 +170,19 @@
 
       const showUploadBtn = computed(() => row.value.showUpload)
 
-      const showExcel = computed(() => /.(excel)|(xls)|(xlsl)$/.test(detail.value.ext))
-
+      const showExcel = computed(() => {
+        return /.(excel)|(xls)|(xlsl)$/.test(detail.value.ext)
+      })
+      const showPdf = computed(() => {
+        if (!detail.value.fid) {
+          return false
+        }
+        const isPdf = /.(pdf)|(PDF)$/.test(detail.value.ext)
+        if (!isPdf) {
+          return false
+        }
+        return true
+      })
       const uploadExecl = () => {
         downloadByUrl({
           url: 'http://localhost:7070' + detail.value.filepath
@@ -186,7 +203,8 @@
         showUploadBtn,
         showExcel,
         uploadExecl,
-        pdfUrl
+        pdfUrl,
+        showPdf
       }
     }
   })

+ 10 - 3
src/views/design-directive/catalog/pdf.vue

@@ -10,10 +10,13 @@
 </template>
 
 <script lang="ts">
-  import PDF from 'pdfjs-dist'
+  import { GlobalWorkerOptions, getDocument } from 'pdfjs-dist'
   import { defineComponent, PropType, reactive, ref, watch, toRefs } from 'vue'
   import { PdfData } from '/#/tree'
+  import workerSrc from 'pdfjs-dist/build/pdf.worker.entry'
+  GlobalWorkerOptions.workerSrc = workerSrc
   export default defineComponent({
+    name: 'PreviewPdf',
     props: { url: { type: String as PropType<string>, required: true } },
     setup(props) {
       const pdfCanvas = ref(null)
@@ -32,7 +35,7 @@
       function loadPdf(url: string) {
         // 引入pdf.js的字体
         let CMAP_URL = 'https://unpkg.com/pdfjs-dist@2.0.943/cmaps/'
-        pdfData.value = PDF.getDocument({
+        pdfData.value = getDocument({
           url,
           cMapUrl: CMAP_URL,
           cMapPacked: true
@@ -58,7 +61,11 @@
 
       function renderPage(num: number) {
         pdfVM.renderingPage = true
-        pdfData.value.then(pdf => {
+        console.log(pdfData.value)
+
+        pdfData.value?.promise?.then(pdf => {
+          console.log(111)
+
           pdfVM.pdfPageNumber = pdf.numPages
           pdf.getPage(num).then(page => {
             // 获取DOM中为预览PDF准备好的canvasDOM对象

+ 88 - 23
src/views/design-directive/management/index.vue

@@ -30,6 +30,12 @@
                 @pressEnter="onSave(record.id)"
               />
               <check-outlined class="editable-cell-icon-check" @click="onSave(record.id)" />
+
+              <CloseOutlined
+                class="editable-cell-icon-check"
+                :style="{ right: '-24px' }"
+                @click="onCancel(record.id)"
+              />
             </div>
             <div v-else class="editable-cell-text-wrapper">
               {{ text || ' ' }}
@@ -54,35 +60,51 @@
     >
       <div class="p-3">
         <a-form :model="formState" :rules="rules" layout="vertical" ref="formRef">
-          <a-form-item name="name" required label="节点名称">
-            <a-input v-model:value="formState.name" />
+          <a-form-item name="name" required label="名称">
+            <a-input v-model:value="formState.name" autocomplete="off" class="w-6" />
           </a-form-item>
-          <a-form-item name="id" required label="父级">
+          <a-form-item
+            name="id"
+            required
+            :label="treeSelectLabel"
+            :hidden="type === 'edit' ? true : false"
+          >
             <a-tree-select
               v-model:value="formState.id"
-              :treeData="treeData"
+              :treeData="treeSelectData"
               :replace-fields="replaceFields"
               :tree-default-expand-all="true"
               :dropdown-style="{ height: '20rem' }"
             />
           </a-form-item>
+          <a-form-item name="code2" label="图标编码">
+            <a-input v-model:value="formState.code2" autocomplete="off" />
+          </a-form-item>
         </a-form>
       </div>
     </AModal>
   </div>
 </template>
 <script lang="ts">
-  import { computed, defineComponent, reactive, ref, toRaw, toRefs, UnwrapRef } from 'vue'
+  import { computed, defineComponent, reactive, ref, toRaw, toRefs, unref, UnwrapRef } from 'vue'
   import { useDesign } from '/@/hooks/web/useDesign'
   import { Table, Modal, Form, Input, TreeSelect, Popconfirm, message } from 'ant-design-vue'
-  import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue'
-  import { sectionAddApi, sectionAllApi, sectionUpdateApi, treeResfulApi } from '/@/api/sys/tree'
+  import { CheckOutlined, EditOutlined, CloseOutlined } from '@ant-design/icons-vue'
+  import {
+    delSectionApi,
+    sectionAddApi,
+    sectionAllApi,
+    sectionUpdateApi,
+    treeResfulApi
+  } from '/@/api/sys/tree'
   import { TreeResultModel } from '/@/api/model/tree'
   import { TreeRow } from '/#/tree'
+  import { useMessage } from '/@/hooks/web/useMessage'
 
   interface FormState {
     id: string
     name: string
+    code2: string
   }
   enum ModalType {
     ADD = 'add',
@@ -99,6 +121,7 @@
       AFormItem: Form.Item,
       CheckOutlined,
       EditOutlined,
+      CloseOutlined,
       APopconfirm: Popconfirm
     },
     setup() {
@@ -116,7 +139,8 @@
         serial: 0,
         attribution: '',
         contractId: '',
-        createTime: ''
+        createTime: '',
+        code2: ''
       })
       const modal = reactive({
         visible: false,
@@ -124,13 +148,27 @@
       })
       const formState: UnwrapRef<FormState> = reactive({
         id: '',
-        name: ''
+        name: '',
+        code2: ''
       })
 
       // 目录操作相关
       const toggleModal = (type?: string) => {
         // 要打开form弹窗了, 设置当前的表单值
         if (!modal.visible) {
+          if (row.value.id && type) {
+            const unRow = unref(row)
+            if (type === ModalType.ADD) {
+              formState.id = unRow.depth === 3 ? unRow.parentId : unRow.id
+            } else {
+              formState.id = unRow.id
+              formState.name = unRow.name
+              formState.code2 = unRow.code2
+            }
+          } else {
+            const { createMessage } = useMessage()
+            return createMessage.warning('请先选择节点再进行操作')
+          }
         }
         modal.visible = !modal.visible
         type && (modal.type = type)
@@ -148,10 +186,10 @@
         }
       }
 
-      const onConfirm = () => {
+      const onConfirm = async () => {
         try {
-          onSubmit()
-          initData()
+          await onSubmit()
+          await initData()
           toggleModal()
         } catch (error) {}
       }
@@ -194,9 +232,9 @@
         },
         {
           title: '图表编码',
-          dataIndex: 'code',
-          key: 'code',
-          slots: { customRender: 'code' }
+          dataIndex: 'code2',
+          key: 'code2',
+          slots: { customRender: 'code2' }
         },
         {
           title: '操作',
@@ -220,24 +258,47 @@
         editableData[key] = record
       }
 
-      const onSave = (key: string) => {
-        delete editableData[key]
+      const onSave = async (key: string) => {
+        const { id, name, code2 } = toRaw(editableData[key])
+        await sectionUpdateApi({ id, name, code2 })
         // 执行保存请求 后初始化数据
-        // initData()
+        delete editableData[key]
+        initData()
       }
 
-      const onDelete = (key: string) => {
-        // 执行删除请求 后初始化数据
-        // initData()
+      const onCancel = async (key: string) => {
+        delete editableData[key]
+      }
+      const onDelete = async (key: string) => {
+        try {
+          await delSectionApi({ id: key })
+          await initData()
+        } catch (error) {}
       }
 
       const rules = {
         name: [{ required: true, message: '请输入名称' }],
-        id: [{ required: true, message: '请选择父节点' }]
+        id: [
+          { required: true, message: modal.type === ModalType.ADD ? '请选择父节点' : '请选择节点' }
+        ]
       }
 
       const replaceFields = { children: 'children', title: 'name', value: 'id' }
 
+      const treeSelectData = computed(() => {
+        if (modal.type === ModalType.ADD) {
+          return treeData.value.map(item => {
+            const newItem = { ...item }
+            if (item.children && item.children.length) {
+              newItem.children = item.children.map(item => ({ ...item, children: [] }))
+            }
+            return newItem
+          })
+        }
+        return treeData.value
+      })
+
+      const treeSelectLabel = computed(() => (modal.type === ModalType.ADD ? '父级目录' : '节点'))
       return {
         ...toRefs(modal),
         prefixCls,
@@ -257,7 +318,10 @@
         onEdit,
         onSave,
         onDelete,
-        handleTreeOpreate
+        handleTreeOpreate,
+        treeSelectData,
+        treeSelectLabel,
+        onCancel
       }
     }
   })
@@ -277,6 +341,7 @@
     }
     .editable-cell {
       position: relative;
+      width: 50%;
       .editable-cell-input-wrapper,
       .editable-cell-text-wrapper {
         padding-right: 24px;