fix: repair AI learning analysis authentication

bugfix/ai-assessment-evidence-rescore
chenyuan 1 month ago
parent f4d65c510e
commit d6d91138a1

@ -217,10 +217,13 @@ export function uploadResourceFile(data) {
}
// 学情分析
export function getLearningAnalysis(params) {
let { stuNeed,stuData}=params
const { stuNeed, stuData } = params
return request({
url: import.meta.env.VITE_APP_AI_API+'learnAnalysis/getStuPersonLearnAnalysis?stuNeed='+stuNeed,
url: import.meta.env.VITE_APP_AI_API + 'learnAnalysis/getStuPersonLearnAnalysis',
method: 'POST',
data:stuData
params: { stuNeed },
data: stuData,
// AI 服务使用独立鉴权,不能携带本系统的登录令牌。
headers: { isToken: false }
})
}

@ -12,7 +12,8 @@
<h3>此处为AI根据学情数据进行的智能分析,从个人成绩和实训时长角度给出分析结果,仅供参考</h3>
</div>
<div class="content">
<div class="analysis">
<el-empty v-if="scoreLoaded && !hasScoreData" class="empty-score" description="暂无成绩数据,暂时无法进行AI学情分析" />
<div v-else class="analysis">
<template v-for="item in dialogue" :key="item.role">
<template v-for="chid in item.child" :key="chid" v-if="item.role == roleId">
<div class="analysis-item" @click="analysis(chid)">{{ chid.name }}</div>
@ -57,39 +58,62 @@ const dialogue = ref([
},
]);
const scoreList = ref([]);
const getScoreList = () => {
if (roleId.value == 4) {
indexApi.getStuModuleDetail({ userId: userStore.userInfo.userId }).then((res) => {
scoreList.value = res.data;
proxy.$cache.session.setJSON("scoreList", scoreList.value);
});
} else {
scoreApi
.getScoreList({
const scoreLoaded = ref(false);
const hasScoreData = ref(false);
const hasTeacherScoreData = (row) => {
return Number(row.completedTaskCount || 0) > 0 || moduleMap.some(({ key }) => row[`${key}Score`] !== null && row[`${key}Score`] !== undefined);
};
const getScoreList = async () => {
scoreLoaded.value = false;
scoreList.value = [];
hasScoreData.value = false;
proxy.$cache.session.remove("scoreList");
try {
if (roleId.value == 4) {
const res = await indexApi.getStuModuleDetail({ userId: userStore.userInfo.userId });
scoreList.value = Array.isArray(res?.data) ? res.data : [];
hasScoreData.value = scoreList.value.length > 0;
} else {
const res = await scoreApi.getScoreList({
index: 1,
size: 1000,
schoolId: userStore.userInfo.schoolId,
})
.then((res) => {
const transformedData = res.data.list.map((item) => ({
name: item.name,
className: item.className,
schoolId: item.schoolId,
scores: moduleMap.map(({ key, name }) => ({
moduleName: name,
score: item[`${key}Score`] || 0,
// 总成绩
totalScore: item.score || 0,
// 总排名
totalRank: item.stuRank || null,
})),
}));
proxy.$cache.session.setJSON("scoreList", transformedData);
});
const rows = Array.isArray(res?.data?.list) ? res.data.list : [];
hasScoreData.value = rows.some(hasTeacherScoreData);
scoreList.value = rows.map((item) => ({
name: item.name,
className: item.className,
schoolId: item.schoolId,
scores: moduleMap.map(({ key, name }) => ({
moduleName: name,
score: item[`${key}Score`] || 0,
// 总成绩
totalScore: item.score || 0,
// 总排名
totalRank: item.stuRank || null,
})),
}));
}
if (hasScoreData.value) {
proxy.$cache.session.setJSON("scoreList", scoreList.value);
} else {
proxy.$message.warning("暂无成绩数据,暂时无法进行AI学情分析");
}
} catch (error) {
proxy.$message.error("成绩数据加载失败,请稍后重试");
} finally {
scoreLoaded.value = true;
}
};
// 分析
const analysis = (val) => {
if (!scoreLoaded.value) {
return proxy.$message.warning("成绩数据正在加载,请稍候");
}
if (!hasScoreData.value) {
return proxy.$message.warning("暂无成绩数据,暂时无法进行AI学情分析");
}
proxy.$cache.session.setJSON("msg", val.msg);
router.push("/ai/learning-situation-dialogue");
};
@ -165,6 +189,13 @@ onMounted(() => {
background: linear-gradient(-90deg, #1160ff 0%, #1994ff 100%);
}
}
.empty-score {
height: 100%;
--el-empty-description-margin-top: 16px;
:deep(.el-empty__description p) {
color: #ffffff;
}
}
.brief-introduction {
display: flex;
justify-content: center;

@ -159,16 +159,20 @@ const gInterrupt = () => {
}
};
// 获取分析
const getAnalysis = () => {
const getAnalysis = async () => {
loading.value = true;
AI.getLearningAnalysis({ stuNeed: proxy.$cache.session.getJSON("msg"), stuData: proxy.$cache.session.getJSON("scoreList") }).then((res) => {
try {
const res = await AI.getLearningAnalysis({ stuNeed: proxy.$cache.session.getJSON("msg"), stuData: proxy.$cache.session.getJSON("scoreList") });
messages.value.push({
id: Date.now(),
role: "assistant",
content: res,
});
} catch (error) {
proxy.$message.error("AI学情分析暂时不可用,请稍后重试");
} finally {
loading.value = false;
});
}
};
// 计算高度的函数
const updateHeight = () => {

@ -0,0 +1,29 @@
const fs = require("node:fs");
const path = require("node:path");
const test = require("node:test");
const assert = require("node:assert/strict");
const root = path.resolve(__dirname, "..");
const apiSource = fs.readFileSync(path.join(root, "src/api/AI.js"), "utf8");
const analysisSource = fs.readFileSync(path.join(root, "src/views/analysis-of-students/analysis.vue"), "utf8");
const dialogueSource = fs.readFileSync(path.join(root, "src/views/analysis-of-students/dialogue.vue"), "utf8");
test("learning analysis request does not send the commerce login token", () => {
const requestBlock = apiSource.match(/export function getLearningAnalysis[\s\S]*?\n}/)?.[0] || "";
assert.match(requestBlock, /headers:\s*\{\s*isToken:\s*false\s*}/);
assert.match(requestBlock, /params:\s*\{\s*stuNeed\s*}/);
});
test("learning analysis page handles empty and failed score data", () => {
assert.match(analysisSource, /暂无成绩数据,暂时无法进行AI学情分析/);
assert.match(analysisSource, /proxy\.\$cache\.session\.remove\("scoreList"\)/);
assert.match(analysisSource, /rows\.some\(hasTeacherScoreData\)/);
assert.match(analysisSource, /completedTaskCount/);
assert.match(analysisSource, /if \(!hasScoreData\.value\)/);
assert.match(analysisSource, /finally\s*\{\s*scoreLoaded\.value = true/);
});
test("AI analysis failure always closes the loading overlay", () => {
assert.match(dialogueSource, /AI学情分析暂时不可用,请稍后重试/);
assert.match(dialogueSource, /finally\s*\{\s*loading\.value = false/);
});
Loading…
Cancel
Save