ExampleDialog.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <script setup lang="tsx">
  2. import { ContentWrap } from '@/components/ContentWrap'
  3. import { Search } from '@/components/Search'
  4. import { Dialog } from '@/components/Dialog'
  5. import { useI18n } from '@/hooks/web/useI18n'
  6. import { ElButton, ElTag } from 'element-plus'
  7. import { Table } from '@/components/Table'
  8. import { getTableListApi, saveTableApi, delTableListApi } from '@/api/table'
  9. import { useTable } from '@/hooks/web/useTable'
  10. import { TableData } from '@/api/table/types'
  11. import { ref, unref, reactive } from 'vue'
  12. import Write from './components/Write.vue'
  13. import Detail from './components/Detail.vue'
  14. import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
  15. const ids = ref<string[]>([])
  16. const { tableRegister, tableState, tableMethods } = useTable({
  17. fetchDataApi: async () => {
  18. const { currentPage, pageSize } = tableState
  19. const res = await getTableListApi({
  20. pageIndex: unref(currentPage),
  21. pageSize: unref(pageSize),
  22. ...unref(searchParams)
  23. })
  24. return {
  25. list: res.data.list,
  26. total: res.data.total
  27. }
  28. },
  29. fetchDelApi: async () => {
  30. const res = await delTableListApi(unref(ids))
  31. return !!res
  32. }
  33. })
  34. const { loading, dataList, total, currentPage, pageSize } = tableState
  35. const { getList, getElTableExpose, delList } = tableMethods
  36. const searchParams = ref({})
  37. const setSearchParams = (params: any) => {
  38. searchParams.value = params
  39. getList()
  40. }
  41. const { t } = useI18n()
  42. const crudSchemas = reactive<CrudSchema[]>([
  43. {
  44. field: 'selection',
  45. search: {
  46. hidden: true
  47. },
  48. form: {
  49. hidden: true
  50. },
  51. detail: {
  52. hidden: true
  53. },
  54. table: {
  55. type: 'selection'
  56. }
  57. },
  58. {
  59. field: 'index',
  60. label: t('tableDemo.index'),
  61. type: 'index',
  62. search: {
  63. hidden: true
  64. },
  65. form: {
  66. hidden: true
  67. },
  68. detail: {
  69. hidden: true
  70. }
  71. },
  72. {
  73. field: 'title',
  74. label: t('tableDemo.title'),
  75. search: {
  76. component: 'Input'
  77. },
  78. form: {
  79. component: 'Input',
  80. colProps: {
  81. span: 24
  82. }
  83. },
  84. detail: {
  85. span: 24
  86. }
  87. },
  88. {
  89. field: 'author',
  90. label: t('tableDemo.author'),
  91. search: {
  92. hidden: true
  93. }
  94. },
  95. {
  96. field: 'display_time',
  97. label: t('tableDemo.displayTime'),
  98. search: {
  99. hidden: true
  100. },
  101. form: {
  102. component: 'DatePicker',
  103. componentProps: {
  104. type: 'datetime',
  105. valueFormat: 'YYYY-MM-DD HH:mm:ss'
  106. }
  107. }
  108. },
  109. {
  110. field: 'importance',
  111. label: t('tableDemo.importance'),
  112. search: {
  113. hidden: true
  114. },
  115. form: {
  116. component: 'Select',
  117. componentProps: {
  118. style: {
  119. width: '100%'
  120. },
  121. options: [
  122. {
  123. label: '重要',
  124. value: 3
  125. },
  126. {
  127. label: '良好',
  128. value: 2
  129. },
  130. {
  131. label: '一般',
  132. value: 1
  133. }
  134. ]
  135. }
  136. },
  137. detail: {
  138. slots: {
  139. default: (data: any) => {
  140. return (
  141. <ElTag
  142. type={
  143. data.importance === 1 ? 'success' : data.importance === 2 ? 'warning' : 'danger'
  144. }
  145. >
  146. {data.importance === 1
  147. ? t('tableDemo.important')
  148. : data.importance === 2
  149. ? t('tableDemo.good')
  150. : t('tableDemo.commonly')}
  151. </ElTag>
  152. )
  153. }
  154. }
  155. }
  156. },
  157. {
  158. field: 'pageviews',
  159. label: t('tableDemo.pageviews'),
  160. search: {
  161. hidden: true
  162. },
  163. form: {
  164. component: 'InputNumber',
  165. value: 0
  166. }
  167. },
  168. {
  169. field: 'content',
  170. label: t('exampleDemo.content'),
  171. search: {
  172. hidden: true
  173. },
  174. table: {
  175. show: false
  176. },
  177. form: {
  178. component: 'Editor',
  179. colProps: {
  180. span: 24
  181. }
  182. },
  183. detail: {
  184. span: 24,
  185. slots: {
  186. default: (data: any) => {
  187. return <div innerHTML={data.content}></div>
  188. }
  189. }
  190. }
  191. },
  192. {
  193. field: 'action',
  194. width: '260px',
  195. label: t('tableDemo.action'),
  196. search: {
  197. hidden: true
  198. },
  199. form: {
  200. hidden: true
  201. },
  202. detail: {
  203. hidden: true
  204. },
  205. table: {
  206. slots: {
  207. default: (data: any) => {
  208. return (
  209. <>
  210. <ElButton type="primary" onClick={() => action(data.row, 'edit')}>
  211. {t('exampleDemo.edit')}
  212. </ElButton>
  213. <ElButton type="success" onClick={() => action(data.row, 'detail')}>
  214. {t('exampleDemo.detail')}
  215. </ElButton>
  216. <ElButton type="danger" onClick={() => delData(data.row)}>
  217. {t('exampleDemo.del')}
  218. </ElButton>
  219. </>
  220. )
  221. }
  222. }
  223. }
  224. }
  225. ])
  226. // @ts-ignore
  227. const { allSchemas } = useCrudSchemas(crudSchemas)
  228. const dialogVisible = ref(false)
  229. const dialogTitle = ref('')
  230. const currentRow = ref<TableData | null>(null)
  231. const actionType = ref('')
  232. const AddAction = () => {
  233. dialogTitle.value = t('exampleDemo.add')
  234. currentRow.value = null
  235. dialogVisible.value = true
  236. actionType.value = ''
  237. }
  238. const delLoading = ref(false)
  239. const delData = async (row: TableData | null) => {
  240. const elTableExpose = await getElTableExpose()
  241. ids.value = row ? [row.id] : elTableExpose?.getSelectionRows().map((v: TableData) => v.id) || []
  242. delLoading.value = true
  243. await delList(unref(ids).length).finally(() => {
  244. delLoading.value = false
  245. })
  246. }
  247. const action = (row: TableData, type: string) => {
  248. dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
  249. actionType.value = type
  250. currentRow.value = row
  251. dialogVisible.value = true
  252. }
  253. const writeRef = ref<ComponentRef<typeof Write>>()
  254. const saveLoading = ref(false)
  255. const save = async () => {
  256. const write = unref(writeRef)
  257. const formData = await write?.submit()
  258. if (formData) {
  259. saveLoading.value = true
  260. const res = await saveTableApi(formData)
  261. .catch(() => {})
  262. .finally(() => {
  263. saveLoading.value = false
  264. })
  265. if (res) {
  266. dialogVisible.value = false
  267. currentPage.value = 1
  268. getList()
  269. }
  270. }
  271. }
  272. </script>
  273. <template>
  274. <ContentWrap>
  275. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  276. <div class="mb-10px">
  277. <ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
  278. <ElButton :loading="delLoading" type="danger" @click="delData(null)">
  279. {{ t('exampleDemo.del') }}
  280. </ElButton>
  281. </div>
  282. <Table
  283. v-model:pageSize="pageSize"
  284. v-model:currentPage="currentPage"
  285. :columns="allSchemas.tableColumns"
  286. :data="dataList"
  287. :loading="loading"
  288. :pagination="{
  289. total: total
  290. }"
  291. @register="tableRegister"
  292. />
  293. </ContentWrap>
  294. <Dialog v-model="dialogVisible" :title="dialogTitle">
  295. <Write
  296. v-if="actionType !== 'detail'"
  297. ref="writeRef"
  298. :form-schema="allSchemas.formSchema"
  299. :current-row="currentRow"
  300. />
  301. <Detail
  302. v-if="actionType === 'detail'"
  303. :detail-schema="allSchemas.detailSchema"
  304. :current-row="currentRow"
  305. />
  306. <template #footer>
  307. <ElButton v-if="actionType !== 'detail'" type="primary" :loading="saveLoading" @click="save">
  308. {{ t('exampleDemo.save') }}
  309. </ElButton>
  310. <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
  311. </template>
  312. </Dialog>
  313. </template>