| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <template>
- <div class="about main-background main-background-type0">
- <div v-if="!isInMiniProgram" class="nav-placeholder" />
- <section class="main-section large">
- <div class="content">
- <div class="title left-right">
- <a-button :icon="h(ArrowLeftOutlined)" @click="router.back()">返回</a-button>
- <h2>传承协议审核</h2>
- <div class="w-20" />
- </div>
- <a-spin :spinning="loader.loading.value">
- <div
- v-if="loader.loading.value" class="h-50"
- />
- <a-result
- v-else-if="!currentAgreement"
- status="warning"
- title="无法加载传承协议"
- sub-title="请从管理员列表进入,并确认传承协议 ID 与传承人用户 ID 正确。"
- />
- <div v-else>
- <a-alert
- type="info"
- show-icon
- class="mb-4"
- :message="progressHint"
- />
- <AgreementFormDisplay
- ref="agreementFormRef"
- :currentAgreement="(currentAgreement as AgreementDetail)"
- isReviewer
- />
- <a-divider />
- <a-card title="审核提交" size="small" class="review-submit-card" :class="{ collapsed: reviewCardCollapsed }">
- <template #extra>
- <a-button
- size="small"
- type="text"
- :icon="h(reviewCardCollapsed ? UpOutlined : DownOutlined)"
- @click="reviewCardCollapsed = !reviewCardCollapsed"
- >
- {{ reviewCardCollapsed ? '展开' : '收起' }}
- </a-button>
- </template>
- <a-alert
- v-if="!canSubmitReview"
- type="warning"
- show-icon
- class="mb-4"
- message="当前账号用户组无权在此环节审核"
- />
- <a-form layout="vertical" size="middle">
- <div class="flex flex-col md:flex-row lg:flex-row w-full gap-3">
- <div class="flex flex-col flex-1">
- <a-form-item required :label="`审核通过:${reviewLevelLabel}`">
- <a-button
- block
- type="primary"
- :loading="submitLoading"
- :disabled="!canSubmitReview"
- @click="submitReview"
- >
- 通过审核
- </a-button>
- </a-form-item>
- </div>
- <div class="flex flex-col flex-1">
- <a-form-item required label="不通过回退:回退原因">
- <a-textarea
- v-model:value="rejectReason"
- allow-clear
- placeholder="请输入回退原因"
- rows="3"
- maxlength="500"
- show-count
- />
- </a-form-item>
- <a-button
- block
- danger
- :loading="rejectLoading"
- :disabled="!canSubmitReview"
- @click="submitReject"
- >
- 回退
- </a-button>
- </div>
- </div>
- </a-form>
- </a-card>
- </div>
- </a-spin>
- </div>
- </section>
- </div>
- </template>
- <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 { RequestApiError } from '@imengyu/imengyu-utils';
- import { ArrowLeftOutlined, UpOutlined, DownOutlined } from '@ant-design/icons-vue';
- import { useSimpleDataLoader } from '@/composeables/useSimpleDataLoader';
- import { useMemorizeVar } from '@/composeables/useMemorizeVar';
- import { isInMiniProgram } from '@/composeables/MiniProgramIng.ts';
- import AssessmentContentApi, { AgreementDetail } from '@/api/collect/AssessmentContent';
- import AgreementFormDisplay from './components/AgreementFormDisplay.vue';
- import { useReview } from './composeables/Review.ts';
- function formatErr(e: unknown): string {
- if (e instanceof RequestApiError)
- return e.errorMessage;
- if (e instanceof Error)
- return e.message;
- return String(e);
- }
- const router = useRouter();
- const route = useRoute();
- const agreementFormRef = ref<InstanceType<typeof AgreementFormDisplay> | null>(null);
- const queryFormId = computed(() => Number(route.query.id) || 0);
- const queryUserId = computed(() => Number(route.query.userId) || 0);
- const queryProgress = computed(() => {
- const p = Number(route.query.progress);
- return Number.isFinite(p) ? p : 0;
- });
- const currentAgreement = ref<AgreementDetail | null>(null);
- const { variable: reviewCardCollapsed } = useMemorizeVar<boolean>('argeement-sign-review-card-collapsed', false);
- const submitLoading = ref(false);
- const rejectLoading = ref(false);
- const rejectReason = ref<string | null>(null);
- const currentProgress = computed(() => currentAgreement.value?.progress ?? 0);
- const { reviewProgressInfo, canSubmitReview, reviewLevelLabel, progressHint } = useReview(currentProgress);
- const loader = useSimpleDataLoader(async () => {
- const id = queryFormId.value;
- const uid = queryUserId.value;
- if (!id || !uid) {
- currentAgreement.value = null;
- return null;
- }
- const detail = await AssessmentContentApi.getAgreementDetail(id, uid);
- currentAgreement.value = detail;
- return detail;
- }, { immediate: false });
- watch(
- () => [queryFormId.value, queryUserId.value] as const,
- () => { loader.load(); },
- );
- onMounted(() => { loader.load(); });
- async function submitReview() {
- const d = currentAgreement.value;
- if (!d?.id) {
- message.warning('缺少传承协议 ID');
- return;
- }
- if (!canSubmitReview.value) {
- message.warning('当前账号用户组无权提交审核');
- return;
- }
- try {
- await agreementFormRef.value?.validate();
- } catch {
- message.warning('请填写完整信息');
- return;
- }
- try {
- submitLoading.value = true;
- await AssessmentContentApi.reviewAgreement({
- id: d.id,
- progress: reviewProgressInfo.value.target,
- });
- message.success('审核通过');
- router.back();
- } catch (e) {
- Modal.error({ title: '审核提交失败', content: formatErr(e) });
- } finally {
- submitLoading.value = false;
- }
- }
- async function submitReject() {
- const d = currentAgreement.value;
- if (!d?.id) {
- message.warning('缺少传承协议 ID');
- return;
- }
- if (!canSubmitReview.value) {
- message.warning('当前账号用户组无权回退');
- return;
- }
- const reason = (rejectReason.value ?? '').trim();
- if (!reason) {
- message.warning('请输入回退原因');
- return;
- }
- try {
- rejectLoading.value = true;
- await AssessmentContentApi.reviewAgreement({
- id: d.id,
- progress: queryProgress.value,
- rejectType: reviewProgressInfo.value.rejectTarget,
- rejectReason: reason,
- });
- message.success('已回退');
- router.back();
- } catch (e) {
- Modal.error({ title: '回退失败', content: formatErr(e) });
- } finally {
- rejectLoading.value = false;
- }
- }
- </script>
- <style lang="scss" scoped>
- .review-submit-card {
- position: sticky;
- bottom: 0;
- z-index: 10;
- box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
- :deep(.ant-form-item) {
- margin-bottom: 0!important;
- }
- &.collapsed :deep(.ant-card-body) {
- display: none;
- }
- }
- </style>
|