EditConfigured.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <script setup lang="ts">
  2. import { ref } from 'vue';
  3. import { useRequest } from 'alova/client';
  4. import { getDeviceManageDetailMethod, updateDeviceManageMethod } from '@/request/api/device.api';
  5. import { branchMethod } from '@/request/api/system.api';
  6. import type { DeviceManageModel } from '@/model/device.model';
  7. import { AioFlowConfig, type FlowRequestData } from '@/pages/aio/flow-config/index';
  8. type FollowModel = Partial<DeviceManageModel>;
  9. const flowData = ref<FlowRequestData>();
  10. const loading = ref<boolean>(false);
  11. const props = defineProps<{ data: FollowModel }>();
  12. const emits = defineEmits<{
  13. submit: [data?: DeviceManageModel];
  14. }>();
  15. const model = ref<DeviceManageModel>({});
  16. // 获取详情
  17. const getDetail = async () => {
  18. try {
  19. const res = await getDeviceManageDetailMethod(props.data);
  20. if (res && JSON.stringify(res) !== '{}') {
  21. flowData.value = { ...res } as FlowRequestData;
  22. loading.value = false;
  23. model.value = { ...res };
  24. }
  25. } catch (error: any) {
  26. console.error(error, 'error');
  27. loading.value = false;
  28. }
  29. };
  30. onMounted(() => {
  31. if (props.data && props.data.id) {
  32. getDetail();
  33. }
  34. });
  35. const branch = ref<any[]>([]);
  36. useRequest(branchMethod(0, 1, 1)).onSuccess(({ data }) => {
  37. const to = (data?: any[]): any[] => {
  38. return Array.isArray(data)
  39. ? data.map((item) => {
  40. return {
  41. ...item,
  42. value: item.id,
  43. key: item.id.toString(),
  44. children: to(item.children),
  45. };
  46. })
  47. : [];
  48. };
  49. branch.value = to(data);
  50. });
  51. const { loading: submitting, send: submit } = useRequest(updateDeviceManageMethod, { immediate: false }).onSuccess(() => {
  52. emits('submit');
  53. });
  54. const flowRef = useTemplateRef<InstanceType<typeof AioFlowConfig>>('flow');
  55. const save = async () => {
  56. // 改为仅透传提交事件,由父级统一关闭弹窗,避免重复 close 导致内部状态异常
  57. try {
  58. await flowRef.value!.validate(/* 传入 false 不展示错误信息 */ true);
  59. flowData.value!.id = model.value?.id as string;
  60. submit(flowData.value as any);
  61. } catch (error: any) {
  62. console.error('保存错误', error.message);
  63. }
  64. };
  65. const reset = () => {
  66. flowRef.value?.update(flowData.value as FlowRequestData);
  67. };
  68. </script>
  69. <template>
  70. <div class="form-container">
  71. <div class="summary-container">
  72. <div class="summary-item mb-3">
  73. <span class="label" v-if="model?.warrant">设备ID:</span><span class="value">{{ model.warrant }}</span>
  74. </div>
  75. <div class="flex">
  76. <div class="summary-item mr-6" v-if="model && model.orgName">
  77. <span class="label">组织名称:</span><span class="value">{{ model.orgName }}</span>
  78. </div>
  79. <div class="summary-item" v-if="model && model.institutionName">
  80. <span class="label">机构名称:</span><span class="value">{{ model.institutionName }}</span>
  81. </div>
  82. </div>
  83. </div>
  84. <!-- 流程配置 -->
  85. <div class="content-container">
  86. <div class="title">流程配置</div>
  87. <span class="section-divider"></span>
  88. <!-- validate 方法通过后会自动更新 -->
  89. <AioFlowConfig ref="flow" :loading="loading" v-model:request-data="flowData"></AioFlowConfig>
  90. </div>
  91. <!-- 保存和重置 -->
  92. <div class="button-container">
  93. <vxe-button type="reset" content="重置" @click="reset()"></vxe-button>
  94. <vxe-button type="submit" status="primary" content="保存" @click="save()" :loading="submitting"></vxe-button>
  95. </div>
  96. </div>
  97. </template>
  98. <style scoped lang="scss">
  99. .form-container {
  100. padding: 20px;
  101. height: 100%;
  102. display: flex;
  103. flex-direction: column;
  104. }
  105. .summary-container {
  106. flex: none;
  107. margin-bottom: 20px;
  108. }
  109. .content-container {
  110. flex: 1;
  111. display: flex;
  112. flex-direction: column;
  113. min-height: 0;
  114. > div:not(.title) {
  115. flex: auto;
  116. overflow: auto;
  117. }
  118. > .title {
  119. flex: none;
  120. padding: 12px 12px 12px 0;
  121. font-size: 16px;
  122. font-weight: 800;
  123. }
  124. }
  125. .section-divider {
  126. height: 1px !important;
  127. background-color: #d9d9d9;
  128. margin-bottom: 15px !important;
  129. }
  130. .button-container {
  131. flex: none;
  132. display: flex;
  133. justify-content: center;
  134. align-items: center;
  135. gap: 16px;
  136. padding-top: 20px;
  137. }
  138. </style>