TreatmentPlanEdit.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <script setup lang="ts">
  2. import type { UploadFile, UploadProps } from 'ant-design-vue';
  3. import type { TreatmentPlanSubmitVO } from '#/api/outcome';
  4. import { ref } from 'vue';
  5. import { InboxOutlined } from '@ant-design/icons-vue';
  6. import { message, Upload, UploadDragger } from 'ant-design-vue';
  7. import { useEditShell } from '#/adapter/shell';
  8. import { invokeMethod } from '#/adapter/vxe-table/proxy/invoke-method';
  9. import { uploadFileMethod } from '#/api/common';
  10. import { useWorkroomStore } from '#/stores';
  11. import { treatmentPlanForm } from '../treatment-plan.data';
  12. const workroomStore = useWorkroomStore();
  13. const pdfFileList = ref<UploadFile[]>([]);
  14. const pdfUrl = ref<string>();
  15. const pdfUploading = ref(false);
  16. function createUploadFile(url: string | undefined, name: string): UploadFile[] {
  17. if (!url) return [];
  18. return [
  19. {
  20. uid: '-1',
  21. name,
  22. status: 'done',
  23. url,
  24. },
  25. ];
  26. }
  27. function resetUploads() {
  28. pdfFileList.value = [];
  29. pdfUrl.value = void 0;
  30. pdfUploading.value = false;
  31. }
  32. async function uploadImmediately(file: File) {
  33. const uploadFile: UploadFile = {
  34. uid: `${Date.now()}`,
  35. name: file.name,
  36. status: 'uploading',
  37. percent: 0,
  38. };
  39. pdfFileList.value = [uploadFile];
  40. pdfUploading.value = true;
  41. try {
  42. const url = await invokeMethod(uploadFileMethod(file), { force: true });
  43. if (!url) {
  44. throw new Error('upload empty url');
  45. }
  46. pdfUrl.value = url;
  47. pdfFileList.value = [
  48. {
  49. ...uploadFile,
  50. status: 'done',
  51. url,
  52. },
  53. ];
  54. } catch {
  55. pdfUrl.value = void 0;
  56. pdfFileList.value = [
  57. {
  58. ...uploadFile,
  59. status: 'error',
  60. },
  61. ];
  62. message.error(`${file.name} 上传失败,请重试`);
  63. } finally {
  64. pdfUploading.value = false;
  65. }
  66. }
  67. const { Form, Shell } = useEditShell<TreatmentPlanSubmitVO>(treatmentPlanForm, {
  68. handleLoad(model) {
  69. resetUploads();
  70. pdfUrl.value = model.pdfUrl;
  71. pdfFileList.value = createUploadFile(model.pdfUrl, '诊疗方案.pdf');
  72. return model;
  73. },
  74. handleSubmit(values) {
  75. const workroomId = values.workroomId || workroomStore.workroomId;
  76. if (!workroomId) {
  77. message.error('请先选择工作室');
  78. throw new Error('workroom required');
  79. }
  80. if (pdfUploading.value) {
  81. message.warning('文件上传中,请稍候');
  82. throw new Error('uploading');
  83. }
  84. if (!pdfUrl.value) {
  85. message.error('请上传诊疗方案PDF文件');
  86. throw new Error('pdf required');
  87. }
  88. return {
  89. ...values,
  90. workroomId,
  91. pdfUrl: pdfUrl.value,
  92. };
  93. },
  94. onClosed: resetUploads,
  95. });
  96. const beforePdfUpload: UploadProps['beforeUpload'] = (file) => {
  97. const isPdf =
  98. file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
  99. if (!isPdf) {
  100. message.error('仅支持PDF格式文件');
  101. return Upload.LIST_IGNORE;
  102. }
  103. void uploadImmediately(file);
  104. return false;
  105. };
  106. function onPdfRemove() {
  107. pdfUrl.value = void 0;
  108. }
  109. </script>
  110. <template>
  111. <Shell>
  112. <Form />
  113. <div class="pb-4">
  114. <div class="mb-2 text-sm">
  115. <span class="text-destructive mr-1">*</span>
  116. 诊疗方案文档
  117. </div>
  118. <UploadDragger
  119. v-model:file-list="pdfFileList"
  120. :before-upload="beforePdfUpload"
  121. :max-count="1"
  122. accept=".pdf,application/pdf"
  123. @remove="onPdfRemove"
  124. >
  125. <p class="ant-upload-drag-icon">
  126. <InboxOutlined />
  127. </p>
  128. <p class="ant-upload-text">点击上传或拖拽PDF文件到此处</p>
  129. <p class="ant-upload-hint">支持PDF格式</p>
  130. </UploadDragger>
  131. </div>
  132. </Shell>
  133. </template>