PageLossReportItem.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <div class="disaster-precaution-container">
  3. <header class="disaster-precaution-container__header">
  4. <img :src="BackIcon" alt="back" class="back-icon" @click="router.back()" />
  5. <span class="disaster-precaution-container__title">{{ headerTitle }}</span>
  6. </header>
  7. <main class="disaster-precaution-container__main">
  8. <component :is="dynamicComponent" ref="dynamicComponentRef" />
  9. </main>
  10. <footer class="disaster-precaution-container__footer" v-if="operate">
  11. <el-button @click="router.back()">取消</el-button>
  12. <el-button type="primary" @click="handleSubmitNext" v-if="operate === 'create'">提交,并创建下一条</el-button>
  13. <el-button type="primary" @click="handleSubmitSingle">提交</el-button>
  14. </footer>
  15. <UploadLoading :form-loading="formLoading" v-if="formLoading" />
  16. </div>
  17. </template>
  18. <script lang="ts" setup>
  19. import { useRouter, useRoute } from 'vue-router';
  20. import { ref, computed, defineAsyncComponent } from 'vue';
  21. import { ElMessage } from 'element-plus';
  22. import UploadLoading from '@/components/UploadLoading.vue';
  23. import type { LossRecordFormData } from '@/types/disaster-control';
  24. import { createLossRecord, editLossRecord } from '@/api/disaster-control';
  25. import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
  26. import BackIcon from 'assets/svg/back.svg';
  27. const router = useRouter();
  28. const route = useRoute();
  29. const reportTaskId = Number(route.params.id);
  30. const dynamicComponentRef = ref();
  31. const operate = route.query.operation;
  32. const headerTitle = computed(() => {
  33. const fixedTitle = '损失记录';
  34. if (operate === 'create') {
  35. return `创建${fixedTitle}`;
  36. } else if (operate === 'edit') {
  37. return `编辑${fixedTitle}`;
  38. } else {
  39. return `查看${fixedTitle}`;
  40. }
  41. });
  42. const dynamicComponent = computed(() => {
  43. if (operate === 'create') {
  44. return defineAsyncComponent(() => import('./src/components/CreateLossReportItem.vue'));
  45. } else if (operate === 'edit') {
  46. return defineAsyncComponent(() => import('./src/components/EditLossReportItem.vue'));
  47. } else {
  48. return '';
  49. }
  50. });
  51. const formLoading = ref(false);
  52. const formatAttachmentList = async (file: File) => {
  53. if (!file) return file;
  54. const fileName = file.name;
  55. const res = await uploadFileApi({ bizType: UPLOAD_BIZ_TYPE.ATTACHMENT, fileName, file });
  56. return res.url;
  57. };
  58. const createLossReportFunc = async (formData: LossRecordFormData) => {
  59. const imagesListRes: string[] = await Promise.all(
  60. (formData.uploadImages || []).map((item) => formatAttachmentList(item)),
  61. );
  62. const createParam = {
  63. reportTaskId,
  64. ...formData,
  65. images: imagesListRes,
  66. };
  67. await createLossRecord(createParam);
  68. };
  69. const editLossReportFunc = async (formData: LossRecordFormData) => {
  70. const imagesListRes: string[] = await Promise.all(
  71. (formData.uploadImages || []).map((item) => formatAttachmentList(item)),
  72. );
  73. formData.images = [...(formData.images || []), ...imagesListRes];
  74. const editParam = {
  75. id: reportTaskId,
  76. ...formData,
  77. };
  78. await editLossRecord(editParam);
  79. };
  80. const handleSubmit = async () => {
  81. const validateResult = await dynamicComponentRef.value?.validateForm();
  82. if (!validateResult) return;
  83. const formData = dynamicComponentRef.value?.getFormData();
  84. formLoading.value = true;
  85. let message;
  86. try {
  87. if (operate === 'create') {
  88. await createLossReportFunc(formData);
  89. message = '创建成功';
  90. } else {
  91. await editLossReportFunc(formData);
  92. message = '编辑成功';
  93. }
  94. ElMessage.success(message);
  95. return true; // 成功时返回true
  96. } catch (error) {
  97. return false; // 失败时返回false
  98. } finally {
  99. formLoading.value = false;
  100. }
  101. };
  102. const handleSubmitSingle = async () => {
  103. const success = await handleSubmit();
  104. if (!success) return;
  105. router.back();
  106. };
  107. const handleSubmitNext = async () => {
  108. const success = await handleSubmit();
  109. if (!success) return;
  110. dynamicComponentRef.value?.initFormData();
  111. // 滚动到页面顶部 - 使用更可靠的方法
  112. const mainElement = document.querySelector('.info-container');
  113. if (!mainElement) return;
  114. mainElement.scrollTop = 0;
  115. };
  116. </script>
  117. <style lang="scss" scoped>
  118. @use '../style/disaster.scss' as *;
  119. @use './src/style/common.scss' as *;
  120. </style>