index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <div class="flex">
  3. <!-- ====== 字典分类 ====== -->
  4. <el-card class="w-1/2 dict" :gutter="12" shadow="always">
  5. <template #header>
  6. <div class="card-header">
  7. <span>字典分类</span>
  8. </div>
  9. </template>
  10. <XTable @register="registerType" @cell-click="cellClickEvent">
  11. <!-- 操作:新增类型 -->
  12. <template #toolbar_buttons>
  13. <XButton
  14. type="primary"
  15. preIcon="ep:zoom-in"
  16. :title="t('action.add')"
  17. v-hasPermi="['system:dict:create']"
  18. @click="handleTypeCreate()"
  19. />
  20. </template>
  21. <template #actionbtns_default="{ row }">
  22. <!-- 操作:编辑类型 -->
  23. <XTextButton
  24. preIcon="ep:edit"
  25. :title="t('action.edit')"
  26. v-hasPermi="['system:dict:update']"
  27. @click="handleTypeUpdate(row.id)"
  28. />
  29. <!-- 操作:删除类型 -->
  30. <XTextButton
  31. preIcon="ep:delete"
  32. :title="t('action.del')"
  33. v-hasPermi="['system:dict:delete']"
  34. @click="typeDeleteData(row.id)"
  35. />
  36. </template>
  37. </XTable>
  38. <!-- @星语:分页和列表重叠在一起了 -->
  39. </el-card>
  40. <!-- ====== 字典数据 ====== -->
  41. <el-card class="w-1/2 dict" style="margin-left: 10px" :gutter="12" shadow="hover">
  42. <template #header>
  43. <div class="card-header">
  44. <span>字典数据</span>
  45. </div>
  46. </template>
  47. <!-- 列表 -->
  48. <div v-if="!tableTypeSelect">
  49. <span>请从左侧选择</span>
  50. </div>
  51. <div v-if="tableTypeSelect">
  52. <!-- 列表 -->
  53. <XTable @register="registerData">
  54. <!-- 操作:新增数据 -->
  55. <template #toolbar_buttons>
  56. <XButton
  57. type="primary"
  58. preIcon="ep:zoom-in"
  59. :title="t('action.add')"
  60. v-hasPermi="['system:dict:create']"
  61. @click="handleDataCreate()"
  62. />
  63. </template>
  64. <template #actionbtns_default="{ row }">
  65. <!-- 操作:修改数据 -->
  66. <XTextButton
  67. v-hasPermi="['system:dict:update']"
  68. preIcon="ep:edit"
  69. :title="t('action.edit')"
  70. @click="handleDataUpdate(row.id)"
  71. />
  72. <!-- 操作:删除数据 -->
  73. <XTextButton
  74. v-hasPermi="['system:dict:delete']"
  75. preIcon="ep:delete"
  76. :title="t('action.del')"
  77. @click="dataDeleteData(row.id)"
  78. />
  79. </template>
  80. </XTable>
  81. </div>
  82. </el-card>
  83. <XModal id="dictModel" v-model="dialogVisible" :title="dialogTitle">
  84. <Form
  85. v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
  86. :schema="DictTypeSchemas.allSchemas.formSchema"
  87. :rules="DictTypeSchemas.dictTypeRules"
  88. ref="typeFormRef"
  89. >
  90. <template #type>
  91. <template v-if="actionType == 'typeUpdate'">
  92. <el-tag>{{ dictTypeValue }}</el-tag>
  93. </template>
  94. <template v-else><el-input v-model="dictTypeValue" /> </template>
  95. </template>
  96. </Form>
  97. <Form
  98. v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
  99. :schema="DictDataSchemas.allSchemas.formSchema"
  100. :rules="DictDataSchemas.dictDataRules"
  101. ref="dataFormRef"
  102. />
  103. <!-- 操作按钮 -->
  104. <template #footer>
  105. <XButton
  106. v-if="['typeCreate', 'typeUpdate'].includes(actionType)"
  107. type="primary"
  108. :title="t('action.save')"
  109. :loading="actionLoading"
  110. @click="submitTypeForm"
  111. />
  112. <XButton
  113. v-if="['dataCreate', 'dataUpdate'].includes(actionType)"
  114. type="primary"
  115. :title="t('action.save')"
  116. :loading="actionLoading"
  117. @click="submitDataForm"
  118. />
  119. <XButton :title="t('dialog.close')" @click="dialogVisible = false" />
  120. </template>
  121. </XModal>
  122. </div>
  123. </template>
  124. <script setup lang="ts" name="Dict">
  125. import { ref, unref, reactive } from 'vue'
  126. import { useI18n } from '@/hooks/web/useI18n'
  127. import { useMessage } from '@/hooks/web/useMessage'
  128. import { useXTable } from '@/hooks/web/useXTable'
  129. import { VxeTableEvents } from 'vxe-table'
  130. import { FormExpose } from '@/components/Form'
  131. import { ElInput, ElTag, ElCard } from 'element-plus'
  132. import * as DictTypeSchemas from './dict.type'
  133. import * as DictDataSchemas from './dict.data'
  134. import * as DictTypeApi from '@/api/system/dict/dict.type'
  135. import * as DictDataApi from '@/api/system/dict/dict.data'
  136. import { DictDataVO, DictTypeVO } from '@/api/system/dict/types'
  137. const { t } = useI18n() // 国际化
  138. const message = useMessage() // 消息弹窗
  139. const [registerType, { reload: typeGetList, deleteData: typeDeleteData }] = useXTable({
  140. allSchemas: DictTypeSchemas.allSchemas,
  141. getListApi: DictTypeApi.getDictTypePageApi,
  142. deleteApi: DictTypeApi.deleteDictTypeApi
  143. })
  144. const queryParams = reactive({
  145. dictType: null
  146. })
  147. const [registerData, { reload: dataGetList, deleteData: dataDeleteData }] = useXTable({
  148. allSchemas: DictDataSchemas.allSchemas,
  149. params: queryParams,
  150. getListApi: DictDataApi.getDictDataPageApi,
  151. deleteApi: DictDataApi.deleteDictDataApi
  152. })
  153. // ========== 字典分类列表相关 ==========
  154. const dictTypeValue = ref('')
  155. // 字典分类修改操作
  156. const handleTypeCreate = () => {
  157. dictTypeValue.value = ''
  158. setDialogTile('typeCreate')
  159. }
  160. const handleTypeUpdate = async (rowId: number) => {
  161. setDialogTile('typeUpdate')
  162. // 设置数据
  163. const res = await DictTypeApi.getDictTypeApi(rowId)
  164. dictTypeValue.value = res.type
  165. unref(typeFormRef)?.setValues(res)
  166. }
  167. // 字典数据修改操作
  168. const handleDataCreate = () => {
  169. setDialogTile('dataCreate')
  170. }
  171. const handleDataUpdate = async (rowId: number) => {
  172. setDialogTile('dataUpdate')
  173. // 设置数据
  174. const res = await DictDataApi.getDictDataApi(rowId)
  175. unref(dataFormRef)?.setValues(res)
  176. }
  177. // 字典分类点击行事件
  178. const parentType = ref('')
  179. const tableTypeSelect = ref(false)
  180. const cellClickEvent: VxeTableEvents.CellClick = async ({ row }) => {
  181. tableTypeSelect.value = true
  182. queryParams.dictType = row['type']
  183. await dataGetList()
  184. parentType.value = row['type']
  185. }
  186. // 弹出框
  187. const dialogVisible = ref(false) // 是否显示弹出层
  188. const dialogTitle = ref('edit') // 弹出层标题
  189. const actionLoading = ref(false) // 遮罩层
  190. const typeFormRef = ref<FormExpose>() // 分类表单 Ref
  191. const dataFormRef = ref<FormExpose>() // 数据表单 Ref
  192. const actionType = ref('') // 操作按钮的类型
  193. // 设置标题
  194. const setDialogTile = (type: string) => {
  195. dialogTitle.value = t('action.' + type)
  196. actionType.value = type
  197. dialogVisible.value = true
  198. }
  199. // 提交按钮
  200. const submitTypeForm = async () => {
  201. const elForm = unref(typeFormRef)?.getElFormRef()
  202. if (!elForm) return
  203. elForm.validate(async (valid) => {
  204. if (valid && dictTypeValue.value != '') {
  205. actionLoading.value = true
  206. // 提交请求
  207. try {
  208. const data = unref(typeFormRef)?.formModel as DictTypeVO
  209. if (actionType.value === 'typeCreate') {
  210. data.type = dictTypeValue.value
  211. await DictTypeApi.createDictTypeApi(data)
  212. message.success(t('common.createSuccess'))
  213. } else if (actionType.value === 'typeUpdate') {
  214. await DictTypeApi.updateDictTypeApi(data)
  215. message.success(t('common.updateSuccess'))
  216. }
  217. dialogVisible.value = false
  218. } finally {
  219. actionLoading.value = false
  220. typeGetList()
  221. }
  222. }
  223. })
  224. }
  225. const submitDataForm = async () => {
  226. const elForm = unref(dataFormRef)?.getElFormRef()
  227. if (!elForm) return
  228. elForm.validate(async (valid) => {
  229. if (valid) {
  230. actionLoading.value = true
  231. // 提交请求
  232. try {
  233. const data = unref(dataFormRef)?.formModel as DictDataVO
  234. if (actionType.value === 'dataCreate') {
  235. data.dictType = parentType.value
  236. await DictDataApi.createDictDataApi(data)
  237. message.success(t('common.createSuccess'))
  238. } else if (actionType.value === 'dataUpdate') {
  239. await DictDataApi.updateDictDataApi(data)
  240. message.success(t('common.updateSuccess'))
  241. }
  242. dialogVisible.value = false
  243. } finally {
  244. actionLoading.value = false
  245. dataGetList()
  246. }
  247. }
  248. })
  249. }
  250. </script>