useVxeCrudSchemas.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import { DescriptionsSchema } from '@/types/descriptions'
  2. import { getIntDictOptions } from '@/utils/dict'
  3. import { reactive } from 'vue'
  4. import {
  5. FormItemRenderOptions,
  6. VxeColumnPropTypes,
  7. VxeFormItemProps,
  8. VxeGridPropTypes,
  9. VxeTableDefines
  10. } from 'vxe-table'
  11. import { eachTree } from 'xe-utils'
  12. import { useI18n } from '@/hooks/web/useI18n'
  13. import { VxeTableColumn } from '@/types/table'
  14. import { FormSchema } from '@/types/form'
  15. import { ComponentOptions } from '@/types/components'
  16. export type VxeCrudSchema = {
  17. // 主键ID
  18. primaryKey?: string
  19. primaryType?: VxeColumnPropTypes.Type
  20. // 是否开启操作栏插槽
  21. action?: boolean
  22. columns: VxeCrudColumns[]
  23. }
  24. type VxeCrudColumns = Omit<VxeTableColumn, 'children'> & {
  25. field: string
  26. title?: string
  27. formatter?: VxeColumnPropTypes.Formatter
  28. search?: CrudSearchParams
  29. table?: CrudTableParams
  30. form?: CrudFormParams
  31. detail?: CrudDescriptionsParams
  32. print?: CrudPrintParams
  33. children?: VxeCrudColumns[]
  34. dictType?: string
  35. }
  36. type CrudSearchParams = {
  37. // 是否显示在查询项
  38. show?: boolean
  39. } & Omit<VxeFormItemProps, 'field'>
  40. type CrudTableParams = {
  41. // 是否显示表头
  42. show?: boolean
  43. } & Omit<VxeTableDefines.ColumnOptions, 'field'>
  44. type CrudFormParams = {
  45. // 是否显示表单项
  46. show?: boolean
  47. } & Omit<FormSchema, 'field'>
  48. type CrudDescriptionsParams = {
  49. // 是否显示表单项
  50. show?: boolean
  51. } & Omit<DescriptionsSchema, 'field'>
  52. type CrudPrintParams = {
  53. // 是否显示表单项
  54. show?: boolean
  55. } & Omit<VxeTableDefines.ColumnInfo[], 'field'>
  56. export type VxeAllSchemas = {
  57. searchSchema: VxeFormItemProps[]
  58. tableSchema: VxeGridPropTypes.Columns
  59. formSchema: FormSchema[]
  60. detailSchema: DescriptionsSchema[]
  61. printSchema: VxeTableDefines.ColumnInfo[]
  62. }
  63. // 过滤所有结构
  64. export const useVxeCrudSchemas = (
  65. crudSchema: VxeCrudSchema
  66. ): {
  67. allSchemas: VxeAllSchemas
  68. } => {
  69. // 所有结构数据
  70. const allSchemas = reactive<VxeAllSchemas>({
  71. searchSchema: [],
  72. tableSchema: [],
  73. formSchema: [],
  74. detailSchema: [],
  75. printSchema: []
  76. })
  77. const searchSchema = filterSearchSchema(crudSchema)
  78. allSchemas.searchSchema = searchSchema || []
  79. const tableSchema = filterTableSchema(crudSchema)
  80. allSchemas.tableSchema = tableSchema || []
  81. const formSchema = filterFormSchema(crudSchema)
  82. allSchemas.formSchema = formSchema
  83. const detailSchema = filterDescriptionsSchema(crudSchema)
  84. allSchemas.detailSchema = detailSchema
  85. const printSchema = filterPrintSchema(crudSchema)
  86. allSchemas.printSchema = printSchema
  87. return {
  88. allSchemas
  89. }
  90. }
  91. // 过滤 Search 结构
  92. const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] => {
  93. const searchSchema: VxeFormItemProps[] = []
  94. const { t } = useI18n()
  95. eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
  96. // 判断是否显示
  97. if (schemaItem?.search?.show) {
  98. let itemRenderName = schemaItem?.search?.itemRender?.name || '$input'
  99. const options: any[] = []
  100. let itemRender: FormItemRenderOptions = {
  101. name: itemRenderName,
  102. props: { placeholder: t('common.inputText') }
  103. }
  104. if (schemaItem.dictType) {
  105. const allOptions = { label: '全部', value: '' }
  106. options.push(allOptions)
  107. getIntDictOptions(schemaItem.dictType).forEach((dict) => {
  108. options.push(dict)
  109. })
  110. itemRender.options = options
  111. if (!schemaItem.search.itemRender?.name) itemRenderName = '$select'
  112. itemRender = {
  113. name: itemRenderName,
  114. options: options,
  115. props: { placeholder: t('common.selectText') }
  116. }
  117. }
  118. const searchSchemaItem = {
  119. // 默认为 input
  120. span: 8,
  121. folding: searchSchema.length > 2,
  122. itemRender: itemRender,
  123. ...schemaItem.search,
  124. field: schemaItem.field,
  125. title: schemaItem.search?.title || schemaItem.title
  126. }
  127. // 删除不必要的字段
  128. delete searchSchemaItem.show
  129. searchSchema.push(searchSchemaItem)
  130. }
  131. })
  132. // 添加搜索按钮
  133. const buttons: VxeFormItemProps = {
  134. span: 24,
  135. align: 'center',
  136. collapseNode: searchSchema.length > 3,
  137. itemRender: {
  138. name: '$buttons',
  139. children: [
  140. { props: { type: 'submit', content: t('common.query'), status: 'primary' } },
  141. { props: { type: 'reset', content: t('common.reset') } }
  142. ]
  143. }
  144. }
  145. searchSchema.push(buttons)
  146. return searchSchema
  147. }
  148. // 过滤 table 结构
  149. const filterTableSchema = (crudSchema: VxeCrudSchema): VxeGridPropTypes.Columns => {
  150. const { t } = useI18n()
  151. const tableSchema: VxeGridPropTypes.Columns = []
  152. // 主键ID
  153. if (crudSchema.primaryKey) {
  154. const tableSchemaItem = {
  155. title: t('common.index'),
  156. field: crudSchema.primaryKey,
  157. type: crudSchema.primaryType ? crudSchema.primaryType : 'seq',
  158. width: '50px'
  159. }
  160. tableSchema.push(tableSchemaItem)
  161. }
  162. eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
  163. // 判断是否显示
  164. if (schemaItem?.table?.show !== false) {
  165. const tableSchemaItem = {
  166. ...schemaItem.table,
  167. field: schemaItem.field,
  168. title: schemaItem.table?.title || schemaItem.title
  169. }
  170. if (schemaItem?.formatter) {
  171. tableSchemaItem.formatter = schemaItem.formatter
  172. }
  173. if (schemaItem?.dictType) {
  174. tableSchemaItem.cellRender = {
  175. name: 'XDict',
  176. content: schemaItem.dictType
  177. }
  178. }
  179. // 删除不必要的字段
  180. delete tableSchemaItem.show
  181. tableSchema.push(tableSchemaItem)
  182. }
  183. })
  184. // 操作栏插槽
  185. if (crudSchema.action && crudSchema.action == true) {
  186. const tableSchemaItem = {
  187. title: t('table.action'),
  188. field: 'actionbtns',
  189. width: '240px',
  190. slots: {
  191. default: 'actionbtns_default'
  192. }
  193. }
  194. tableSchema.push(tableSchemaItem)
  195. }
  196. return tableSchema
  197. }
  198. // 过滤 form 结构
  199. const filterFormSchema = (crudSchema: VxeCrudSchema): FormSchema[] => {
  200. const formSchema: FormSchema[] = []
  201. eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
  202. // 判断是否显示
  203. if (schemaItem?.form?.show !== false) {
  204. let component = schemaItem?.form?.component || 'Input'
  205. const options: ComponentOptions[] = []
  206. let comonentProps = {}
  207. if (schemaItem.dictType) {
  208. getIntDictOptions(schemaItem.dictType).forEach((dict) => {
  209. options.push(dict)
  210. })
  211. comonentProps = {
  212. options: options
  213. }
  214. if (!(schemaItem.form && schemaItem.form.component)) component = 'Select'
  215. }
  216. const formSchemaItem = {
  217. // 默认为 input
  218. component: component,
  219. componentProps: comonentProps,
  220. ...schemaItem.form,
  221. field: schemaItem.field,
  222. label: schemaItem.form?.label || schemaItem.title
  223. }
  224. // 删除不必要的字段
  225. delete formSchemaItem.show
  226. formSchema.push(formSchemaItem)
  227. }
  228. })
  229. return formSchema
  230. }
  231. // 过滤 descriptions 结构
  232. const filterDescriptionsSchema = (crudSchema: VxeCrudSchema): DescriptionsSchema[] => {
  233. const descriptionsSchema: DescriptionsSchema[] = []
  234. eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
  235. // 判断是否显示
  236. if (schemaItem?.detail?.show !== false) {
  237. const descriptionsSchemaItem = {
  238. ...schemaItem.detail,
  239. field: schemaItem.field,
  240. label: schemaItem.detail?.label || schemaItem.title
  241. }
  242. // 删除不必要的字段
  243. delete descriptionsSchemaItem.show
  244. descriptionsSchema.push(descriptionsSchemaItem)
  245. }
  246. })
  247. return descriptionsSchema
  248. }
  249. // 过滤 打印 结构
  250. const filterPrintSchema = (crudSchema: VxeCrudSchema): any[] => {
  251. const printSchema: any[] = []
  252. eachTree(crudSchema.columns, (schemaItem: VxeCrudColumns) => {
  253. // 判断是否显示
  254. if (schemaItem?.print?.show !== false) {
  255. const printSchemaItem = {
  256. field: schemaItem.field
  257. }
  258. printSchema.push(printSchemaItem)
  259. }
  260. })
  261. return printSchema
  262. }