ExampleDialog.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <script setup lang="ts">
  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 { h, 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 { register, tableObject, methods } = useTable<TableData>({
  16. getListApi: getTableListApi,
  17. delListApi: delTableListApi,
  18. response: {
  19. list: 'list',
  20. total: 'total'
  21. }
  22. })
  23. const { getList, setSearchParams } = methods
  24. getList()
  25. const { t } = useI18n()
  26. const crudSchemas = reactive<CrudSchema[]>([
  27. {
  28. field: 'index',
  29. label: t('tableDemo.index'),
  30. type: 'index',
  31. form: {
  32. show: false
  33. },
  34. detail: {
  35. show: false
  36. }
  37. },
  38. {
  39. field: 'title',
  40. label: t('tableDemo.title'),
  41. search: {
  42. show: true
  43. },
  44. form: {
  45. colProps: {
  46. span: 24
  47. }
  48. },
  49. detail: {
  50. span: 24
  51. }
  52. },
  53. {
  54. field: 'author',
  55. label: t('tableDemo.author')
  56. },
  57. {
  58. field: 'display_time',
  59. label: t('tableDemo.displayTime'),
  60. form: {
  61. component: 'DatePicker',
  62. componentProps: {
  63. type: 'datetime',
  64. valueFormat: 'YYYY-MM-DD HH:mm:ss'
  65. }
  66. }
  67. },
  68. {
  69. field: 'importance',
  70. label: t('tableDemo.importance'),
  71. formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
  72. return h(
  73. ElTag,
  74. {
  75. type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
  76. },
  77. () =>
  78. cellValue === 1
  79. ? t('tableDemo.important')
  80. : cellValue === 2
  81. ? t('tableDemo.good')
  82. : t('tableDemo.commonly')
  83. )
  84. },
  85. form: {
  86. component: 'Select',
  87. componentProps: {
  88. options: [
  89. {
  90. label: '重要',
  91. value: 3
  92. },
  93. {
  94. label: '良好',
  95. value: 2
  96. },
  97. {
  98. label: '一般',
  99. value: 1
  100. }
  101. ]
  102. }
  103. }
  104. },
  105. {
  106. field: 'pageviews',
  107. label: t('tableDemo.pageviews'),
  108. form: {
  109. component: 'InputNumber',
  110. value: 0
  111. }
  112. },
  113. {
  114. field: 'content',
  115. label: t('exampleDemo.content'),
  116. table: {
  117. show: false
  118. },
  119. form: {
  120. component: 'Editor',
  121. colProps: {
  122. span: 24
  123. }
  124. },
  125. detail: {
  126. span: 24
  127. }
  128. },
  129. {
  130. field: 'action',
  131. width: '260px',
  132. label: t('tableDemo.action'),
  133. form: {
  134. show: false
  135. },
  136. detail: {
  137. show: false
  138. }
  139. }
  140. ])
  141. const { allSchemas } = useCrudSchemas(crudSchemas)
  142. const dialogVisible = ref(false)
  143. const dialogTitle = ref('')
  144. const AddAction = () => {
  145. dialogTitle.value = t('exampleDemo.add')
  146. tableObject.currentRow = null
  147. dialogVisible.value = true
  148. }
  149. const delLoading = ref(false)
  150. const delData = async (row: TableData | null, multiple: boolean) => {
  151. tableObject.currentRow = row
  152. const { delList, getSelections } = methods
  153. const selections = await getSelections()
  154. delLoading.value = true
  155. await delList(
  156. multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
  157. multiple
  158. ).finally(() => {
  159. delLoading.value = false
  160. })
  161. }
  162. const actionType = ref('')
  163. const action = (row: TableData, type: string) => {
  164. dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
  165. actionType.value = type
  166. tableObject.currentRow = row
  167. dialogVisible.value = true
  168. }
  169. const writeRef = ref<ComponentRef<typeof Write>>()
  170. const loading = ref(false)
  171. const save = async () => {
  172. const write = unref(writeRef)
  173. await write?.elFormRef?.validate(async (isValid) => {
  174. if (isValid) {
  175. loading.value = true
  176. const data = (await write?.getFormData()) as TableData
  177. const res = await saveTableApi(data)
  178. .catch(() => {})
  179. .finally(() => {
  180. loading.value = false
  181. })
  182. if (res) {
  183. dialogVisible.value = false
  184. tableObject.currentPage = 1
  185. getList()
  186. }
  187. }
  188. })
  189. }
  190. </script>
  191. <template>
  192. <ContentWrap>
  193. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  194. <div class="mb-10px">
  195. <ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
  196. <ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
  197. {{ t('exampleDemo.del') }}
  198. </ElButton>
  199. </div>
  200. <Table
  201. v-model:pageSize="tableObject.pageSize"
  202. v-model:currentPage="tableObject.currentPage"
  203. :columns="allSchemas.tableColumns"
  204. :data="tableObject.tableList"
  205. :loading="tableObject.loading"
  206. :pagination="{
  207. total: tableObject.total
  208. }"
  209. @register="register"
  210. >
  211. <template #action="{ row }">
  212. <ElButton type="primary" @click="action(row, 'edit')">
  213. {{ t('exampleDemo.edit') }}
  214. </ElButton>
  215. <ElButton type="success" @click="action(row, 'detail')">
  216. {{ t('exampleDemo.detail') }}
  217. </ElButton>
  218. <ElButton type="danger" @click="delData(row, false)">
  219. {{ t('exampleDemo.del') }}
  220. </ElButton>
  221. </template>
  222. </Table>
  223. </ContentWrap>
  224. <Dialog v-model="dialogVisible" :title="dialogTitle">
  225. <Write
  226. v-if="actionType !== 'detail'"
  227. ref="writeRef"
  228. :form-schema="allSchemas.formSchema"
  229. :current-row="tableObject.currentRow"
  230. />
  231. <Detail
  232. v-if="actionType === 'detail'"
  233. :detail-schema="allSchemas.detailSchema"
  234. :current-row="tableObject.currentRow"
  235. />
  236. <template #footer>
  237. <ElButton v-if="actionType !== 'detail'" type="primary" :loading="loading" @click="save">
  238. {{ t('exampleDemo.save') }}
  239. </ElButton>
  240. <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
  241. </template>
  242. </Dialog>
  243. </template>