|
@@ -57,10 +57,28 @@
|
|
|
<div>智能批改</div>
|
|
<div>智能批改</div>
|
|
|
<div class="edit-box-header">
|
|
<div class="edit-box-header">
|
|
|
<el-button @click="handleCorrect" :disabled="!showCorrectBtn" @mouseover="handleCorrectTip">开始批改</el-button>
|
|
<el-button @click="handleCorrect" :disabled="!showCorrectBtn" @mouseover="handleCorrectTip">开始批改</el-button>
|
|
|
- <el-button @click="handleCorrectToPage" :disabled="!showCorrectToPageBtn" @mouseenter="handleCorrectToPageTip">查看完整批改报告</el-button>
|
|
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ v-if="showCorrectToPageBtn"
|
|
|
|
|
+ @click="handleCorrectToPage"
|
|
|
|
|
+ >
|
|
|
|
|
+ 查看过往批改记录
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="correct-rule-tip">
|
|
|
|
|
+ 提示:建议在提交前使用逐句批改,同一版本仅可批改一次。
|
|
|
</div>
|
|
</div>
|
|
|
<div class="capacity-item">
|
|
<div class="capacity-item">
|
|
|
- <div v-loading="loading" element-loading-text="智能批改中" class="remark">{{ data.overallEvaluation?.evaluation }}</div>
|
|
|
|
|
|
|
+ <div v-loading="loading" element-loading-text="智能批改中" class="remark">
|
|
|
|
|
+ <div v-if="data.overallEvaluation?.evaluation">
|
|
|
|
|
+ {{ data.overallEvaluation.evaluation }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-else class="remark-empty">
|
|
|
|
|
+ <el-empty
|
|
|
|
|
+ :image-size="96"
|
|
|
|
|
+ description="暂无批改结果,点击“开始批改”后在此查看智能批改内容。"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</div>
|
|
</div>
|
|
@@ -80,7 +98,6 @@ import ViewsWordEditor from "@/components/ViewsWordEditor/ViewsWordEditor.vue";
|
|
|
import {useRoute} from "vue-router";
|
|
import {useRoute} from "vue-router";
|
|
|
import {ElMessage} from "element-plus";
|
|
import {ElMessage} from "element-plus";
|
|
|
import router from "@/router";
|
|
import router from "@/router";
|
|
|
-import * as path from "node:path";
|
|
|
|
|
import emitter from "@/utils/emitter";
|
|
import emitter from "@/utils/emitter";
|
|
|
|
|
|
|
|
|
|
|
|
@@ -101,8 +118,11 @@ import emitter from "@/utils/emitter";
|
|
|
let loading = ref(false)
|
|
let loading = ref(false)
|
|
|
let open= ref(false)
|
|
let open= ref(false)
|
|
|
let showCorrectBtn = ref(false)
|
|
let showCorrectBtn = ref(false)
|
|
|
|
|
+ let canCorrectByVersion = ref(false)
|
|
|
let showCorrectToPageBtn = ref(false)
|
|
let showCorrectToPageBtn = ref(false)
|
|
|
let hasStagedContent = ref(false) // 用于跟踪是否已暂存内容
|
|
let hasStagedContent = ref(false) // 用于跟踪是否已暂存内容
|
|
|
|
|
+ let hasUnsavedChanges = ref(false) // 用于跟踪是否有未保存改动
|
|
|
|
|
+ let manualCorrectRequested = ref(false) // 仅允许手动点击后触发批改
|
|
|
|
|
|
|
|
// 获得路由中的assignmentId
|
|
// 获得路由中的assignmentId
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
@@ -149,60 +169,79 @@ import emitter from "@/utils/emitter";
|
|
|
// 如果没有传入version,使用props中的version
|
|
// 如果没有传入version,使用props中的version
|
|
|
const versionToUse = version !== undefined ? version : props.engagement.version;
|
|
const versionToUse = version !== undefined ? version : props.engagement.version;
|
|
|
|
|
|
|
|
- apis.getOverall(props.engagement.assignmentId, store.user.id, versionToUse)
|
|
|
|
|
|
|
+ return apis.getOverall(props.engagement.assignmentId, store.user.id, versionToUse)
|
|
|
.then(res => {
|
|
.then(res => {
|
|
|
if (res.data.data) {
|
|
if (res.data.data) {
|
|
|
data.overallEvaluation = res.data.data;
|
|
data.overallEvaluation = res.data.data;
|
|
|
console.log('成功获取评语:', data.overallEvaluation);
|
|
console.log('成功获取评语:', data.overallEvaluation);
|
|
|
}
|
|
}
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
|
|
+ return Boolean(res.data.data?.evaluation)
|
|
|
})
|
|
})
|
|
|
.catch(err => {
|
|
.catch(err => {
|
|
|
ElMessage.error("获取智能批改结果异常")
|
|
ElMessage.error("获取智能批改结果异常")
|
|
|
console.log(err)
|
|
console.log(err)
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
|
|
+ return false
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const updateCorrectButtonState = () => {
|
|
|
|
|
+ showCorrectBtn.value = canCorrectByVersion.value && !hasUnsavedChanges.value
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const isEvaluationTaskAccepted = (payload: any) => {
|
|
|
|
|
+ return payload?.code === 200
|
|
|
|
|
+ || payload?.status === 'accepted'
|
|
|
|
|
+ || payload?.data?.status === 'accepted'
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const pollLatestEvaluationResult = (attempt = 0) => {
|
|
|
|
|
+ const maxAttempts = 20
|
|
|
|
|
+ const intervalMs = 1500
|
|
|
|
|
+
|
|
|
|
|
+ if (attempt >= maxAttempts) {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ ElMessage.warning("批改任务已提交,结果仍在生成中,请稍后查看")
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
|
|
|
|
|
+ .then(async (versionRes: any) => {
|
|
|
|
|
+ const versionList = versionRes?.data?.data || []
|
|
|
|
|
+ if (!versionList.length) {
|
|
|
|
|
+ setTimeout(() => pollLatestEvaluationResult(attempt + 1), intervalMs)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const latestVersion = versionList[0].version
|
|
|
|
|
+ showCorrectToPageBtn.value = true
|
|
|
|
|
+ const hasEvaluation = await getEvaluation(latestVersion)
|
|
|
|
|
+ if (hasEvaluation) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setTimeout(() => pollLatestEvaluationResult(attempt + 1), intervalMs)
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err: any) => {
|
|
|
|
|
+ console.error('轮询批改结果失败:', err)
|
|
|
|
|
+ setTimeout(() => pollLatestEvaluationResult(attempt + 1), intervalMs)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const toEvaluation = () => {
|
|
const toEvaluation = () => {
|
|
|
|
|
+ if (!manualCorrectRequested.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ manualCorrectRequested.value = false
|
|
|
|
|
+
|
|
|
apis.overAllEvaluation(props.engagement.assignmentId, store.user.id)
|
|
apis.overAllEvaluation(props.engagement.assignmentId, store.user.id)
|
|
|
.then(res => {
|
|
.then(res => {
|
|
|
- if(res.data.code === 200){
|
|
|
|
|
- console.log('批改请求成功,等待后端处理完成...');
|
|
|
|
|
-
|
|
|
|
|
- // 延迟获取评语,确保后端已经保存,并获取最新版本号
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- // 先获取最新的版本列表
|
|
|
|
|
- apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
|
|
|
|
|
- .then(versionRes => {
|
|
|
|
|
- if (versionRes.data.data && versionRes.data.data.length > 0) {
|
|
|
|
|
- // 获取最新版本号(列表第一个就是最新的)
|
|
|
|
|
- const latestVersion = versionRes.data.data[0].version;
|
|
|
|
|
- console.log('获取到最新版本号:', latestVersion);
|
|
|
|
|
-
|
|
|
|
|
- // 使用最新版本号获取评语
|
|
|
|
|
- getEvaluation(latestVersion);
|
|
|
|
|
-
|
|
|
|
|
- // 允许查看详细报告
|
|
|
|
|
- showCorrectToPageBtn.value = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 如果获取不到版本列表,尝试使用当前版本+1
|
|
|
|
|
- console.log('未获取到版本列表,使用当前版本+1');
|
|
|
|
|
- const nextVersion = (props.engagement.version || 0) + 1;
|
|
|
|
|
- getEvaluation(nextVersion);
|
|
|
|
|
- showCorrectToPageBtn.value = true;
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- .catch(err => {
|
|
|
|
|
- console.error('获取版本列表失败:', err);
|
|
|
|
|
- // 如果获取版本列表失败,尝试使用当前版本+1
|
|
|
|
|
- const nextVersion = (props.engagement.version || 0) + 1;
|
|
|
|
|
- getEvaluation(nextVersion);
|
|
|
|
|
- showCorrectToPageBtn.value = true;
|
|
|
|
|
- });
|
|
|
|
|
- }, 1500); // 延迟1.5秒,确保后端处理完成
|
|
|
|
|
- }else{
|
|
|
|
|
- ElMessage.error("智能批改请求超时")
|
|
|
|
|
|
|
+ if (isEvaluationTaskAccepted(res.data)) {
|
|
|
|
|
+ console.log('批改任务已提交,开始轮询结果...')
|
|
|
|
|
+ pollLatestEvaluationResult()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.data?.message || "智能批改请求失败")
|
|
|
loading.value = false;
|
|
loading.value = false;
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -225,8 +264,11 @@ import emitter from "@/utils/emitter";
|
|
|
|
|
|
|
|
// 请求批改
|
|
// 请求批改
|
|
|
const handleCorrect = () => {
|
|
const handleCorrect = () => {
|
|
|
|
|
+ if (!showCorrectBtn.value) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ manualCorrectRequested.value = true
|
|
|
loading.value = true;
|
|
loading.value = true;
|
|
|
- showCorrectBtn.value = !showCorrectBtn.value
|
|
|
|
|
toEvaluation()
|
|
toEvaluation()
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -265,34 +307,109 @@ import emitter from "@/utils/emitter";
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 用于判断是否已存在历史批改记录
|
|
|
|
|
|
|
+ * 优先用 /current 接口判断当前版本是否已有批改结果:
|
|
|
|
|
+ * - 有结果 → 直接展示,禁止重复批改
|
|
|
|
|
+ * - 无结果 → 再查历史列表,决定按钮状态
|
|
|
*/
|
|
*/
|
|
|
const getEvaluationVersionList = () => {
|
|
const getEvaluationVersionList = () => {
|
|
|
- if(JSON.stringify(props.engagement) !== '{}'){
|
|
|
|
|
- // 检查是否已有暂存的作文内容
|
|
|
|
|
- const hasContent = props.engagement.content && props.engagement.content.trim() !== '';
|
|
|
|
|
- if (hasContent) {
|
|
|
|
|
- hasStagedContent.value = true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
|
|
|
|
|
|
|
+ if (JSON.stringify(props.engagement) === '{}') return
|
|
|
|
|
+
|
|
|
|
|
+ const hasContent = props.engagement.textContent && props.engagement.textContent.trim() !== ''
|
|
|
|
|
+ if (hasContent) {
|
|
|
|
|
+ hasStagedContent.value = true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ apis.getCurrentVersionEvaluation(props.engagement.assignmentId, store.user.id)
|
|
|
|
|
+ .then((currentRes: any) => {
|
|
|
|
|
+ const currentEvaluation = currentRes?.data?.data
|
|
|
|
|
+ const currentVersion = currentEvaluation?.version
|
|
|
|
|
+ const overallStatus = currentEvaluation?.overallStatus ?? 0
|
|
|
|
|
+ const sentenceStatus = currentEvaluation?.sentenceStatus ?? 0
|
|
|
|
|
+
|
|
|
|
|
+ // /current 接口返回的是“状态”,不是“批改内容”
|
|
|
|
|
+ // 只有当状态显示已完成时,才认为该版本已批改;批改内容需用 /select/overall 获取
|
|
|
|
|
+ if (overallStatus === 1 || sentenceStatus === 1) {
|
|
|
|
|
+ canCorrectByVersion.value = false
|
|
|
|
|
+ showCorrectToPageBtn.value = true
|
|
|
|
|
+
|
|
|
|
|
+ // 优先展示整体评价内容(逐句内容在独立页面展示)
|
|
|
|
|
+ if (overallStatus === 1 && typeof currentVersion === 'number') {
|
|
|
|
|
+ console.info('[EVAL][FE][Silder] current has overall, fetch overall content', {
|
|
|
|
|
+ assignmentId: props.engagement.assignmentId,
|
|
|
|
|
+ userId: store.user.id,
|
|
|
|
|
+ version: currentVersion
|
|
|
|
|
+ })
|
|
|
|
|
+ apis.getOverall(props.engagement.assignmentId, store.user.id, currentVersion)
|
|
|
|
|
+ .then((res: any) => {
|
|
|
|
|
+ if (res?.data?.code === 200) {
|
|
|
|
|
+ data.overallEvaluation = res.data.data
|
|
|
|
|
+ console.info('[EVAL][FE][Silder] overall content loaded', {
|
|
|
|
|
+ version: currentVersion,
|
|
|
|
|
+ evalLen: res.data.data?.evaluation?.length ?? -1
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ data.overallEvaluation = null
|
|
|
|
|
+ console.warn('[EVAL][FE][Silder] overall content non-200', {
|
|
|
|
|
+ version: currentVersion,
|
|
|
|
|
+ code: res?.data?.code,
|
|
|
|
|
+ msg: res?.data?.msg
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err: any) => {
|
|
|
|
|
+ console.error('获取当前版本整体评价失败:', err)
|
|
|
|
|
+ data.overallEvaluation = null
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ // 避免 loading 遮罩导致用户误以为没有内容
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ data.overallEvaluation = null
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 当前版本尚未批改,查询历史列表决定按钮可用性
|
|
|
|
|
+ apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
|
|
|
|
|
+ .then(res => {
|
|
|
|
|
+ const list = res.data.data || []
|
|
|
|
|
+ if (list.length === 0) {
|
|
|
|
|
+ canCorrectByVersion.value = hasStagedContent.value
|
|
|
|
|
+ showCorrectToPageBtn.value = false
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showCorrectToPageBtn.value = true
|
|
|
|
|
+ canCorrectByVersion.value = hasStagedContent.value
|
|
|
|
|
+ }
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(err => {
|
|
|
|
|
+ ElMessage.error("获取评价历史记录异常")
|
|
|
|
|
+ console.log(err)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(err => {
|
|
|
|
|
+ console.error('检查当前版本批改状态异常,回退到历史列表查询:', err)
|
|
|
|
|
+ apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
|
|
|
.then(res => {
|
|
.then(res => {
|
|
|
- // 从未批改过
|
|
|
|
|
- if(res.data.data.length === 0){
|
|
|
|
|
- // 修改:从未批改过时,只有当已有暂存内容时才能启用批改按钮
|
|
|
|
|
- showCorrectBtn.value = hasStagedContent.value
|
|
|
|
|
|
|
+ const list = res.data.data || []
|
|
|
|
|
+ if (list.length === 0) {
|
|
|
|
|
+ canCorrectByVersion.value = hasStagedContent.value
|
|
|
showCorrectToPageBtn.value = false
|
|
showCorrectToPageBtn.value = false
|
|
|
} else {
|
|
} else {
|
|
|
showCorrectToPageBtn.value = true
|
|
showCorrectToPageBtn.value = true
|
|
|
- showCorrectBtn.value = (res.data.data[0].version !== props.engagement.version) && hasStagedContent.value
|
|
|
|
|
|
|
+ canCorrectByVersion.value = (list[0].version !== props.engagement.version) && hasStagedContent.value
|
|
|
}
|
|
}
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
})
|
|
})
|
|
|
- .catch(err => {
|
|
|
|
|
|
|
+ .catch(err2 => {
|
|
|
ElMessage.error("获取评价历史记录异常")
|
|
ElMessage.error("获取评价历史记录异常")
|
|
|
- console.log(err)
|
|
|
|
|
|
|
+ console.log(err2)
|
|
|
})
|
|
})
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 添加节流函数
|
|
// 添加节流函数
|
|
@@ -309,15 +426,16 @@ import emitter from "@/utils/emitter";
|
|
|
|
|
|
|
|
// 使用节流包装 handleCorrectTip
|
|
// 使用节流包装 handleCorrectTip
|
|
|
const handleCorrectTip = throttle(() => {
|
|
const handleCorrectTip = throttle(() => {
|
|
|
- if(!showCorrectBtn.value) {
|
|
|
|
|
- ElMessage.info("请更新作文内容并暂存后批改");
|
|
|
|
|
|
|
+ if (!showCorrectBtn.value) {
|
|
|
|
|
+ if (hasUnsavedChanges.value) {
|
|
|
|
|
+ ElMessage.info("检测到未保存修改,请先暂存后再批改")
|
|
|
|
|
+ } else if (!canCorrectByVersion.value) {
|
|
|
|
|
+ ElMessage.info("当前版本已完成智能批改")
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.info("请更新作文内容并暂存后批改")
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }, 2000); // 2秒的节流时间
|
|
|
|
|
-
|
|
|
|
|
- const handleCorrectToPageTip = throttle(() => {
|
|
|
|
|
- if(!showCorrectToPageBtn.value)
|
|
|
|
|
- ElMessage.info("批改后查看报告")
|
|
|
|
|
- },1000);
|
|
|
|
|
|
|
+ }, 2000)
|
|
|
|
|
|
|
|
// 监听props变化
|
|
// 监听props变化
|
|
|
watch(() => props.engagement, (newEngagement, oldEngagement) => {
|
|
watch(() => props.engagement, (newEngagement, oldEngagement) => {
|
|
@@ -327,12 +445,21 @@ import emitter from "@/utils/emitter";
|
|
|
}, { immediate: true });
|
|
}, { immediate: true });
|
|
|
|
|
|
|
|
// 监听暂存成功事件
|
|
// 监听暂存成功事件
|
|
|
- emitter.on('stage-success', () => {
|
|
|
|
|
- console.log('收到暂存成功事件,启用批改按钮')
|
|
|
|
|
- // 暂存成功后,标记已有暂存内容,并启用"开始批改"按钮
|
|
|
|
|
|
|
+ const handleStageSuccess = () => {
|
|
|
|
|
+ console.log('收到暂存成功事件,刷新当前版本批改状态')
|
|
|
hasStagedContent.value = true
|
|
hasStagedContent.value = true
|
|
|
- showCorrectBtn.value = true
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ hasUnsavedChanges.value = false
|
|
|
|
|
+ // 暂存不会产生新版本:是否可再次批改取决于当前版本是否已批改
|
|
|
|
|
+ getEvaluationVersionList()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const handleModifiedStateChange = (state: boolean) => {
|
|
|
|
|
+ hasUnsavedChanges.value = Boolean(state)
|
|
|
|
|
+ updateCorrectButtonState()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ emitter.on('stage-success', handleStageSuccess)
|
|
|
|
|
+ emitter.on('is-modified', handleModifiedStateChange)
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
fetchData()
|
|
fetchData()
|
|
@@ -340,7 +467,8 @@ import emitter from "@/utils/emitter";
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
// 清理事件监听器
|
|
// 清理事件监听器
|
|
|
- emitter.off('stage-success');
|
|
|
|
|
|
|
+ emitter.off('stage-success', handleStageSuccess);
|
|
|
|
|
+ emitter.off('is-modified', handleModifiedStateChange);
|
|
|
});
|
|
});
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|