EditConfigured.vue 4.1 KB

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