feat(aihr): align figma pages for release
This commit is contained in:
@@ -89,6 +89,50 @@
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="panel pending-review-panel">
|
||||
<div class="panel-title with-actions">
|
||||
<div class="panel-title-main">
|
||||
<el-icon><DocumentChecked /></el-icon>
|
||||
<div>
|
||||
<h2>答案待复核</h2>
|
||||
<p>员工反馈为「没解决」的答案会进入这里,复核后从待办队列移除。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="review-toolbar">
|
||||
<el-select v-model="pendingReviewStatus" size="small" @change="loadPendingReviews">
|
||||
<el-option label="待复核" value="待复核" />
|
||||
<el-option label="已复核" value="已复核" />
|
||||
</el-select>
|
||||
<el-button size="small" :loading="pendingReviewLoading" @click="loadPendingReviews">刷新</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table v-loading="pendingReviewLoading" :data="pendingReviews" size="small" class="record-table">
|
||||
<el-table-column prop="queryText" label="员工问题" min-width="260" />
|
||||
<el-table-column prop="verdict" label="反馈" width="90">
|
||||
<template #default="{ row }">
|
||||
<span class="review-verdict negative">{{ row.verdict === 'down' ? '没解决' : row.verdict }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="position" label="岗位" width="120" />
|
||||
<el-table-column prop="createTime" label="提交时间" width="170" />
|
||||
<el-table-column label="操作" width="110" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="row.reviewStatus === '待复核'"
|
||||
link
|
||||
type="danger"
|
||||
:loading="reviewingFeedbackId === row.id"
|
||||
@click="markFeedbackReviewed(row)"
|
||||
>
|
||||
标记已复核
|
||||
</el-button>
|
||||
<span v-else class="review-done">已复核</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-empty v-if="!pendingReviewLoading && !pendingReviews.length" description="暂无待复核答案" />
|
||||
</section>
|
||||
|
||||
<section class="panel record-panel">
|
||||
<div class="panel-title">
|
||||
<el-icon><Tickets /></el-icon>
|
||||
@@ -110,9 +154,18 @@
|
||||
import { DocumentChecked, Reading, Tickets, Upload } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { UploadFile } from 'element-plus';
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { reviewKnowledgeSop, searchKnowledgeSop, uploadKnowledgeDoc, type SopRecord, type SopSearchResponse } from '@/api/aihr/sop';
|
||||
import {
|
||||
listAnswerFeedback,
|
||||
reviewAnswerFeedback,
|
||||
reviewKnowledgeSop,
|
||||
searchKnowledgeSop,
|
||||
uploadKnowledgeDoc,
|
||||
type AnswerFeedbackItem,
|
||||
type SopRecord,
|
||||
type SopSearchResponse
|
||||
} from '@/api/aihr/sop';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
@@ -212,6 +265,10 @@ const uploading = ref(false);
|
||||
const uploadedRecords = ref<SopRecord[]>([]);
|
||||
const reviewSaving = ref(false);
|
||||
const reviewStatus = ref('');
|
||||
const pendingReviewStatus = ref('待复核');
|
||||
const pendingReviewLoading = ref(false);
|
||||
const reviewingFeedbackId = ref<number | null>(null);
|
||||
const pendingReviews = ref<AnswerFeedbackItem[]>([]);
|
||||
|
||||
const activeSeed = computed(() => sopSeeds[selectedCategory.value]);
|
||||
const answerText = computed(() => apiResult.value?.answer ?? activeSeed.value.answer);
|
||||
@@ -318,6 +375,32 @@ async function markReview(usable: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPendingReviews() {
|
||||
pendingReviewLoading.value = true;
|
||||
try {
|
||||
const { data } = await listAnswerFeedback(pendingReviewStatus.value);
|
||||
pendingReviews.value = data ?? [];
|
||||
} catch {
|
||||
pendingReviews.value = [];
|
||||
ElMessage.error('答案待复核列表加载失败');
|
||||
} finally {
|
||||
pendingReviewLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function markFeedbackReviewed(row: AnswerFeedbackItem) {
|
||||
reviewingFeedbackId.value = row.id;
|
||||
try {
|
||||
await reviewAnswerFeedback(row.id);
|
||||
pendingReviews.value = pendingReviews.value.filter((item) => item.id !== row.id);
|
||||
ElMessage.success('答案已标记为已复核');
|
||||
} catch {
|
||||
ElMessage.error('答案复核失败');
|
||||
} finally {
|
||||
reviewingFeedbackId.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDocSelected(uploadFile: UploadFile) {
|
||||
const raw = uploadFile.raw;
|
||||
if (!raw) return;
|
||||
@@ -359,6 +442,10 @@ async function generateTraining() {
|
||||
trainingGenerated.value = true;
|
||||
ElMessage.success('已基于引用片段生成训练题');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadPendingReviews();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -425,6 +512,48 @@ async function generateTraining() {
|
||||
}
|
||||
}
|
||||
|
||||
.panel-title.with-actions {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.panel-title-main,
|
||||
.review-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.panel-title-main {
|
||||
gap: 8px;
|
||||
|
||||
p {
|
||||
margin: 4px 0 0;
|
||||
color: #657184;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.review-toolbar {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pending-review-panel {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.review-verdict,
|
||||
.review-done {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.review-verdict.negative {
|
||||
color: #c80f1f;
|
||||
}
|
||||
|
||||
.review-done {
|
||||
color: #15844a;
|
||||
}
|
||||
|
||||
.category-list {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
|
||||
Reference in New Issue
Block a user