edit.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <template>
  2. <a-modal
  3. v-model:visible="visible"
  4. :title="`${role?.roleId ? $t('sys.update') : $t('sys.add')}${$t(
  5. 'role.name'
  6. )}`"
  7. width="480px"
  8. :after-close="onCancel"
  9. @ok="saveHandler"
  10. >
  11. <template #footer>
  12. <a-button class="action-bottom" size="middle" @click="visible = false">
  13. {{ $t('sys.cancel') }}
  14. </a-button>
  15. <a-button
  16. class="action-bottom"
  17. type="primary"
  18. size="middle"
  19. @click="saveHandler"
  20. >
  21. {{ $t('sys.save') }}
  22. </a-button>
  23. </template>
  24. <a-form
  25. ref="fromRef"
  26. :model="editRole"
  27. class="form"
  28. label-align="right"
  29. :label-col="{ span: 5 }"
  30. >
  31. <a-form-item
  32. name="roleName"
  33. :label="$t('role.roleNameLabel')"
  34. :rules="[{ required: true, message: $t('role.roleNameRule') }]"
  35. >
  36. <a-input
  37. v-model:value="editRole.roleName"
  38. :placeholder="$t('role.roleNameRule')"
  39. />
  40. </a-form-item>
  41. <a-form-item
  42. name="remark"
  43. :label="$t('role.remarkLabel')"
  44. :rules="[{ required: false, max: 50, message: $t('role.remarkRule') }]"
  45. >
  46. <a-textarea
  47. v-model:value.trim="editRole.remark"
  48. :resize="false"
  49. style="height: 104px; resize: none"
  50. :placeholder="$t('role.remarkRule')"
  51. />
  52. </a-form-item>
  53. <a-form-item name="roleMenus" :label="$t('role.roleMenusLabel')">
  54. <div class="menu-layer ant-input">
  55. <a-tree
  56. v-if="menuTree.length"
  57. :disable-checkbox="defaultRoles"
  58. :checked-keys="
  59. Array.from(new Set([...editRole.menuIds, ...defaultRoles]))
  60. "
  61. default-expand-all
  62. checkable
  63. :tree-data="menuTree"
  64. @update:checked-keys="(ids: any) => (editRole.menuIds = ids)"
  65. />
  66. </div>
  67. </a-form-item>
  68. </a-form>
  69. </a-modal>
  70. </template>
  71. <script lang="ts" setup>
  72. import { ref, defineProps, toRaw, onMounted } from 'vue'
  73. import { RoutesName } from '@/router'
  74. import { useRoleStore, useProject, MenuTree } from '@/store'
  75. import { ui18n } from '@/lang'
  76. import { message } from 'ant-design-vue'
  77. import { Role } from '@/api'
  78. import type { FormInstance } from 'ant-design-vue'
  79. export type EditRole = PartialPart<Role, 'roleId' | 'createTime'>
  80. defineOptions({ name: 'EditMember' })
  81. const props = defineProps<{
  82. role?: EditRole
  83. onSave: (data: EditRole) => void
  84. onCancel: () => void
  85. }>()
  86. const roleStore = useRoleStore()
  87. const projectStore = useProject()
  88. const defaultRoles = ref<Role['roleId'][]>([])
  89. const menuTree = ref<MenuTree[]>([])
  90. const editRole = ref<EditRole>(
  91. props.role
  92. ? { ...props.role }
  93. : {
  94. projectName: projectStore.current?.projectName || '',
  95. remark: '',
  96. roleName: '',
  97. menuIds: []
  98. }
  99. )
  100. const fromRef = ref<FormInstance>()
  101. const visible = ref(true)
  102. const saveHandler = async () => {
  103. if (!editRole.value.roleName.trim()) {
  104. message.error(ui18n.t('role.roleNameRule'))
  105. return
  106. }
  107. await fromRef.value?.validate()
  108. await props.onSave({
  109. ...toRaw(editRole.value),
  110. remark: editRole.value.remark || '',
  111. menuIds: Array.from(
  112. new Set([...editRole.value.menuIds, ...defaultRoles.value])
  113. )
  114. })
  115. visible.value = false
  116. }
  117. onMounted(async () => {
  118. await roleStore.fetch()
  119. defaultRoles.value = roleStore.getRoleIds([
  120. RoutesName.projectScenes,
  121. RoutesName.personal
  122. ])
  123. menuTree.value = roleStore.getMenuTree(defaultRoles.value)
  124. })
  125. </script>
  126. <style lang="scss" scoped>
  127. .footer {
  128. display: flex;
  129. justify-content: space-between;
  130. align-items: center;
  131. p {
  132. margin-bottom: 0;
  133. color: #646566;
  134. font-size: 14px;
  135. }
  136. }
  137. </style>