Kaynağa Gözat

💊 按要求增加审核层级

快乐的梦鱼 1 ay önce
ebeveyn
işleme
68e9380b07

+ 15 - 0
src/api/auth/UserApi.ts

@@ -51,6 +51,20 @@ export class UserInfo extends DataModel<UserInfo> {
     this.setNameMapperCase('Camel', 'Snake');
     this._convertTable = {
       id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true },
+      adminGroup: {
+        customToClientFn: (data: any) => {
+          const adminGroup = [] as { id: number, name: string }[];
+          for (const key in data) {
+            if (data[key])
+              adminGroup.push({ 
+              id: data[key].group_id as number, 
+              name: data[key].name as string 
+            });
+          }
+          console.log(data, adminGroup);
+          return adminGroup;
+        },
+      },
     }
   }
 
@@ -61,6 +75,7 @@ export class UserInfo extends DataModel<UserInfo> {
   avatar = '';
   username = '';
   regionId = 0;
+  adminGroup = [] as { id: number, name: string }[];
   isReviewer = false;
 }
 

+ 66 - 33
src/pages/collect/assessment/evaluation-form-review.vue

@@ -23,9 +23,9 @@
               :message="progressHint"
             />
             <SelfAssessmentFormDisplay
-              :current-form="currentForm"
-              :check-item-list="checkItemList"
-              :current-form-check-items="currentFormCheckItems"
+              :current-form="(currentForm as SelfAssessmentDetail)"
+              :check-item-list="(checkItemList as CheckItemInfo[])"
+              :current-form-check-items="(currentFormCheckItems as SelfAssessmentCheckItemAnswer[])"
               :readonly="true"
             />
             <a-divider />
@@ -38,6 +38,14 @@
             </ul>
             <a-divider />
             <a-card title="审核提交" size="small">
+              <a-alert
+                v-if="!canSubmitReview"
+                type="warning"
+                show-icon
+                class="mb-4"
+                message="当前账号用户组无权在此环节审核"
+                :description="`仅项目保护单位(9)、县(区)文旅部门(5)、设区市文旅部门/省非遗中心(10)、省文化和旅游厅(11) 可提交。`"
+              />
               <a-form layout="vertical" class="max-w-xl">
                 <a-form-item :label="`审核环节:${reviewLevelLabel}`">
                   <a-select
@@ -57,13 +65,15 @@
                   />
                 </a-form-item>
                 <a-form-item label="提交后进度">
-                  <a-select
-                    v-model:value="submitProgress"
-                    :options="progressSubmitOptions"
-                  />
+                  <a-input :value="progressSubmitLabel" readonly />
                 </a-form-item>
                 <a-form-item>
-                  <a-button type="primary" :loading="submitLoading" @click="submitReview">
+                  <a-button
+                    type="primary"
+                    :loading="submitLoading"
+                    :disabled="!canSubmitReview"
+                    @click="submitReview"
+                  >
                     提交审核
                   </a-button>
                 </a-form-item>
@@ -89,6 +99,7 @@ import AssessmentContentApi, {
 } from '@/api/collect/AssessmentContent';
 import SelfAssessmentFormDisplay from './components/SelfAssessmentFormDisplay.vue';
 import { useSimpleDataLoader } from '@/composeables/useSimpleDataLoader';
+import { useAuthStore } from '@/stores/auth';
 
 function formatErr(e: unknown): string {
   if (e instanceof RequestApiError)
@@ -101,6 +112,9 @@ function formatErr(e: unknown): string {
 const router = useRouter();
 const route = useRoute();
 
+const authStore = useAuthStore();
+const currentUserGroups = computed(() => authStore.userInfo?.adminGroup || []);
+
 const queryFormId = computed(() => Number(route.query.id) || 0);
 const queryUserId = computed(() => Number(route.query.userId) || 0);
 /** 列表当前进度(与管理员列表一致) */
@@ -117,7 +131,21 @@ const annexLinks = ref<{ id: number; name: string; url: string }[]>([]);
 const submitLoading = ref(false);
 const reviewOpinion = ref<number | null>(null);
 const reviewPoints = ref<number | null>(null);
-const submitProgress = ref<number>(2);
+
+/** 用户组 → 本环节提交后的 progress */
+const GROUP_TO_REVIEW_PROGRESS: Record<number, number> = {
+  9: 2, // 项目保护单位
+  5: 3, // 县(区)文旅部门
+  10: 4, // 设区市文旅部门、省非遗中心
+  11: 5, // 省文化和旅游厅
+};
+
+const PROGRESS_SUBMIT_LABELS: Record<number, string> = {
+  2: '2 — 项目保护单位审核完成',
+  3: '3 — 县(区)文旅部门审核完成',
+  4: '4 — 设区市文旅部门、省非遗中心审核完成',
+  5: '5 — 省文化和旅游厅审核完成',
+};
 
 const opinionSelectOptions = [
   { label: '优秀', value: 1 },
@@ -127,24 +155,23 @@ const opinionSelectOptions = [
   { label: '取消资格', value: 5 },
 ];
 
-const progressSubmitOptions = [
-  { label: '2 — 项目保护单位审核完成', value: 2 },
-  { label: '3 — 县(区)文旅部门审核完成', value: 3 },
-  { label: '4 — 设区市文旅部门、省非遗中心审核完成', value: 4 },
-  { label: '5 — 省文化和旅游厅审核完成', value: 5 },
-];
+const reviewProgress = computed(
+  () => {
+    const currentUserGroup = currentUserGroups.value.find((group) => GROUP_TO_REVIEW_PROGRESS[group.id]);
+    return GROUP_TO_REVIEW_PROGRESS[currentUserGroup?.id ?? 0] ?? 0;
+  },
+);
 
-const targetProgressDefault = computed(() => {
-  const p = listProgress.value;
-  if (!Number.isFinite(p) || p < 1)
-    return 2;
-  if (p >= 5)
-    return 5;
-  return p + 1;
-});
+const canSubmitReview = computed(
+  () => reviewProgress.value >= 2 && reviewProgress.value <= 5,
+);
+
+const progressSubmitLabel = computed(
+  () => PROGRESS_SUBMIT_LABELS[reviewProgress.value] ?? '—',
+);
 
 const reviewLevelLabel = computed(() => {
-  switch (submitProgress.value) {
+  switch (reviewProgress.value) {
     case 2:
       return '项目保护单位';
     case 3:
@@ -159,11 +186,12 @@ const reviewLevelLabel = computed(() => {
 });
 
 const progressHint = computed(() => {
-  const id = queryFormId.value;
-  const uid = queryUserId.value;
   const lp = listProgress.value;
-  const lpText = Number.isFinite(lp) ? `列表进度:${lp}` : '未传列表进度参数,已按默认环节填写';
-  return `自查表 ID ${id},传承人用户 ID ${uid}。${lpText}。提交后进度将更新为 ${submitProgress.value}。`;
+  const lpText = Number.isFinite(lp) ? `列表进度:${lp}` : '未传列表进度参数';
+  const roleText = canSubmitReview.value
+    ? `当前账号审核环节:${reviewLevelLabel.value}(提交后 progress=${reviewProgress.value})`
+    : `当前用户组 ${currentUserGroups.value.map((group) => group.name).join(',')} 无对应审核环节`;
+  return `${lpText}。${roleText}。`;
 });
 
 const currentYear = new Date().getFullYear();
@@ -201,7 +229,9 @@ async function loadAnnexLinks(formId: number) {
 }
 
 function applyPrefillFromDetail(f: SelfAssessmentDetail) {
-  const t = submitProgress.value;
+  const t = reviewProgress.value;
+  if (!canSubmitReview.value)
+    return;
   if (t === 2) {
     reviewOpinion.value = f.ichUnit ?? null;
     reviewPoints.value = f.unitPoints || null;
@@ -232,15 +262,14 @@ const loader = useSimpleDataLoader(async () => {
     await loadAnnexLinks(detail.id);
   else
     annexLinks.value = [];
-  submitProgress.value = targetProgressDefault.value;
   applyPrefillFromDetail(detail);
   return detail;
 }, { immediate: false });
 
-watch(submitProgress, () => {
+watch(reviewProgress, () => {
   const f = currentForm.value;
   if (f)
-    applyPrefillFromDetail(f);
+    applyPrefillFromDetail(f as SelfAssessmentDetail);
 });
 
 watch(
@@ -260,11 +289,15 @@ async function submitReview() {
     message.warning('缺少自查表 ID');
     return;
   }
+  if (!canSubmitReview.value) {
+    message.warning('当前账号用户组无权提交审核');
+    return;
+  }
   if (reviewOpinion.value == null) {
     message.warning('请选择审核意见');
     return;
   }
-  const t = submitProgress.value;
+  const t = reviewProgress.value;
   const base = { id: f.id, progress: t };
   const points = reviewPoints.value != null && reviewPoints.value >= 0 ? reviewPoints.value : undefined;
   const op = reviewOpinion.value;

+ 1 - 0
src/stores/auth.ts

@@ -13,6 +13,7 @@ export const useAuthStore = defineStore('auth', {
     userId: 0,
     userInfo: null as null|UserInfo,
     loginType: 0,
+    
   }),
   actions: {
     async loadLoginState() {