Write.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <script setup lang="tsx">
  2. import { Form, FormSchema } from '@/components/Form'
  3. import { useForm } from '@/hooks/web/useForm'
  4. import { PropType, reactive, watch, ref, unref, nextTick } from 'vue'
  5. import { useValidator } from '@/hooks/web/useValidator'
  6. import { useI18n } from '@/hooks/web/useI18n'
  7. import { ElTree, ElCheckboxGroup, ElCheckbox } from 'element-plus'
  8. import { getMenuListApi } from '@/api/menu'
  9. import { filter, eachTree } from '@/utils/tree'
  10. import { findIndex } from '@/utils'
  11. const { t } = useI18n()
  12. const { required } = useValidator()
  13. const props = defineProps({
  14. currentRow: {
  15. type: Object as PropType<any>,
  16. default: () => null
  17. }
  18. })
  19. const treeRef = ref<typeof ElTree>()
  20. const formSchema = ref<FormSchema[]>([
  21. {
  22. field: 'roleName',
  23. label: t('role.roleName'),
  24. component: 'Input'
  25. },
  26. {
  27. field: 'status',
  28. label: t('menu.status'),
  29. component: 'Select',
  30. componentProps: {
  31. options: [
  32. {
  33. label: t('userDemo.disable'),
  34. value: 0
  35. },
  36. {
  37. label: t('userDemo.enable'),
  38. value: 1
  39. }
  40. ]
  41. }
  42. },
  43. {
  44. field: 'menu',
  45. label: t('role.menu'),
  46. colProps: {
  47. span: 24
  48. },
  49. formItemProps: {
  50. slots: {
  51. default: () => {
  52. return (
  53. <>
  54. <div class="flex w-full">
  55. <div class="flex-1">
  56. <ElTree
  57. ref={treeRef}
  58. show-checkbox
  59. node-key="id"
  60. highlight-current
  61. check-strictly
  62. expand-on-click-node={false}
  63. data={treeData.value}
  64. onNode-click={nodeClick}
  65. >
  66. {{
  67. default: (data) => {
  68. return <span>{data.data.meta.title}</span>
  69. }
  70. }}
  71. </ElTree>
  72. </div>
  73. <div class="flex-1">
  74. {unref(currentTreeData) && unref(currentTreeData)?.permission ? (
  75. <ElCheckboxGroup v-model={unref(currentTreeData).meta.permission}>
  76. {unref(currentTreeData)?.permission.map((v: string) => {
  77. return <ElCheckbox label={v} />
  78. })}
  79. </ElCheckboxGroup>
  80. ) : null}
  81. </div>
  82. </div>
  83. </>
  84. )
  85. }
  86. }
  87. }
  88. }
  89. ])
  90. const currentTreeData = ref()
  91. const nodeClick = (treeData: any) => {
  92. currentTreeData.value = treeData
  93. }
  94. const rules = reactive({
  95. roleName: [required()],
  96. role: [required()],
  97. status: [required()]
  98. })
  99. const { formRegister, formMethods } = useForm()
  100. const { setValues, getFormData, getElFormExpose } = formMethods
  101. const treeData = ref([])
  102. const getMenuList = async () => {
  103. const res = await getMenuListApi()
  104. if (res) {
  105. treeData.value = res.data.list
  106. if (!props.currentRow) return
  107. await nextTick()
  108. const checked: any[] = []
  109. eachTree(props.currentRow.menu, (v) => {
  110. checked.push({
  111. id: v.id,
  112. permission: v.meta?.permission || []
  113. })
  114. })
  115. eachTree(treeData.value, (v) => {
  116. const index = findIndex(checked, (item) => {
  117. return item.id === v.id
  118. })
  119. if (index > -1) {
  120. const meta = { ...(v.meta || {}) }
  121. meta.permission = checked[index].permission
  122. v.meta = meta
  123. }
  124. })
  125. for (const item of checked) {
  126. unref(treeRef)?.setChecked(item.id, true, false)
  127. }
  128. // unref(treeRef)?.setCheckedKeys(
  129. // checked.map((v) => v.id),
  130. // false
  131. // )
  132. }
  133. }
  134. getMenuList()
  135. const submit = async () => {
  136. const elForm = await getElFormExpose()
  137. const valid = await elForm?.validate().catch((err) => {
  138. console.log(err)
  139. })
  140. if (valid) {
  141. const formData = await getFormData()
  142. const checkedKeys = unref(treeRef)?.getCheckedKeys() || []
  143. const data = filter(unref(treeData), (item: any) => {
  144. return checkedKeys.includes(item.id)
  145. })
  146. formData.menu = data || []
  147. console.log(formData)
  148. return formData
  149. }
  150. }
  151. watch(
  152. () => props.currentRow,
  153. (currentRow) => {
  154. if (!currentRow) return
  155. setValues(currentRow)
  156. },
  157. {
  158. deep: true,
  159. immediate: true
  160. }
  161. )
  162. defineExpose({
  163. submit
  164. })
  165. </script>
  166. <template>
  167. <Form :rules="rules" @register="formRegister" :schema="formSchema" />
  168. </template>