index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 h-full">
  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. :show-preview-number="false"
  14. :empty-hide-preview="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. <div class="tree">
  33. <Tree
  34. v-if="treeData && treeData[0] && treeData[0].children"
  35. :tree-data="treeData[0].children"
  36. :replace-fields="replaceFields"
  37. :show-line="true"
  38. :default-expand-all="true"
  39. @select="onSelect"
  40. />
  41. </div>
  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. <div class="flex">
  46. <span class="text-2xl font-bold">{{ detail.name }}</span>
  47. <span v-show="showUploadBtn" class="flex ml-3">
  48. <BasicUpload
  49. :max-size="20"
  50. :max-number="1"
  51. @change="handleChange"
  52. :api="uploadApi"
  53. :show-preview-number="false"
  54. :empty-hide-preview="true"
  55. :accept="['pdf', 'PDF']"
  56. btn-text="上传PDF"
  57. />
  58. <BasicUpload
  59. :max-size="20"
  60. :max-number="1"
  61. @change="handleChange"
  62. :api="uploadApi"
  63. :show-preview-number="false"
  64. :empty-hide-preview="true"
  65. :accept="['xlsx', 'xls']"
  66. btn-text="上传excel"
  67. class="ml-2"
  68. btn-type="success"
  69. />
  70. </span>
  71. </div>
  72. <span class="mr-4" v-show="showExcelDownload">
  73. <AButton v-if="detail.excelData.fid" type="primary" @click="uploadExecl"
  74. >下载Excel</AButton
  75. >
  76. </span>
  77. <!-- <AButton type="primary" size="small" class="mx-1">下载PDF</AButton> -->
  78. <!-- <AButton type="primary" size="small" class="mx-1">编辑</AButton> -->
  79. <!-- <AButton type="primary" class="mx-1 mr-4">下载</AButton> -->
  80. </header>
  81. <section class="h-11/12 border-gray-400 border">
  82. <!-- <PreviewPdf v-show="!showExcel" :url="pdfUrl" /> -->
  83. <iframe v-if="showPdf" :src="pdfUrl" frameborder="0" width="100%" height="100%"></iframe>
  84. <div
  85. v-if="detail.name && !detail.pdfData.fid"
  86. class="h-full flex justify-center items-center text-2xl"
  87. >暂未上传可供预览的pdf文件</div
  88. >
  89. </section>
  90. </div>
  91. </div>
  92. </div>
  93. </template>
  94. <script lang="ts">
  95. import { computed, defineComponent, onActivated, ref, watch } from 'vue'
  96. import { saveSectionFileApi, sectionAllApi, treeDetailApi, treeResfulApi } from '/@/api/sys/tree'
  97. import { useDesign } from '/@/hooks/web/useDesign'
  98. import { message, Tree } from 'ant-design-vue'
  99. import { TreeResultModel } from '/@/api/model/tree'
  100. import { BasicUpload } from '/@/components/Upload'
  101. import { uploadApi } from '/@/api/sys/upload'
  102. import { TreeRow } from '/#/tree'
  103. import { downloadByUrl } from '/@/utils/file/download'
  104. import { Icon } from '/@/components/Icon'
  105. interface ATreeRow extends TreeRow {
  106. showUpload: boolean
  107. }
  108. export default defineComponent({
  109. name: 'Catalog',
  110. components: { Icon, BasicUpload, Tree },
  111. setup() {
  112. const treeData = ref<TreeResultModel[]>([])
  113. const row = ref<ATreeRow>({
  114. id: '',
  115. parentId: '',
  116. name: '',
  117. depth: 0,
  118. serial: 0,
  119. attribution: '',
  120. code: '',
  121. code2: '',
  122. contractId: '',
  123. createTime: '',
  124. showUpload: false
  125. })
  126. const detail = ref({
  127. name: '',
  128. pdfData: { content: '', filepath: '', filename: '', ext: '', fid: '' },
  129. excelData: { content: '', filepath: '', filename: '', ext: '', fid: '' }
  130. })
  131. async function initData() {
  132. const result = await sectionAllApi()
  133. treeData.value = result
  134. }
  135. async function initSectionDetail(id: string) {
  136. const result = await treeDetailApi(id)
  137. detail.value = result
  138. }
  139. initData()
  140. const handleTreeOpreate = async (operation: 'upSerial' | 'downSerial') => {
  141. const id = row.value.id
  142. if (!id) {
  143. return message.error('请先选中节点')
  144. }
  145. await treeResfulApi({ id, type: 'serial', operation })
  146. await initData()
  147. }
  148. onActivated(() => initData())
  149. const { prefixCls } = useDesign('catalog')
  150. const replaceFields = { children: 'children', title: 'name', key: 'id' }
  151. const onSelect = (selectedKeys: Event, { selectedNodes }) => {
  152. if (selectedKeys && selectedNodes && selectedKeys!.length) {
  153. const {
  154. id,
  155. parentId,
  156. name,
  157. depth,
  158. serial,
  159. attribution,
  160. code,
  161. code2,
  162. contractId,
  163. children,
  164. createTime
  165. } = selectedNodes[0]?.props
  166. row.value = {
  167. showUpload: depth > 2 ? (children && children.length ? false : true) : false,
  168. id,
  169. parentId,
  170. name,
  171. depth,
  172. serial,
  173. attribution,
  174. code,
  175. code2,
  176. contractId,
  177. createTime
  178. }
  179. }
  180. }
  181. watch(row, (row, prevRow) => {
  182. if (row.id !== prevRow.id) {
  183. initSectionDetail(row.id)
  184. }
  185. })
  186. const handleChange = async (list: string[]) => {
  187. await saveSectionFileApi({ id: row.value.id, contractId: list[0] })
  188. await initSectionDetail(row.value.id)
  189. }
  190. const showUploadBtn = computed(() => row.value.showUpload)
  191. const showExcelDownload = computed(() => detail.value.excelData.fid)
  192. const showPdf = computed(() => {
  193. if (!detail.value.pdfData.fid) {
  194. return false
  195. }
  196. return true
  197. })
  198. const uploadExecl = () => {
  199. downloadByUrl({
  200. url: 'http://sj.6jlzf.cn/static' + detail.value.excelData.filepath
  201. })
  202. }
  203. const pdfUrl = computed(() => 'http://sj.6jlzf.cn/static' + detail.value.pdfData.filepath)
  204. return {
  205. treeData,
  206. replaceFields,
  207. prefixCls,
  208. onSelect,
  209. handleTreeOpreate,
  210. detail,
  211. uploadApi,
  212. handleChange,
  213. row,
  214. showUploadBtn,
  215. showExcelDownload,
  216. uploadExecl,
  217. pdfUrl,
  218. showPdf
  219. }
  220. }
  221. })
  222. </script>
  223. <style lang="less" scoped>
  224. @prefix-cls: ~'@{namespace}-catalog';
  225. .@{prefix-cls} {
  226. width: calc(100% - 2.5rem);
  227. height: calc(100% - 2.5rem);
  228. overflow: hidden;
  229. .tree {
  230. height: calc(100% - 48px);
  231. max-height: 809px;
  232. overflow-x: scroll;
  233. overflow-y: scroll;
  234. }
  235. }
  236. </style>