EditSupplier.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <script setup lang="ts">
  2. import { VxeUI, type VxeFormProps, type VxeFormListeners } from 'vxe-pc-ui';
  3. import type { SupplierModel } from '@/model/care.model';
  4. import { useRequest } from 'alova/client';
  5. import { supplierMethod, supplierEditMethod } from '@/request/api/care.api';
  6. import { getDictionaryMethod } from '@/request/api/dictionary.api';
  7. import { branchMethod } from '@/request/api/system.api';
  8. import { notification } from 'ant-design-vue';
  9. import { TreeSelect } from 'ant-design-vue';
  10. const SHOW_ALL = TreeSelect.SHOW_ALL;
  11. type FormModel = Partial<SupplierModel>;
  12. const defaultModel = {};
  13. const props = defineProps<{ data: FormModel }>();
  14. const emits = defineEmits<{
  15. submit: [data?: SupplierModel];
  16. }>();
  17. const model = ref<Record<string, any>>({});
  18. watchEffect(() => {
  19. const data = props.data;
  20. const collaborateDepts = data?.collaborateDepts?.map((item: any) => ({value: item.deptId, label: item.deptName})) ?? [];
  21. model.value = {
  22. collaborateDepts
  23. }
  24. console.log(model.value, 'model');
  25. });
  26. const branch = ref<any[]>([]);
  27. const { loading: branchLoading } = useRequest(branchMethod).onSuccess(({ data }) => {
  28. const to = (data?: any[]): any[] => {
  29. return Array.isArray(data) ? data.map(item => {
  30. return {
  31. ...item,
  32. value: item.id,
  33. key: item.id.toString(),
  34. children: to(item.children)
  35. }
  36. }) : [];
  37. }
  38. branch.value = to(data);
  39. console.log(branch.value, 'branch');
  40. });
  41. const { loading, send: load } = useRequest((params) => supplierMethod(1, 10, params), {
  42. immediate: false,
  43. initialData: props.data ?? defaultModel,
  44. });
  45. const { loading: submitting, send: submit } = useRequest(supplierEditMethod, { immediate: false }).onSuccess(({ data }) => {
  46. emits('submit');
  47. });
  48. const projectList = ref<Array<{ label: string; value: string }>>([]);
  49. const formProps = reactive<VxeFormProps<FormModel>>({
  50. titleWidth: 100,
  51. titleAlign: 'right',
  52. titleColon: true,
  53. data: { ...props.data },
  54. items: [
  55. {
  56. field: 'name',
  57. title: '供应商',
  58. span: 24,
  59. itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  60. },
  61. {
  62. field: 'detailAddress',
  63. title: '地址',
  64. span: 24,
  65. itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  66. },
  67. {
  68. field: 'kahuna',
  69. title: '负责人',
  70. span: 24,
  71. itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  72. },
  73. {
  74. field: 'phone',
  75. title: '联系电话',
  76. span: 24,
  77. itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  78. },
  79. {
  80. field: 'collaborateDepts',
  81. title: '合作机构',
  82. span: 24,
  83. slots: {
  84. default: 'initiate',
  85. },
  86. },
  87. {
  88. field: 'onlineCPTypes',
  89. title: '居家项目',
  90. span: 24,
  91. itemRender: {
  92. name: 'VxeSelect',
  93. props: {
  94. placeholder: '请选择',
  95. options: computed(() => projectList.value),
  96. optionProps: {
  97. value: 'value',
  98. label: 'label',
  99. },
  100. multiple: true,
  101. collapseTags: true,
  102. clearable: true,
  103. },
  104. },
  105. },
  106. {
  107. field: 'offlineCPTypes',
  108. title: '线下项目',
  109. span: 24,
  110. itemRender: {
  111. name: 'VxeSelect',
  112. props: {
  113. placeholder: '请选择',
  114. options: computed(() => projectList.value),
  115. optionProps: {
  116. value: 'value',
  117. label: 'label',
  118. },
  119. multiple: true,
  120. collapseTags: true,
  121. clearable: true,
  122. },
  123. },
  124. },
  125. { align: 'center', span: 24, slots: { default: 'active' } },
  126. ],
  127. rules: {
  128. name: [{ required: true, message: '请输入供应商名称' }],
  129. phone: [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }],
  130. },
  131. });
  132. function handleSelect(value: string, node: any, extra: any) {
  133. const get = (children?: any[]) => {
  134. if (!Array.isArray(children)) return;
  135. children.forEach(child => {
  136. if (!model.value.collaborateDepts.find((item: any) => item.value === child.value)) {
  137. model.value.collaborateDepts.push(child)
  138. }
  139. get(child.children)
  140. })
  141. }
  142. get(node.children)
  143. }
  144. const formEmits: VxeFormListeners<FormModel> = {
  145. submit({ data }) {
  146. data.collaborateDepts = model.value.collaborateDepts.map((item: any) =>{
  147. return {
  148. deptId: item.value,
  149. deptName: item.label
  150. }
  151. })
  152. console.log(data, '转换之后的新增');
  153. submit(data).then(() => {
  154. notification.success({
  155. message: '操作成功',
  156. });
  157. VxeUI.modal.close('supplier-modal');
  158. });
  159. },
  160. };
  161. function cancel() {
  162. VxeUI.modal.close('supplier-modal');
  163. }
  164. onBeforeMount(async () => {
  165. if (props.data?.id) load(props.data);
  166. try {
  167. const res = await getDictionaryMethod('condition_type');
  168. if (res?.length > 0) {
  169. projectList.value = res; // 直接使用返回的数据
  170. }
  171. } catch (error) {
  172. console.error('获取项目列表失败:', error);
  173. }
  174. });
  175. </script>
  176. <template>
  177. <div class="form-container">
  178. <vxe-form v-bind="formProps" v-on="formEmits" :loading="submitting">
  179. <template #initiate>
  180. <a-tree-select
  181. style="width: 100%"
  182. :show-checked-strategy="SHOW_ALL"
  183. tree-check-strictly
  184. :tree-data="branch"
  185. tree-checkable
  186. allow-clear
  187. v-model:value="model.collaborateDepts"
  188. placeholder="请选择"
  189. @select="handleSelect"
  190. />
  191. </template>
  192. <template #active>
  193. <vxe-button type="reset" content="取消" :disabled="submitting" @click="cancel"></vxe-button>
  194. <vxe-button type="submit" status="primary" content="确定" :loading="submitting"></vxe-button>
  195. </template>
  196. </vxe-form>
  197. </div>
  198. </template>
  199. <style scoped lang="scss">
  200. .form-container {
  201. padding: 20px;
  202. }
  203. </style>