|
|
@@ -67,40 +67,51 @@
|
|
|
/>
|
|
|
<a-form v-else layout="vertical" size="middle">
|
|
|
|
|
|
- <a-alert
|
|
|
- v-if="alreadySubmitted"
|
|
|
- type="success"
|
|
|
- show-icon
|
|
|
- class="mb-4"
|
|
|
- message="当前角色已提交意见,无需重复提交"
|
|
|
- />
|
|
|
<div class="flex flex-col md:flex-row lg:flex-row w-full gap-3 py-3">
|
|
|
<div
|
|
|
v-for="{ gid, def } in displayFieldDefs"
|
|
|
:key="gid"
|
|
|
class="flex flex-col flex-1"
|
|
|
>
|
|
|
- <a-form-item :required="gid === currentUserGroupId" :label="`${def.label} — 审核意见`">
|
|
|
- <a-select
|
|
|
- :value="reviewFields[gid]?.opinion"
|
|
|
+ <div class="flex flex-row gap-3">
|
|
|
+ <a-form-item :required="gid === currentUserGroupId" :label="`${def.label} — 审核意见`">
|
|
|
+ <a-select
|
|
|
+ :value="reviewFields[gid]?.opinion"
|
|
|
+ allow-clear
|
|
|
+ placeholder="请选择审核意见"
|
|
|
+ :options="opinionSelectOptions"
|
|
|
+ @update:value="(v: number | null) => reviewFields[gid].opinion = v"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item :label="`${def.label} — 评分`">
|
|
|
+ <a-input-number
|
|
|
+ :value="reviewFields[gid]?.points"
|
|
|
+ :min="0"
|
|
|
+ :max="100"
|
|
|
+ class="w-full"
|
|
|
+ placeholder="请填写分数"
|
|
|
+ @update:value="(v: number | null) => reviewFields[gid].points = v"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ </div>
|
|
|
+ <a-form-item :label="`${def.label} — 修改意见`">
|
|
|
+ <a-textarea
|
|
|
+ :value="reviewFields[gid]?.reason"
|
|
|
+ @update:value="(v: string | null) => reviewFields[gid].reason = v"
|
|
|
allow-clear
|
|
|
- placeholder="请选择审核意见"
|
|
|
- :options="opinionSelectOptions"
|
|
|
- :disabled="alreadySubmitted || gid !== currentUserGroupId"
|
|
|
- @update:value="(v: number | null) => { if (!reviewFields[gid]) reviewFields[gid] = { opinion: null, points: null }; reviewFields[gid].opinion = v; }"
|
|
|
- />
|
|
|
- </a-form-item>
|
|
|
- <a-form-item :label="`${def.label} — 评分`">
|
|
|
- <a-input-number
|
|
|
- :value="reviewFields[gid]?.points"
|
|
|
- :min="0"
|
|
|
- :max="100"
|
|
|
- class="w-full"
|
|
|
- placeholder="请填写分数"
|
|
|
- :disabled="alreadySubmitted || gid !== currentUserGroupId"
|
|
|
- @update:value="(v: number | null) => { if (!reviewFields[gid]) reviewFields[gid] = { opinion: null, points: null }; reviewFields[gid].points = v; }"
|
|
|
+ placeholder="请输入修改意见/回退原因"
|
|
|
+ :rows="5"
|
|
|
+ :maxlength="500"
|
|
|
+ show-count
|
|
|
/>
|
|
|
</a-form-item>
|
|
|
+ <a-alert
|
|
|
+ v-if="alreadySubmitted && gid === currentUserGroupId"
|
|
|
+ type="success"
|
|
|
+ show-icon
|
|
|
+ class="mb-4"
|
|
|
+ message="当前角色已提交意见"
|
|
|
+ />
|
|
|
</div>
|
|
|
<div v-if="displayFieldDefs.length === 0" class="flex flex-col flex-1">
|
|
|
<a-form-item required :label="isNoProgressChange ? `提交意见:${reviewLevelLabel}` : `审核通过:${reviewLevelLabel}`">
|
|
|
@@ -110,7 +121,7 @@
|
|
|
placeholder="请选择审核意见"
|
|
|
:options="opinionSelectOptions"
|
|
|
:disabled="alreadySubmitted"
|
|
|
- @update:value="(v: number | null) => { if (!reviewFields[currentUserGroupId]) reviewFields[currentUserGroupId] = { opinion: null, points: null }; reviewFields[currentUserGroupId].opinion = v; }"
|
|
|
+ @update:value="(v: number | null) => reviewFields[currentUserGroupId].opinion = v"
|
|
|
/>
|
|
|
</a-form-item>
|
|
|
<a-form-item label="评分">
|
|
|
@@ -121,32 +132,26 @@
|
|
|
class="w-full"
|
|
|
placeholder="请填写分数"
|
|
|
:disabled="alreadySubmitted"
|
|
|
- @update:value="(v: number | null) => { if (!reviewFields[currentUserGroupId]) reviewFields[currentUserGroupId] = { opinion: null, points: null }; reviewFields[currentUserGroupId].points = v; }"
|
|
|
+ @update:value="(v: number | null) => reviewFields[currentUserGroupId].points = v"
|
|
|
/>
|
|
|
</a-form-item>
|
|
|
</div>
|
|
|
- <div v-if="!isNoProgressChange || reviewProgressInfo?.canReject" class="flex flex-col flex-1">
|
|
|
- <a-alert
|
|
|
- v-if="currentForm.rejectReason"
|
|
|
- type="warning"
|
|
|
- show-icon
|
|
|
- class="mb-4"
|
|
|
- :message="`历史修改意见: ${currentForm.rejectReason}`"
|
|
|
+ <div v-if="displayFieldDefs.length <= 1 && (!isNoProgressChange || reviewProgressInfo?.canReject)" class="flex flex-col flex-1">
|
|
|
+ <a-form-item required label="不通过回退:回退原因">
|
|
|
+ <a-textarea
|
|
|
+ :value="reviewFields[currentUserGroupId].reason"
|
|
|
+ @update:value="(v: string | null) => reviewFields[currentUserGroupId].reason = v"
|
|
|
+ allow-clear
|
|
|
+ placeholder="请输入回退原因"
|
|
|
+ :rows="5"
|
|
|
+ :maxlength="500"
|
|
|
+ show-count
|
|
|
/>
|
|
|
- <a-form-item required label="不通过回退:回退原因">
|
|
|
- <a-textarea
|
|
|
- v-model:value="rejectReason"
|
|
|
- allow-clear
|
|
|
- placeholder="请输入回退原因"
|
|
|
- rows="5"
|
|
|
- maxlength="500"
|
|
|
- show-count
|
|
|
- />
|
|
|
- </a-form-item>
|
|
|
- </div>
|
|
|
+ </a-form-item>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div class="flex row w-full gap-3">
|
|
|
- <template v-if="!alreadySubmitted">
|
|
|
+ <template v-if="!alreadySubmitted || isMulitRole">
|
|
|
<div class="flex flex-col flex-1">
|
|
|
<a-button
|
|
|
block
|
|
|
@@ -158,7 +163,18 @@
|
|
|
{{ isNoProgressChange ? '提交意见' : '通过审核' }}
|
|
|
</a-button>
|
|
|
</div>
|
|
|
- <div v-if="isNoProgressChange || reviewProgressInfo?.canReject" class="flex flex-col flex-1">
|
|
|
+ <div v-if="isMulitRole" class="flex flex-col flex-1">
|
|
|
+ <a-button
|
|
|
+ block
|
|
|
+ type="primary"
|
|
|
+ :loading="submitLoading"
|
|
|
+ :disabled="!canSubmitReview"
|
|
|
+ @click="saveReasions"
|
|
|
+ >
|
|
|
+ 保存意见
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ <div v-if="reviewProgressInfo?.canReject" class="flex flex-col flex-1">
|
|
|
<a-button
|
|
|
block
|
|
|
danger
|
|
|
@@ -166,7 +182,7 @@
|
|
|
:disabled="!canSubmitReview"
|
|
|
@click="submitReject"
|
|
|
>
|
|
|
- {{ isNoProgressChange ? '预回退' : '回退'}}
|
|
|
+ 回退
|
|
|
</a-button>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -235,6 +251,7 @@ const rejectReason = ref<string | null>(null);
|
|
|
interface ReviewFieldState {
|
|
|
opinion: number | null;
|
|
|
points: number | null;
|
|
|
+ reason: string|null;
|
|
|
}
|
|
|
const reviewFields = ref<Record<number, ReviewFieldState>>({});
|
|
|
|
|
|
@@ -250,6 +267,8 @@ const displayFieldDefs = computed(() => {
|
|
|
.filter((item): item is { gid: number; def: GroupFieldDef } => !!item.def);
|
|
|
});
|
|
|
|
|
|
+const isMulitRole = computed(() => displayFieldDefs.value.length > 1);
|
|
|
+
|
|
|
const opinionSelectOptions = [
|
|
|
{ label: '请选择', value: 0 },
|
|
|
{ label: '优秀', value: 1 },
|
|
|
@@ -263,7 +282,7 @@ const currentProgress = computed(() => currentForm.value?.progress ?? 0);
|
|
|
const { reviewProgressInfo, canSubmitReview, reviewLevelLabel, progressHint, isNoProgressChange } = useReview(currentProgress);
|
|
|
|
|
|
const currentUserGroupId = computed(() => {
|
|
|
- const groups = currentUserGroups.value;
|
|
|
+ const groups = [...currentUserGroups.value].sort((a, b) => b.id - a.id);
|
|
|
return groups.find((g) => GROUP_TO_REVIEW_PROGRESS[g.id])?.id ?? 0;
|
|
|
});
|
|
|
|
|
|
@@ -308,16 +327,17 @@ function applyPrefillFromDetail(f: SelfAssessmentDetail) {
|
|
|
fields[gid] = {
|
|
|
opinion: (f as any)[def.opinionField] ?? null,
|
|
|
points: (f as any)[def.pointsField] || null,
|
|
|
+ reason: f.reasons?.[gid] || null,
|
|
|
};
|
|
|
}
|
|
|
// fallback for non-displayGroup roles (progress-based)
|
|
|
if (displayFieldDefs.value.length === 0) {
|
|
|
const gid = currentUserGroupId.value;
|
|
|
const t = reviewProgressInfo.value?.target;
|
|
|
- if (t === 2) fields[gid] = { opinion: f.ichUnit ?? null, points: f.unitPoints || null };
|
|
|
- else if (t === 3) fields[gid] = { opinion: f.county ?? null, points: f.countyPoints || null };
|
|
|
- else if (t === 4) fields[gid] = { opinion: f.district ?? null, points: f.districtPoints || null };
|
|
|
- else if (t === 5) fields[gid] = { opinion: f.province ?? null, points: f.provincePoints || null };
|
|
|
+ if (t === 2) fields[gid] = { opinion: f.ichUnit ?? null, points: f.unitPoints || null, reason: f.rejectReason || null };
|
|
|
+ else if (t === 3) fields[gid] = { opinion: f.county ?? null, points: f.countyPoints || null, reason: f.rejectReason || null };
|
|
|
+ else if (t === 4) fields[gid] = { opinion: f.district ?? null, points: f.districtPoints || null, reason: f.rejectReason || null };
|
|
|
+ else if (t === 5) fields[gid] = { opinion: f.province ?? null, points: f.provincePoints || null, reason: f.rejectReason || null };
|
|
|
}
|
|
|
reviewFields.value = fields;
|
|
|
}
|
|
|
@@ -352,6 +372,12 @@ watch(
|
|
|
|
|
|
onMounted(() => {
|
|
|
loader.load();
|
|
|
+ setTimeout(() => {
|
|
|
+ console.log('currentUserGroups', currentUserGroups.value, 'currentUserGroupId', currentUserGroupId.value);
|
|
|
+ console.log('reviewProgressInfo', reviewProgressInfo.value, 'canSubmitReview', canSubmitReview.value);
|
|
|
+ console.log('isNoProgressChange', isNoProgressChange.value);
|
|
|
+ console.log(reviewFields.value);
|
|
|
+ }, 800);
|
|
|
});
|
|
|
|
|
|
async function goToAssessmentProtocol() {
|
|
|
@@ -377,6 +403,37 @@ async function goToAssessmentProtocol() {
|
|
|
window.open(path.href, '_blank');
|
|
|
}
|
|
|
|
|
|
+async function saveReasions() {
|
|
|
+ if (!isMulitRole.value) {
|
|
|
+ message.warning('非多角色账号');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const f = currentForm.value;
|
|
|
+ if (!f?.id) {
|
|
|
+ message.warning('缺少自查表 ID');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const reasons = {} as Record<number, string>;
|
|
|
+ for (const { gid, def } of displayFieldDefs.value) {
|
|
|
+ reasons[gid] = reviewFields.value[gid].reason || '';
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ submitLoading.value = true;
|
|
|
+ await AssessmentContentApi.reviewSelfAssessment({
|
|
|
+ id: f.id,
|
|
|
+ progress: f.progress,
|
|
|
+ reasons
|
|
|
+ });
|
|
|
+ message.success('保存成功');
|
|
|
+ } catch (e) {
|
|
|
+ Modal.error({ title: '保存失败', content: formatErr(e) });
|
|
|
+ } finally {
|
|
|
+ submitLoading.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function submitReject() {
|
|
|
const f = currentForm.value;
|
|
|
if (!f?.id) {
|
|
|
@@ -387,6 +444,23 @@ async function submitReject() {
|
|
|
message.warning('当前账号用户组无权回退');
|
|
|
return;
|
|
|
}
|
|
|
+ if (isMulitRole.value) {
|
|
|
+ let result = '';
|
|
|
+ for (const { gid, def } of displayFieldDefs.value) {
|
|
|
+ if (gid === currentUserGroupId.value) {
|
|
|
+ result = reviewFields.value[gid].reason || '';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!result) {
|
|
|
+ Modal.error({
|
|
|
+ title: '提示',
|
|
|
+ content: '未找到对应id的回退原因',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ rejectReason.value = result
|
|
|
+ }
|
|
|
const reason = (rejectReason.value ?? '').trim();
|
|
|
if (!reason) {
|
|
|
message.warning('请输入回退原因');
|