index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <a-row :gutter="10">
  3. <a-col :xs="24" :sm="24" :md="24" :lg="5" :xl="5">
  4. <a-card :bordered="false" :loading="cardLoading" class="left-tree-container">
  5. <a-tree
  6. v-if="treeData.length > 0"
  7. v-model:expandedKeys="defaultExpandedKeys"
  8. :tree-data="treeData"
  9. :field-names="treeFieldNames"
  10. @select="treeSelect"
  11. />
  12. <a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
  13. </a-card>
  14. </a-col>
  15. <a-col :xs="24" :sm="24" :md="24" :lg="19" :xl="19">
  16. <a-card :bordered="false" class="xn-mb10">
  17. <a-form
  18. ref="searchFormRef"
  19. name="advanced_search"
  20. class="ant-advanced-search-form mb-3"
  21. :model="searchFormState"
  22. >
  23. <a-row :gutter="24">
  24. <a-col :span="8">
  25. <a-form-item name="searchKey" label="字典名称">
  26. <a-input v-model:value="searchFormState.searchKey" placeholder="请输入字典名称" />
  27. </a-form-item>
  28. </a-col>
  29. <a-col :span="8">
  30. <a-button type="primary" @click="tableRef.refresh(true)">
  31. <template #icon><SearchOutlined /></template>
  32. 查询
  33. </a-button>
  34. <a-button class="snowy-button-left" @click="reset">
  35. <template #icon><redo-outlined /></template>
  36. 重置
  37. </a-button>
  38. </a-col>
  39. </a-row>
  40. </a-form>
  41. </a-card>
  42. <a-card :bordered="false" class="xn-mb10">
  43. <s-table
  44. ref="tableRef"
  45. :columns="columns"
  46. :data="loadData"
  47. :expand-row-by-click="true"
  48. bordered
  49. :tool-config="toolConfig"
  50. :row-key="(record) => record.id"
  51. >
  52. <template #bodyCell="{ column, record }">
  53. <template v-if="column.dataIndex === 'level'">
  54. <a-tag color="blue" v-if="record.level">{{ record.level }}</a-tag>
  55. <a-tag color="green" v-else>子级</a-tag>
  56. </template>
  57. <template v-if="column.dataIndex === 'action'">
  58. <a @click="formRef.onOpen(record)" v-if="hasPerm('bizDictEdit')">编辑</a>
  59. </template>
  60. </template>
  61. </s-table>
  62. </a-card>
  63. </a-col>
  64. </a-row>
  65. <Form ref="formRef" @successful="formSuccessful()" />
  66. </template>
  67. <script setup>
  68. import { Empty } from 'ant-design-vue'
  69. import bizDictApi from '@/api/biz/bizDictApi'
  70. import Form from './form.vue'
  71. import tool from '@/utils/tool'
  72. const columns = [
  73. {
  74. title: '字典名称',
  75. dataIndex: 'dictLabel',
  76. width: 350
  77. },
  78. {
  79. title: '字典值',
  80. dataIndex: 'dictValue',
  81. width: 350
  82. },
  83. {
  84. title: '排序',
  85. dataIndex: 'sortCode'
  86. }
  87. ]
  88. if (hasPerm('bizDictEdit')) {
  89. columns.push({
  90. title: '操作',
  91. dataIndex: 'action',
  92. align: 'center',
  93. width: '150px'
  94. })
  95. }
  96. // 定义tableDOM
  97. const tableRef = ref(null)
  98. const formRef = ref()
  99. const cardLoading = ref(true)
  100. const searchFormRef = ref()
  101. const searchFormState = ref({})
  102. // 默认展开的节点
  103. const defaultExpandedKeys = ref([])
  104. const treeData = ref([])
  105. // 替换treeNode 中 title,key,children
  106. const treeFieldNames = { children: 'children', title: 'dictLabel', key: 'id' }
  107. const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
  108. // 表格查询 返回 Promise 对象
  109. const loadData = (parameter) => {
  110. loadTreeData()
  111. return bizDictApi.dictPage(Object.assign(parameter, searchFormState.value)).then((data) => {
  112. if (data.records) {
  113. if (searchFormState.value.parentId) {
  114. let dataArray = []
  115. data.records.forEach((item) => {
  116. const obj = data.records.find((f) => f.id === item.parentId)
  117. if (!obj) {
  118. dataArray.push(item)
  119. }
  120. })
  121. if (dataArray.length === 1) {
  122. data.records.forEach((item) => {
  123. if (item.id === dataArray[0].id) {
  124. item.level = '上级'
  125. }
  126. })
  127. }
  128. dataArray = []
  129. }
  130. }
  131. return data
  132. })
  133. }
  134. // 重置
  135. const reset = () => {
  136. searchFormRef.value.resetFields()
  137. tableRef.value.refresh(true)
  138. }
  139. // 加载左侧的树
  140. const loadTreeData = () => {
  141. bizDictApi
  142. .dictTree()
  143. .then((res) => {
  144. if (res) {
  145. treeData.value = res
  146. }
  147. })
  148. .finally(() => {
  149. cardLoading.value = false
  150. })
  151. }
  152. // 点击树查询
  153. const treeSelect = (selectedKeys) => {
  154. if (selectedKeys && selectedKeys.length > 0) {
  155. searchFormState.value.parentId = selectedKeys.toString()
  156. if (!columns.find((f) => f.title === '层级')) {
  157. columns.splice(2, 0, {
  158. title: '层级',
  159. dataIndex: 'level',
  160. width: 100
  161. })
  162. }
  163. } else {
  164. delete searchFormState.value.parentId
  165. columns.splice(2, 1)
  166. }
  167. tableRef.value.refresh(true)
  168. }
  169. // 表单界面回调
  170. const formSuccessful = () => {
  171. tableRef.value.refresh()
  172. refreshStoreDict()
  173. }
  174. // 刷新store中的字典
  175. const refreshStoreDict = () => {
  176. nextTick(() => {
  177. bizDictApi.dictTreeAll().then((res) => {
  178. tool.data.set('DICT_TYPE_TREE_DATA', res)
  179. })
  180. })
  181. }
  182. </script>
  183. <style lang="less" scoped>
  184. .ant-form-item {
  185. margin-bottom: 0 !important;
  186. }
  187. .snowy-button-left {
  188. margin-left: 8px;
  189. }
  190. </style>