8
0

template.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <template>
  2. <hc-drawer v-model="isShow" to-id="hc-main-box" is-close @close="drawerClose">
  3. <hc-body split>
  4. <template #left>
  5. <hc-card>
  6. <template #header>
  7. <hc-search-input v-model="searchTreeName" placeholder="请输入关键字" @search="searchTreeNameClick" />
  8. </template>
  9. <template v-if="isTreeMode === 1">
  10. <hc-lazy-tree
  11. v-if="isShow" :root-menu="treeMenuRoot" is-load-menu :h-props="treeProps" tree-key="id"
  12. @load-menu="treeLazyMenu" @load="treeLoadNode" @node-tap="treeNodeTap" @menu-tap="treeMenuClick"
  13. >
  14. <template #name="{ data }">
  15. <span class="text-16px font-400">{{ data.name }}</span>
  16. </template>
  17. </hc-lazy-tree>
  18. </template>
  19. <template v-if="isTreeMode === 2">
  20. <hc-data-tree
  21. ref="treeRef" :root-menu="treeMenuRoot" is-load-menu :h-props="treeProps" tree-key="id" :datas="treeData"
  22. @load-menu="treeDataMenu" @node-tap="treeNodeTap" @menu-tap="treeMenuClick"
  23. >
  24. <template #name="{ data }">
  25. <span class="text-16px font-400">{{ data.name }}</span>
  26. </template>
  27. </hc-data-tree>
  28. </template>
  29. </hc-card>
  30. </template>
  31. <hc-card>
  32. <template #header>
  33. <template v-if="isCheckd">
  34. <template v-if="tableTempExcelProps.file">
  35. <div class="table-temp-name truncate">
  36. <span>{{ tableTempExcelProps.title }}</span>
  37. <i class="i-iconoir-check-circle-solid" />
  38. </div>
  39. <el-button hc-btn type="primary">重新上传</el-button>
  40. <el-button hc-btn type="danger">删除</el-button>
  41. <el-button hc-btn type="success">下载Excel</el-button>
  42. </template>
  43. <template v-else>
  44. <el-button hc-btn type="primary">上传Excel</el-button>
  45. </template>
  46. <template v-if="excelInfo.templateExtension">
  47. <div class="table-temp-name truncate">
  48. <span>{{ excelInfo.templateExtension }}</span>
  49. <i class="i-iconoir-check-circle-solid" />
  50. </div>
  51. <el-button hc-btn type="danger">删除</el-button>
  52. <el-button hc-btn type="success">下载模板</el-button>
  53. </template>
  54. </template>
  55. <template v-else>
  56. <div class="text-red">该目录为根目录没有EXCEL文件</div>
  57. </template>
  58. </template>
  59. <template #extra>
  60. <el-button v-if="tableTempExcelProps.file" hc-btn type="primary" @click="fullScreenClick">全屏显示</el-button>
  61. </template>
  62. <div :id="tableTempExcelId" class="relative h-full">
  63. <hc-online-office v-if="isShow" ui="hc-table-temp-excel" :props="tableTempExcelProps" />
  64. </div>
  65. </hc-card>
  66. </hc-body>
  67. <!-- 新增清表 -->
  68. <HcAddExcel v-model="addExcelShow" :info="addExcelInfo" :type="addExcelType" @finish="addExcelFinish" />
  69. </hc-drawer>
  70. </template>
  71. <script setup>
  72. import { ref, watch } from 'vue'
  73. import { useAppStore } from '~src/store'
  74. import screenfull from 'screenfull'
  75. import { getArrValue, getObjValue, getRandom, isNullES } from 'js-fast-way'
  76. import HcAddExcel from './add-excel.vue'
  77. import mainApi from '~api/exctab/exceltab'
  78. const props = defineProps({
  79. data: {
  80. type: Object,
  81. default: () => ({}),
  82. },
  83. })
  84. //事件
  85. const emit = defineEmits(['close'])
  86. const store = useAppStore()
  87. const userInfo = ref(store.getUserInfo)
  88. //双向绑定
  89. const isShow = defineModel('modelValue', {
  90. default: false,
  91. })
  92. //监听数据
  93. const dataInfo = ref(props.data)
  94. watch(() => props.data, (data) => {
  95. dataInfo.value = data
  96. }, { immediate: true, deep: true })
  97. //监听显示
  98. watch(isShow, (val) => {
  99. if (val) getDataApi()
  100. })
  101. //处理相关数据
  102. const tableTempExcelId = ref('')
  103. const getDataApi = () => {
  104. tableTempExcelId.value = getRandom(6)
  105. }
  106. //树搜索
  107. const isTreeMode = ref(1) //1懒加载,2全加载
  108. const searchTreeName = ref('')
  109. const searchTreeNameClick = async () => {
  110. if (isNullES(searchTreeName.value)) {
  111. isTreeMode.value = 1
  112. } else {
  113. isTreeMode.value = 2
  114. await getTreeAllData()
  115. treeRef.value?.treeRef?.filter(searchTreeName.value)
  116. }
  117. }
  118. //树配置
  119. const treeRef = ref(null)
  120. const treeProps = {
  121. label: 'name',
  122. children: 'children',
  123. isLeaf: (item) => {
  124. return !item.hasChildren
  125. },
  126. }
  127. //树菜单根节点
  128. const treeMenuRoot = [
  129. { icon: 'add-circle', label: '新增', key: 'add' },
  130. { icon: 'delete-bin', label: '删除', key: 'del' },
  131. ]
  132. //懒加载树的菜单
  133. const treeLazyMenu = ({ item, level }, resolve) => {
  134. let newMenu = []
  135. if (item.fileType !== 3) {
  136. newMenu.push({ icon: 'add-circle', label: '新增', key: 'add' })
  137. }
  138. if (item.fileType !== 1) {
  139. newMenu.push({ icon: 'draft', label: '编辑', key: 'edit' })
  140. }
  141. if (level !== 1) {
  142. newMenu.push({ icon: 'sort-asc', label: '排序', key: 'sort' })
  143. }
  144. if (item.fileType !== 3) {
  145. newMenu.push({ icon: 'file-upload', label: '上传', key: 'upload' })
  146. }
  147. newMenu.push({ icon: 'delete-bin', label: '删除', key: 'del' })
  148. resolve(newMenu)
  149. }
  150. //全加载树的菜单
  151. const treeDataMenu = ({ node, item, level }, resolve) => {
  152. const { isLeaf } = node
  153. let newMenu = []
  154. if (item.fileType !== 3) {
  155. newMenu.push({ icon: 'add-circle', label: '新增', key: 'add' })
  156. }
  157. if (item.fileType !== 1) {
  158. newMenu.push({ icon: 'draft', label: '编辑', key: 'edit' })
  159. }
  160. if (isLeaf) {
  161. newMenu.push({ icon: 'sort-asc', label: '排序', key: 'sort' })
  162. }
  163. if (level !== 1) {
  164. newMenu.push({ icon: 'file-upload', label: '上传', key: 'upload' })
  165. }
  166. newMenu.push({ icon: 'delete-bin', label: '删除', key: 'del' })
  167. resolve(newMenu)
  168. }
  169. //菜单被点击
  170. const treeMenuClick = ({ key, data }) => {
  171. console.log(key)
  172. if (key === 'add') {
  173. addExcelInfo.value = getObjValue(data)
  174. addExcelType.value = '新增'
  175. addExcelShow.value = true
  176. }
  177. }
  178. //新增/编辑清表
  179. const addExcelShow = ref(false)
  180. const addExcelInfo = ref({})
  181. const addExcelType = ref('')
  182. const addExcelFinish = () => {
  183. }
  184. //全加载树
  185. const treeData = ref([])
  186. const getTreeAllData = async () => {
  187. const { data } = await mainApi.tabLazyTreeAll({
  188. modeId: dataInfo.value.id,
  189. //name: searchTreeName.value,
  190. name: '',
  191. })
  192. treeData.value = getArrValue(data)
  193. }
  194. //懒加载树
  195. const treeLoadNode = async ({ item, level }, resolve) => {
  196. const parentId = level === 0 ? 0 : item.id
  197. const { data } = await mainApi.tabLazyTree({
  198. parentId: parentId,
  199. modeId: dataInfo.value.id,
  200. })
  201. resolve(getArrValue(data))
  202. }
  203. //在线编辑表格文件的配置
  204. const tableTempExcelProps = ref({})
  205. //树节点被点击
  206. const nodeInfo = ref({})
  207. const isCheckd = ref(false)
  208. const treeNodeTap = ({ node, data }) => {
  209. nodeInfo.value = data
  210. if (!node.isLeaf) {
  211. tableTempExcelProps.value = {}
  212. isCheckd.value = true
  213. return
  214. }
  215. //处理详情
  216. if (data.fileType === 3) {
  217. isCheckd.value = true
  218. getDetailExcel(data.id)
  219. } else {
  220. isCheckd.value = false
  221. }
  222. }
  223. //获取模板详情
  224. const excelInfo = ref({})
  225. const getDetailExcel = async (dataId) => {
  226. const { code, data } = await mainApi.detailExcel(dataId)
  227. if (code !== 200) return
  228. const { id, extension, fileUrl } = getObjValue(data)
  229. const { user_id, user_name } = userInfo.value
  230. excelInfo.value = getObjValue(data)
  231. tableTempExcelProps.value = {
  232. type: 'xlsx',
  233. key: id + '_' + Math.random() + '',
  234. title: extension,
  235. file: fileUrl,
  236. userId: user_id,
  237. userName: user_name,
  238. }
  239. }
  240. //全屏显示
  241. const fullScreenClick = () => {
  242. // 判断是否支持
  243. if (!screenfull.isEnabled) {
  244. window.$message.warning('当前浏览器不支持全屏')
  245. return false
  246. }
  247. //指定全屏区域元素
  248. const element = document.getElementById(tableTempExcelId.value)
  249. if (element) screenfull.request(element)
  250. }
  251. //关闭抽屉
  252. const drawerClose = () => {
  253. isShow.value = false
  254. tableTempExcelProps.value = {}
  255. emit('close')
  256. }
  257. </script>
  258. <style scoped lang="scss">
  259. .table-temp-name {
  260. position: relative;
  261. box-sizing: border-box;
  262. min-width: 200px;
  263. height: 28px;
  264. border: 1px solid gainsboro;
  265. padding: 0 10px;
  266. border-radius: 3px;
  267. display: flex;
  268. justify-content: space-between;
  269. align-items: center;
  270. margin-right: 10px;
  271. font-size: 14px;
  272. i {
  273. color: #00a870;
  274. margin-left: 10px;
  275. }
  276. }
  277. .hc-table-temp-excel {
  278. position: relative;
  279. }
  280. </style>