| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- <template>
- <CommonRoot>
- <FlexCol padding="space.lg">
- <SimplePageContentLoader :loader="loader">
- <template v-if="loader.isFinished.value">
- <Result
- v-if="!currentForm"
- status="info"
- title="您还未填写评估表"
- >
- <Height :height="30" />
- <Button type="primary" @click="createForm">去填写评估表</Button>
- </Result>
- <FlexCol v-else gap="gap.lg">
- <EvaluationFormBlock
- :currentForm="(currentForm as SelfAssessmentDetail)"
- :formOptions="formOptions"
- :checkItemList="(checkItemList as CheckItemInfo[])"
- :currentFormCheckItems="(currentFormCheckItems as SelfAssessmentCheckItemAnswer[])"
- />
- <Divider />
- <FlexRow align="flex-end" justify="space-between">
- <H3>自评总分</H3>
- <Text fontSize="50rpx" color="#315816" fontFamily="HUNdin1451" :text="`${totalPoints}分`" />
- </FlexRow>
- <Divider />
- <FlexCol gap="gap.lg">
- <FlexCol v-for="(title, secIdx) in externalReviewSectionTitles" :key="secIdx" gap="gap.sm">
- <Text bold :text="title" />
- <Text text="评分:(待终审填写)" />
- <FlexRow wrap align="center" gap="gap.md">
- <CheckBox
- v-for="(label, i) in externalReviewScoreRow1"
- :key="`${secIdx}-r1-${i}`"
- disabled
- :model-value="false"
- :text="label"
- :check-size="28"
- />
- </FlexRow>
- <FlexRow wrap align="center" gap="gap.md">
- <CheckBox
- v-for="(label, i) in externalReviewScoreRow2"
- :key="`${secIdx}-r2-${i}`"
- disabled
- :model-value="false"
- :text="label"
- :check-size="28"
- />
- </FlexRow>
- <FlexCol align="flex-end">
- <Text color="text.second" text="填写单位(盖章)" />
- <Text color="text.second" text="年 月 日" />
- </FlexCol>
- </FlexCol>
- </FlexCol>
- <Divider />
- <H3>佐证资料上传</H3>
- <Result v-if="!currentForm?.id" status="info" title="请先保存评估表后再上传佐证资料" />
- <Uploader
- v-else
- ref="uploaderRef"
- :upload="assessmentAnnexUpload"
- :max-upload-count="9"
- :max-file-size="20 * 1024 * 1024"
- :group-type="true"
- list-type="list"
- />
- <Height :height="30" />
- <Divider />
- <Button type="primary" block :loading="submitLoading" @click="saveForm">保存评估表</Button>
- <Button :loading="submitLoading" @click="downloadForm">下载评估表PDF</Button>
- </FlexCol>
- </template>
- </SimplePageContentLoader>
- <XBarSpace />
- </FlexCol>
- </CommonRoot>
- </template>
- <script setup lang="ts">
- import { computed, ref } from 'vue';
- import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
- import { useAuthStore } from '@/store/auth';
- import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
- import { useAliOssUploadCo } from '@/common/components/upload/AliOssUploadCo';
- import { assertNotNull, formatError, StringUtils, waitTimeOut } from '@imengyu/imengyu-utils';
- import { toast, alert } from '@/components/dialog/CommonRoot';
- import AssessmentContentApi, {
- SelfAssessmentDetail,
- CheckItemInfo,
- SelfAssessmentCheckItemAnswer,
- getCheckAnnexType,
- } from '@/api/collect/AssessmentContent';
- import CommonRoot from '@/components/dialog/CommonRoot.vue';
- import Button from '@/components/basic/Button.vue';
- import Result from '@/components/feedback/Result.vue';
- import FlexCol from '@/components/layout/FlexCol.vue';
- import Height from '@/components/layout/space/Height.vue';
- import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
- import H3 from '@/components/typography/H3.vue';
- import FlexRow from '@/components/layout/FlexRow.vue';
- import Text from '@/components/basic/Text.vue';
- import XBarSpace from '@/components/layout/space/XBarSpace.vue';
- import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
- import type { RadioValueProps } from '@/components/dynamic/wrappers/RadioValue';
- import type { FieldProps } from '@/components/form/Field.vue';
- import type { SignatureFieldProps } from '@/components/form/SignatureField.vue';
- import { useImageSimpleUploadCo } from '@/common/components/upload/ImageUploadCo';
- import EvaluationFormBlock from './components/EvaluationFormBlock.vue';
- import Uploader, { type UploaderInstance } from '@/components/form/Uploader.vue';
- import { getMimeType } from '@/common/components/upload/mimes';
- import Divider from '@/components/display/Divider.vue';
- import { stringUrlToUploaderItem } from '@/components/form/Uploader';
- import CheckBox from '@/components/form/CheckBox.vue';
- /** 评估表下方展示用:各级审核意见(不接数据、禁用) */
- const externalReviewSectionTitles = [
- '1. 项目保护单位意见',
- '2. 县(区)文旅部门审核意见',
- '3. 设区市文旅部门、省非遗中心审核意见',
- ] as const;
- const externalReviewScoreRow1 = ['优秀', '合格', '不合格'] as const;
- const externalReviewScoreRow2 = ['丧失传承能力', '取消资格'] as const;
- let loaded = false;
- const { querys } = useLoadQuerys({
- id: 0,
- userId: 0,
- }, () => {
- if (loaded)
- return;
- loaded = true;
- loader.load();
- });
- const currentForm = ref<SelfAssessmentDetail | null>(null);
- const currentFormCheckItems = ref<SelfAssessmentCheckItemAnswer[]>([]);
- const authStore = useAuthStore();
- const assessmentAnnexUpload = useAliOssUploadCo('assessment/annex', async (res, item) => {
- assertNotNull(currentForm.value, 'currentForm is null');
- const mimetype = getMimeType(item.filePath);
- await AssessmentContentApi.saveAnnex({
- name: '佐证资料' + StringUtils.path.getFileName(item.filePath),
- formId: currentForm.value.id,
- url: res,
- type: getCheckAnnexType(mimetype),
- mimetype: mimetype,
- fileSize: item.size
- ? Math.max(1, Math.ceil(item.size / 1024))
- : undefined,
- });
- });
- const uploaderRef = ref<UploaderInstance | null>(null);
- const formRef = ref<IDynamicFormRef | null>(null);
- const formOptions : IDynamicFormOptions = {
- formAdditionaProps: {
- labelFlex: 4,
- inputFlex: 8,
- },
- formItems: [
- {
- type: 'flat-group',
- label: '传承人自查评估',
- name: 'selfAssessmentGroup',
- childrenColProps: { span: 24 },
- children: [
- {
- label: '传承人名称',
- name: 'inheritor',
- type: 'text',
- additionalProps: { placeholder: '请输入传承人名称' },
- },
- {
- label: '项目保护单位',
- name: 'unit',
- type: 'text',
- additionalProps: { placeholder: '请输入项目保护单位' },
- },
- {
- label: '项目名称',
- name: 'ichName',
- type: 'text',
- additionalProps: { placeholder: '请输入项目名称' },
- },
- {
- label: '联系电话',
- name: 'mobile',
- type: 'text',
- additionalProps: { placeholder: '请输入联系电话' },
- },
- {
- label: '身份证号',
- name: 'idCard',
- type: 'text',
- additionalProps: { placeholder: '请输入身份证号' },
- },
- {
- label: '级别',
- name: 'level',
- type: 'select-id',
- additionalProps: {
- placeholder: '请选择级别',
- loadData: async () => [
- { text: '国家级', value: 23 },
- { text: '省级', value: 24 },
- { text: '市级', value: 25 },
- ],
- },
- formProps: {
- showRightArrow: true,
- },
- },
- {
- label: '家庭住址',
- name: 'address',
- type: 'text',
- additionalProps: { placeholder: '请输入家庭住址' },
- },
- {
- label: '获评时间',
- name: 'awardTime',
- type: 'date',
- additionalProps: {
- placeholder: '请选择获评时间',
- shouldUpdateValueImmediately: true,
- },
- formProps: {
- showRightArrow: true,
- },
- },
- {
- label: '自评报告',
- name: 'content',
- type: 'textarea',
- additionalProps: {
- placeholder: '请填写自评报告',
- rows: 10,
- showWordLimit: true,
- maxLength: 3000,
- multiline: true,
- confirmType: "return",
- } as FieldProps,
- },
- ],
- },
- {
- type: 'insertion',
- name: 'insertCheckList',
- },
- {
- type: 'flat-group',
- label: '传承人自查评估',
- name: 'selfAssessmentGroup2',
- childrenColProps: { span: 24 },
- children: [
- {
- label: '其他相关情况(扣分内容)',
- name: 'deductContent',
- type: 'text',
- additionalProps: {
- showWordLimit: true,
- maxlength: 260,
- placeholder: '请输入其他相关情况(扣分内容)',
- } as FieldProps,
- },
- {
- label: '其他相关情况(扣分分值)',
- name: 'deductPoints',
- type: 'number',
- additionalProps: {
- placeholder: '请输入其他相关情况(扣分分值)',
- min: 0,
- max: 100,
- },
- },
- {
- label: '自我评估',
- name: 'self',
- type: 'radio-value',
- additionalProps: {
- options: [
- { text: '优秀', value: 1 },
- { text: '合格', value: 2 },
- { text: '不合格', value: 3 },
- { text: '丧失传承能力', value: 4 },
- { text: '取消资格', value: 5 },
- ],
- vertical: true,
- } as RadioValueProps,
- },
- {
- label: '传承人签名',
- name: 'sign',
- type: 'sign',
- formProps: {
- showRightArrow: true,
- },
- additionalProps: {
- upload: useImageSimpleUploadCo(),
- previewImageProps: {
- width: '400rpx',
- }
- } as SignatureFieldProps,
- }
- ],
- },
- ],
- formRules: {
- inheritor: [{ required: true, message: '请输入传承人名称' }],
- unit: [{ required: true, message: '请输入项目保护单位' }],
- ichName: [{ required: true, message: '请输入项目名称' }],
- mobile: [{ required: true, message: '请输入联系电话' }],
- idCard: [{ required: true, message: '请输入身份证号' }],
- level: [{ required: true, message: '请选择级别' }],
- address: [{ required: true, message: '请输入家庭住址' }],
- content: [{ required: true, message: '请填写自评报告' }],
- self: [{ required: true, message: '请选择自我评估' }],
- sign: [{ required: true, message: '请传承人签名' }],
- awardTime: [{ required: true, message: '请选择获评时间' }],
- },
- };
- const checkItemList = ref<CheckItemInfo[]>([]);
- let checkItemMap = new Map<number, CheckItemInfo>();
- const totalPoints = computed(() => {
- if (!currentForm.value)
- return 0;
- return currentFormCheckItems.value
- .filter((item) => {
- const checkItem = checkItemMap.get(item.id);
- return checkItem && !checkItem.isTitle;
- })
- .reduce((acc, item) => acc + (item.count * item.points), 0)
- - (currentForm.value.deductPoints ?? 0);
- });
- async function loadBasicInfo() {
- const basicInfo = await AssessmentContentApi.getInheritorBasic(authStore.userInfo?.id);
- assertNotNull(currentForm.value, 'currentForm is null');
- currentForm.value.inheritor = basicInfo.name;
- currentForm.value.unit = basicInfo.unit;
- currentForm.value.ichName = basicInfo.ichName;
- currentForm.value.mobile = basicInfo.mobile;
- currentForm.value.level = basicInfo.level;
- currentForm.value.idCard = basicInfo.idCard;
- currentForm.value.address = basicInfo.address;
- }
- async function loadCheckItems() {
- assertNotNull(currentForm.value, 'currentForm is null');
- const { top, map } = await AssessmentContentApi.getCheckItems(Number(currentForm.value.level));
- checkItemList.value = top;
- checkItemMap = map;
- currentFormCheckItems.value = currentForm.value.checkItems.concat();
- }
- async function loadAnnexList() {
- assertNotNull(currentForm.value, 'currentForm is null');
- console.log('awardTime', currentForm.value.awardTime);
- const annexList = await AssessmentContentApi.getAnnexList(currentForm.value.id);
- setTimeout(() => {
- uploaderRef.value!.setList(annexList.data.map((item) => stringUrlToUploaderItem(item.url)));
- }, 1000);
- }
- const submitLoading = ref(false);
- async function createForm() {
- const detail = new SelfAssessmentDetail();
- detail.userId = authStore.userInfo!.id;
- detail.year = new Date().getFullYear();
- detail.checkItems = [];
- currentForm.value = detail;
- await loadBasicInfo();
- await loadCheckItems();
- }
- async function saveForm() {
- const detail = currentForm.value;
- try {
- await formRef.value?.validate();
- } catch (error) {
- toast('请填写完整信息');
- return;
- }
- submitLoading.value = true;
- currentForm.value!.checkItems = currentFormCheckItems.value;
- try {
- assertNotNull(detail, 'currentForm is null');
- await AssessmentContentApi.saveSelfAssessment(detail as SelfAssessmentDetail);
- toast('保存评估表成功');
- await waitTimeOut(1000);
- await loader.reload();
- } catch (error) {
- alert({
- title: '保存评估表失败',
- content: formatError(error),
- });
- }
- submitLoading.value = false;
- }
- async function downloadForm() {
- if (!currentForm.value?.id) {
- toast('请先保存评估表后再下载PDF');
- return;
- }
- try {
- assertNotNull(currentForm.value, 'currentForm is null');
- const pdfPath = await AssessmentContentApi.downloadSelfAssessmentPdf(currentForm.value.id);
- uni.openDocument({
- filePath: pdfPath,
- fileType: 'pdf',
- showMenu: true,
- });
- } catch (error) {
- alert({
- title: '下载评估表失败',
- content: formatError(error),
- });
- }
- }
- const loader = useSimpleDataLoader(async () => {
- await waitTimeOut(1000);
-
- if (querys.value.id > 0) {
- const detail = await AssessmentContentApi.getSelfAssessmentDetail(querys.value.id, querys.value.userId);
- currentForm.value = detail;
- await loadCheckItems();
- await loadAnnexList();
- return;
- }
- const currentYear = new Date().getFullYear();
- const list = await AssessmentContentApi.getSelfAssessmentList({
- userId: authStore.userInfo?.id,
- year: currentYear,
- });
- if (list.data.length > 0) {
- const currentYearItem = list.data.find((item) => item.year === currentYear);
- const detail = await AssessmentContentApi.getSelfAssessmentDetail(
- currentYearItem?.id || list.data[0].id,
- currentYearItem?.userId || authStore.userInfo?.id
- );
- currentForm.value = detail;
- await loadAnnexList();
- await loadCheckItems();
- } else {
- currentForm.value = null;
- }
- return currentForm.value;
- }, false);
- </script>
|