|
|
@@ -36,9 +36,20 @@
|
|
|
:current-form-check-items="(currentFormCheckItems as SelfAssessmentCheckItemAnswer[])"
|
|
|
:readonly="false"
|
|
|
/>
|
|
|
- <template v-if="isReviewer">
|
|
|
+ <template v-if="isReviewer && currentForm">
|
|
|
+
|
|
|
+ <a-image v-if="currentForm.scan" :src="currentForm.scan" class="small-preview" alt="avatar" />
|
|
|
+ <a-upload
|
|
|
+ class="flex flex-row items-center gap-2 mt-2"
|
|
|
+ list-type="picture-card"
|
|
|
+ :show-upload-list="false"
|
|
|
+ :custom-request="(options: any) => handleScanUpload(options)"
|
|
|
+ >
|
|
|
+ <UploadOutlined /> 上传
|
|
|
+ </a-upload>
|
|
|
+
|
|
|
<a-divider />
|
|
|
- <a-button type="primary" block :loading="submitLoading" @click="reviewModalVisible = true">编辑审核意见</a-button>
|
|
|
+ <a-button type="primary" block :loading="submitLoading" @click="reviewModalVisible = true">过会后编辑分数和意见</a-button>
|
|
|
</template>
|
|
|
<a-divider />
|
|
|
<a-space direction="vertical" class="w-full" size="middle">
|
|
|
@@ -62,7 +73,7 @@
|
|
|
<iframe :src="previewUrl" class="w-full h-full" style="min-height: 60vh"></iframe>
|
|
|
</a-modal>
|
|
|
<a-modal
|
|
|
- title="编辑审核意见"
|
|
|
+ title="过会后编辑分数和意见"
|
|
|
v-model:visible="reviewModalVisible"
|
|
|
:confirm-loading="reviewSubmitting"
|
|
|
ok-text="提交审核"
|
|
|
@@ -103,8 +114,9 @@
|
|
|
<script setup lang="ts">
|
|
|
import { computed, h, onMounted, ref, watch } from 'vue';
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
-import { message, Modal } from 'ant-design-vue';
|
|
|
-import { waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
+import { message, Modal, type UploadProps } from 'ant-design-vue';
|
|
|
+import { UploadOutlined } from '@ant-design/icons-vue';
|
|
|
+import { StringUtils, waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
import { RequestApiError } from '@imengyu/imengyu-utils';
|
|
|
import { ArrowLeftOutlined } from '@ant-design/icons-vue';
|
|
|
import { useAuthStore } from '@/stores/auth';
|
|
|
@@ -121,6 +133,7 @@ import { getFormErrorFieldsMessage } from '@/common/Form.ts';
|
|
|
import { LEVEL_NATIONAL, LEVEL_PROVINCE, LEVEL_DISTRICT } from '@/api/collect/AssessmentConsts.ts';
|
|
|
import { useReview } from './composeables/Review.ts';
|
|
|
import { GROUP_LABELS, GROUP_TO_REVIEW_PROGRESS } from './composeables/GroupData.ts';
|
|
|
+import CommonContent from '@/api/CommonContent.ts';
|
|
|
|
|
|
|
|
|
function formatErr(e: unknown): string {
|
|
|
@@ -382,6 +395,20 @@ const rejectTypeForGroup = computed(() => {
|
|
|
return GROUP_TO_REVIEW_PROGRESS[gid]?.rejectTarget || 0;
|
|
|
});
|
|
|
|
|
|
+async function handleScanUpload(options: Parameters<NonNullable<UploadProps['customRequest']>>[0]) {
|
|
|
+ const { file, onSuccess, onError } = options;
|
|
|
+ try {
|
|
|
+ const res = await CommonContent.uploadSmallFile(file as File, 'image', 'file');
|
|
|
+ onSuccess?.({
|
|
|
+ url: res.fullurl,
|
|
|
+ name: StringUtils.path.getFileName(res.fullurl),
|
|
|
+ });
|
|
|
+ currentForm.value!.scan = res.fullurl;
|
|
|
+ } catch (err) {
|
|
|
+ onError?.(err as Error);
|
|
|
+ message.error(err instanceof Error ? err.message : String(err));
|
|
|
+ }
|
|
|
+}
|
|
|
async function handleReviewSubmit() {
|
|
|
const cf = currentForm.value;
|
|
|
if (!cf?.id) {
|