index.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <div :class="prefixCls" class="m-5 bg-white">
  3. <div class="flex flex-nowrap w-full h-full">
  4. <div class="w-1/4 border-gray-400 border">
  5. <header class="p-2 flex justify-between items-center h-12">
  6. <div class="w-1/2">
  7. <BasicUpload
  8. v-show="showUploadBtn"
  9. :max-size="20"
  10. :max-number="1"
  11. @change="handleChange"
  12. :api="uploadApi"
  13. :showPreviewNumber="false"
  14. :emptyHidePreview="true"
  15. :accept="['xlsx', 'xls', 'pdf']"
  16. />
  17. </div>
  18. <div class="flex flex-row w-1/2 justify-end">
  19. <span class="flex align-middle cursor-pointer" @click="handleTreeOpreate('upSerial')">
  20. <Icon icon="mdi:arrow-up" :size="18" />
  21. 上移
  22. </span>
  23. <span
  24. class="flex align-middle ml-1 cursor-pointer"
  25. @click="handleTreeOpreate('downSerial')"
  26. >
  27. <Icon icon="mdi:arrow-down" :size="18" />
  28. 下移
  29. </span>
  30. </div>
  31. </header>
  32. <section>
  33. <BasicTree
  34. v-if="treeData.length"
  35. :tree-data="treeData"
  36. :replace-fields="replaceFields"
  37. :show-line="true"
  38. :defaultExpandAll="true"
  39. @select="onSelect"
  40. />
  41. </section>
  42. </div>
  43. <div class="w-3/4 ml-4 flex flex-col">
  44. <header class="h-1/12 mt-2 flex justify-between items-center">
  45. <span class="text-3xl font-bold">{{ detail.name }}</span>
  46. <section>
  47. <AButton
  48. v-show="showExcel"
  49. type="primary"
  50. size="small"
  51. class="mr-4"
  52. @click="uploadExecl"
  53. >下载Excel</AButton
  54. >
  55. <!-- <AButton type="primary" size="small" class="mx-1">下载PDF</AButton> -->
  56. <!-- <AButton type="primary" size="small" class="mx-1">编辑</AButton> -->
  57. <!-- <span class="h-full border-l-1 border-gray-400 mx-1"></span> -->
  58. <!-- <AButton type="primary" size="small" class="mx-1 mr-4">下载</AButton> -->
  59. </section>
  60. </header>
  61. <section class="h-11/12 border-gray-400 border">
  62. <!-- <PreviewPdf v-show="!showExcel" :url="pdfUrl" /> -->
  63. <iframe v-if="showPdf" :src="pdfUrl" frameborder="0" width="100%" height="100%"></iframe>
  64. <div
  65. v-if="detail.name && !detail.fid"
  66. class="h-full flex justify-center items-center text-2xl"
  67. >暂未上传数据表</div
  68. >
  69. </section>
  70. </div>
  71. </div>
  72. </div>
  73. </template>
  74. <script lang="ts">
  75. import { computed, defineComponent, ref, watch } from 'vue'
  76. import { saveSectionFileApi, sectionAllApi, treeDetailApi, treeResfulApi } from '/@/api/sys/tree'
  77. import { useDesign } from '/@/hooks/web/useDesign'
  78. import { BasicTree } from '/@/components/Tree/index'
  79. import { Icon } from '/@/components/Icon'
  80. import { message } from 'ant-design-vue'
  81. import { TreeResultModel } from '/@/api/model/tree'
  82. import { BasicUpload } from '/@/components/Upload'
  83. import { uploadApi } from '/@/api/sys/upload'
  84. import { TreeRow } from '/#/tree'
  85. import { downloadByUrl } from '/@/utils/file/download'
  86. import PreviewPdf from './pdf.vue'
  87. interface ATreeRow extends TreeRow {
  88. showUpload: boolean
  89. }
  90. export default defineComponent({
  91. name: 'Catalog',
  92. components: { BasicTree, Icon, BasicUpload, PreviewPdf },
  93. setup() {
  94. const treeData = ref<TreeResultModel[]>([])
  95. const row = ref<ATreeRow>({
  96. id: '',
  97. parentId: '',
  98. name: '',
  99. depth: 0,
  100. serial: 0,
  101. attribution: '',
  102. code: '',
  103. contractId: '',
  104. createTime: '',
  105. showUpload: false
  106. })
  107. const detail = ref({ name: '', content: '', filepath: '', filename: '', ext: '', fid: '' })
  108. async function initData() {
  109. const result = await sectionAllApi()
  110. treeData.value = result.children
  111. }
  112. async function initSectionDetail(id: string) {
  113. const result = await treeDetailApi(id)
  114. detail.value = result
  115. }
  116. initData()
  117. const handleTreeOpreate = async (operation: 'upSerial' | 'downSerial') => {
  118. const id = row.value.id
  119. if (!id) {
  120. return message.error('请先选中节点')
  121. }
  122. await treeResfulApi({ id, type: 'serial', operation })
  123. await initData()
  124. }
  125. const { prefixCls } = useDesign('catalog')
  126. const replaceFields = { children: 'children', title: 'name', key: 'id' }
  127. const onSelect = (selectedKeys: Event, { selectedNodes }) => {
  128. if (selectedKeys!.length) {
  129. const {
  130. id,
  131. parentId,
  132. name,
  133. depth,
  134. serial,
  135. attribution,
  136. code,
  137. contractId,
  138. children,
  139. createTime
  140. } = selectedNodes[0]?.props
  141. row.value = {
  142. showUpload: children && children.length ? false : true,
  143. id,
  144. parentId,
  145. name,
  146. depth,
  147. serial,
  148. attribution,
  149. code,
  150. contractId,
  151. createTime
  152. }
  153. }
  154. }
  155. watch(row, (row, prevRow) => {
  156. if (row.id !== prevRow.id) {
  157. initSectionDetail(row.id)
  158. }
  159. })
  160. const handleChange = async (list: string[]) => {
  161. await saveSectionFileApi({ id: row.value.id, contractId: list[0] })
  162. await initSectionDetail(row.value.id)
  163. }
  164. const showUploadBtn = computed(() => row.value.showUpload)
  165. const showExcel = computed(() => {
  166. return /.(excel)|(xls)|(xlsl)$/.test(detail.value.ext)
  167. })
  168. const showPdf = computed(() => {
  169. if (!detail.value.fid) {
  170. return false
  171. }
  172. const isPdf = /.(pdf)|(PDF)$/.test(detail.value.ext)
  173. if (!isPdf) {
  174. return false
  175. }
  176. return true
  177. })
  178. const uploadExecl = () => {
  179. downloadByUrl({
  180. url: 'http://localhost:7070' + detail.value.filepath
  181. })
  182. }
  183. const pdfUrl = computed(() => 'http://localhost:7070' + detail.value.filepath)
  184. return {
  185. treeData,
  186. replaceFields,
  187. prefixCls,
  188. onSelect,
  189. handleTreeOpreate,
  190. detail,
  191. uploadApi,
  192. handleChange,
  193. row,
  194. showUploadBtn,
  195. showExcel,
  196. uploadExecl,
  197. pdfUrl,
  198. showPdf
  199. }
  200. }
  201. })
  202. </script>
  203. <style lang="less" scoped>
  204. @prefix-cls: ~'@{namespace}-catalog';
  205. .@{prefix-cls} {
  206. width: calc(100% - 2.5rem);
  207. height: calc(100% - 2.5rem);
  208. overflow: hidden;
  209. }
  210. </style>