Write.vue 4.5 KB

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