InstitutionEdit.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <script setup lang="ts">
  2. import { type InstitutionModel } from '@/model/system.model';
  3. import { branchMethod, editInstitutionMethod } from '@/request/api/system.api';
  4. import { useRequest } from 'alova/client';
  5. import { type VxeFormListeners, type VxeFormProps } from 'vxe-pc-ui';
  6. import { VxeUI } from 'vxe-pc-ui';
  7. type FormModel = Partial<InstitutionModel>;
  8. const props = defineProps<{ data: FormModel }>();
  9. const emits = defineEmits<{
  10. submit: [data?: InstitutionModel];
  11. }>();
  12. const model = ref<FormModel>({ ...props.data });
  13. watchEffect(() => {
  14. if (props.data) {
  15. model.value = { ...props.data };
  16. }
  17. });
  18. const branch = ref<any[]>([]);
  19. const { loading: branchLoading } = useRequest(branchMethod(0, 1, 1)).onSuccess(({ data }) => {
  20. const to = (data?: any[]): any[] => {
  21. return Array.isArray(data)
  22. ? data.map((item) => {
  23. return {
  24. ...item,
  25. value: item.id,
  26. key: item.id.toString(),
  27. children: to(item.children),
  28. };
  29. })
  30. : [];
  31. };
  32. branch.value = to(data);
  33. });
  34. const insArr = ref<any[]>([]);
  35. const insLoading = ref(false);
  36. async function getInstitution(orgId: string | number) {
  37. insLoading.value = true;
  38. const res = await branchMethod(1, 0, Number(orgId));
  39. if (res && res.length > 0) {
  40. insArr.value = res;
  41. }
  42. insLoading.value = false;
  43. }
  44. watch(
  45. () => model.value?.orgId,
  46. async (newVal, oldVal) => {
  47. // 只有当值真正改变时才执行(避免初始化时重复调用)
  48. if (newVal !== oldVal) {
  49. if (newVal) {
  50. await getInstitution(newVal);
  51. } else {
  52. // 清空组织时,清空上级机构列表和已选择的上级机构
  53. insArr.value = [];
  54. if (model.value) {
  55. model.value.parentId = undefined;
  56. }
  57. }
  58. }
  59. },
  60. { immediate: true, deep: true }
  61. );
  62. const { loading: submitting, send: submit } = useRequest(editInstitutionMethod, { immediate: false }).onSuccess(() => {
  63. emits('submit');
  64. });
  65. const formProps = reactive<VxeFormProps<FormModel>>({
  66. titleWidth: 120,
  67. titleAlign: 'right',
  68. titleColon: true,
  69. titleAsterisk: true,
  70. data: computed(() => model.value) as any,
  71. items: [
  72. {
  73. field: 'orgId',
  74. title: '组织名称',
  75. span: 24,
  76. itemRender: {
  77. name: 'VxeSelect',
  78. props: {
  79. // multiple: true,
  80. clearable: true,
  81. loading: computed(() => branchLoading.value),
  82. options: computed(() => branch.value),
  83. optionProps: {
  84. value: 'value',
  85. label: 'label',
  86. },
  87. },
  88. events: {
  89. change({ value }: any) {
  90. // 当组织选择改变时,直接调用接口获取上级机构
  91. if (value) {
  92. getInstitution(value);
  93. } else {
  94. // 清空组织时,清空上级机构列表和已选择的上级机构
  95. insArr.value = [];
  96. if (model.value) {
  97. model.value.parentId = undefined;
  98. }
  99. }
  100. },
  101. },
  102. },
  103. },
  104. { field: 'name', title: '机构名称', span: 24, itemRender: { name: 'VxeInput' } },
  105. {
  106. field: 'parentId',
  107. title: '上级机构',
  108. span: 24,
  109. itemRender: {
  110. name: 'VxeTreeSelect',
  111. props: {
  112. loading: computed(() => insLoading.value),
  113. options: computed(() => insArr.value),
  114. optionProps: { value: 'id', label: 'label' },
  115. clearable: true,
  116. },
  117. },
  118. },
  119. { field: 'action', align: 'center', span: 24, slots: { default: 'active' } },
  120. ],
  121. rules: {
  122. roleIds: [{ required: true, message: '请选择组织' }],
  123. nickName: [{ required: true, message: '请输入机构名称' }],
  124. },
  125. });
  126. const formEmits: VxeFormListeners<FormModel> = {
  127. submit({ data }) {
  128. submit(data);
  129. },
  130. };
  131. function cancel() {
  132. VxeUI.modal.close('institution-edit-modal');
  133. }
  134. </script>
  135. <template>
  136. <vxe-form v-bind="formProps" v-on="formEmits" :loading="submitting">
  137. <template #active>
  138. <vxe-button type="submit" status="primary" content="提交" :loading="submitting"></vxe-button>
  139. <vxe-button content="取消" :disabled="submitting" @click="cancel"></vxe-button>
  140. </template>
  141. </vxe-form>
  142. </template>
  143. <style scoped lang="scss"></style>