|
|
@@ -101,6 +101,99 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <!-- 投票 -->
|
|
|
+ <div class="c_t45" v-if="workDetail && workDetail.type === '78' && props.showData">
|
|
|
+ <div class="c_t45_title">
|
|
|
+ <div v-if="props.showData.choiceQuestionListData[props.showData.workIndex]">{{
|
|
|
+ props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .teststitle
|
|
|
+ }}</div>
|
|
|
+ <div class="c_t45_msg">
|
|
|
+ <div>{{ lang.ssAnswerCount }} {{ props.showData.workArray.length }}<span
|
|
|
+ v-if="props.showData.unsubmittedStudents.length > 0">/{{ props.showData.workArray.length +
|
|
|
+ props.showData.unsubmittedStudents.length
|
|
|
+ }}</span></div>
|
|
|
+ <span v-if="props.showData.unsubmittedStudents.length > 0" @click="viewUnsubmittedStudents()">{{
|
|
|
+ lang.ssViewSubmitStatus2 }}</span>
|
|
|
+ </div>
|
|
|
+ <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">{{ lang.ssPrevQ }}</span>-->
|
|
|
+ <!--<span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">{{ lang.ssNextQ }}</span>-->
|
|
|
+ </div>
|
|
|
+ <img class="c_t45_img" :src="props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .timuList[0].src
|
|
|
+ " v-if="props.showData.choiceQuestionListData[props.showData.workIndex] &&
|
|
|
+ props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .timuList.length > 0
|
|
|
+ " @click="previewImageToolRef.previewImage(props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .timuList[0].src)" />
|
|
|
+ <!-- <span class="c_t45_type" v-if="
|
|
|
+ props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .type === '1'
|
|
|
+ ">{{ lang.ssSingleSel }}</span>
|
|
|
+ <span class="c_t45_type" v-if="
|
|
|
+ props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ .type === '2'
|
|
|
+ ">{{ lang.ssMultiOpt }}</span> -->
|
|
|
+ <!-- <span class="c_t45_type">{{ lang.ssChoiceQuestion }}</span> -->
|
|
|
+ <div class="c_t45_echarts" :style="{
|
|
|
+ width: slideWidth - 40 + 'px',
|
|
|
+ }">
|
|
|
+ <div id="echartsArea1" ref="echartsArea1"></div>
|
|
|
+ </div>
|
|
|
+ <div class="aiAnalysis" v-if="props.workArray.length > 0">
|
|
|
+ <div class="ai_header">
|
|
|
+ <div class="ai_title">
|
|
|
+ <svg viewBox="0 0 1024 1024" width="200" height="200">
|
|
|
+ <path
|
|
|
+ d="M512 170.666667C323.477333 170.666667 170.666667 323.477333 170.666667 512s152.810667 341.333333 341.333333 341.333333 341.333333-152.810667 341.333333-341.333333S700.522667 170.666667 512 170.666667zM85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333s426.666667 191.018667 426.666667 426.666667-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512z">
|
|
|
+ </path>
|
|
|
+ <path
|
|
|
+ d="M693.013333 330.986667a42.666667 42.666667 0 0 1 10.304 43.648l-75.413333 226.282666a42.666667 42.666667 0 0 1-26.986667 26.986667l-226.282666 75.413333a42.666667 42.666667 0 0 1-53.973334-53.973333l75.434667-226.261333a42.666667 42.666667 0 0 1 26.986667-26.986667l226.282666-75.413333a42.666667 42.666667 0 0 1 43.648 10.304z m-222.72 139.306666l-41.685333 125.098667 125.077333-41.706667 41.706667-125.077333-125.077333 41.706667z">
|
|
|
+ </path>
|
|
|
+ </svg>{{ lang.ssAnalysis }}
|
|
|
+ </div>
|
|
|
+ <div class="ai_refresh" :class="{ 'disabled': currentAnalysis && currentAnalysis.loading }"
|
|
|
+ @click="aiAnalysisRefresh78()">
|
|
|
+ {{ lang.ssAIGenerate }}
|
|
|
+ <svg viewBox="0 0 1024 1024" width="200" height="200">
|
|
|
+ <path
|
|
|
+ d="M875 483c-33.4 0-60.5 27.1-60.5 60.5v0.1C814.4 710.3 678.8 846 512 846S209.5 710.3 209.5 543.5 345.2 241 512 241c36.8 0 71.7 7.6 104.4 19.7-32 3-57.4 29.1-57.4 61.9 0 34.8 28.2 63 63 63h201.9c34.8 0 63-28.2 63-63V120c0-34.8-28.2-63-63-63s-63 28.2-63 63v81.4C691 150.5 605.2 120 512 120 278.1 120 88.5 309.6 88.5 543.5S278.1 967 512 967s423.5-189.6 423.5-423.5c0-33.4-27.1-60.5-60.5-60.5z">
|
|
|
+ </path>
|
|
|
+ </svg>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="ai_content" v-if="currentAnalysis && currentAnalysis.json">
|
|
|
+ {{ currentAnalysis.json.text }}
|
|
|
+ </div>
|
|
|
+ <div class="ai_echartsData" v-if="currentAnalysis && currentAnalysis.json.keyword">
|
|
|
+ {{ currentAnalysis.json.keyword }}
|
|
|
+ </div>
|
|
|
+ <div class="generatingContent" v-if="currentAnalysis && currentAnalysis.loading">
|
|
|
+ {{ lang.ssGeneratingContent }}...</div>
|
|
|
+ <div class="ai_updateTime" v-if="currentAnalysis">{{ lang.ssUpdateTime }}:{{ currentAnalysis.update_at }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="cq_changeBtn" v-if="props.showData.choiceQuestionListData.length > 1">
|
|
|
+ <div :class="{ cq_cb_disabled: props.showData.workIndex <= 0 }" @click="changeWorkIndex(0)">
|
|
|
+ <svg style="transform: rotate(-90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
|
|
|
+ <path
|
|
|
+ d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
|
|
|
+ fill=""></path>
|
|
|
+ </svg>
|
|
|
+ </div>
|
|
|
+ <span>{{ props.showData.workIndex + 1 }}/{{ props.showData.choiceQuestionListData.length }}</span>
|
|
|
+ <div :class="{ cq_cb_disabled: props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1 }"
|
|
|
+ @click="changeWorkIndex(1)">
|
|
|
+ <svg style="transform: rotate(90deg);" viewBox="0 0 1024 1024" version="1.1" width="200" height="200">
|
|
|
+ <path
|
|
|
+ d="M512 330.666667c14.933333 0 29.866667 4.266667 40.533333 14.933333l277.33333399 234.666667c27.733333 23.466667 29.866667 64 8.53333301 89.6-23.466667 27.733333-64 29.866667-89.6 8.53333299L512 477.866667l-236.8 200.53333299c-27.733333 23.466667-68.266667 19.19999999-89.6-8.53333299-23.466667-27.733333-19.19999999-68.266667 8.53333301-89.6l277.33333399-234.666667c10.666667-10.666667 25.6-14.933333 40.533333-14.933333z"
|
|
|
+ fill=""></path>
|
|
|
+ </svg>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- 问答题 -->
|
|
|
<div class="c_t15" v-if="workDetail && workDetail.type === '15' && props.showData">
|
|
|
<div class="c_t15_title">{{ workDetail.json.answerQ }}</div>
|
|
|
@@ -395,7 +488,7 @@ const processWorkContent = async (content: string, toolType: number): Promise<an
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- if ([45, 15].includes(toolType)) {
|
|
|
+ if ([45, 15, 78].includes(toolType)) {
|
|
|
return JSON.parse(decodeURIComponent(contentToParse))
|
|
|
}
|
|
|
else if (toolType === 72) {
|
|
|
@@ -537,7 +630,7 @@ const handleChartResize = () => {
|
|
|
if (
|
|
|
props.showData &&
|
|
|
props.showData.workDetail &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
setEchartsArea1()
|
|
|
}
|
|
|
@@ -766,7 +859,7 @@ watch(
|
|
|
if (
|
|
|
newVal &&
|
|
|
newVal.choiceQuestionListData[newVal.workIndex] &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
if (
|
|
|
oldVal &&
|
|
|
@@ -804,7 +897,7 @@ watch(
|
|
|
if (
|
|
|
(newVal || newVal === 0) &&
|
|
|
props.showData.workDetail &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
|
|
setEchartsArea1()
|
|
|
@@ -827,7 +920,7 @@ watch(
|
|
|
if (
|
|
|
(newVal || newVal === 0) &&
|
|
|
props.showData.workDetail &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
setEchartsArea1()
|
|
|
}
|
|
|
@@ -845,7 +938,7 @@ watch(
|
|
|
newVal &&
|
|
|
props.showData &&
|
|
|
props.showData.workDetail &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
setEchartsArea1()
|
|
|
}
|
|
|
@@ -863,7 +956,7 @@ watch(
|
|
|
newVal &&
|
|
|
props.showData &&
|
|
|
props.showData.workDetail &&
|
|
|
- props.showData.workDetail.type === '45'
|
|
|
+ (props.showData.workDetail.type === '45' || props.showData.workDetail.type === '78')
|
|
|
) {
|
|
|
handleChartResize()
|
|
|
}
|
|
|
@@ -959,6 +1052,87 @@ const aiAnalysisRefresh45 = () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+// ai生成投票分析 投票
|
|
|
+const aiAnalysisRefresh78 = () => {
|
|
|
+ const _work = props.showData.choiceQuestionListData[props.showData.workIndex]
|
|
|
+ const msg = `# CONTEXT #
|
|
|
+你是K-12阶段的AI教育课堂分析助手,基于上传的课件、逐字稿,以及当页的学生答题数据(选择题/问答题/智能体对话/投票)进行智能分析。
|
|
|
+
|
|
|
+# OBJECTIVE #
|
|
|
+输出当前学生答题的分析报告:整体表现、核心发现(共性问题/误区)、教学优化(改进方向),为教师提供教学策略的建议和支持。
|
|
|
+
|
|
|
+#INPUT#
|
|
|
+课程数据:
|
|
|
+- 课程名称:${props.courseDetail.title}
|
|
|
+- 课程学科:${props.courseDetail.name}
|
|
|
+当前页面答题数据(投票):【分析重点】
|
|
|
+- 投票题目:${_work.teststitle}
|
|
|
+- 选项数据:${JSON.stringify(_work.choiceUser)}
|
|
|
+- 题目图片:${_work.timuList.lenght ? _work.timuList[0].src : ''}
|
|
|
+- 未提交学生:${JSON.stringify(props.showData.unsubmittedStudents.map((item: any) => item.name))}
|
|
|
+
|
|
|
+# ANALYSIS RULES #
|
|
|
+1. **问题定位**:明确指出哪个知识点/概念/步骤掌握不佳
|
|
|
+2. **建议具体**:给出可执行的教学动作(如“增加XX实例演练”“补充XX对比图”)
|
|
|
+
|
|
|
+# RESPONSE #
|
|
|
+采用段落叙述,数据量化呈现,突出可操作建议,严格控制输出为80词内。采用三段式论述:
|
|
|
+1. 整体表现-1句话
|
|
|
+2. 核心发现-1-2句,指出共性问题+典型案例
|
|
|
+3. 改进建议-1句话,提出具体教学动作
|
|
|
+
|
|
|
+# EXAMPLES #
|
|
|
+样例:
|
|
|
+选择题正确率62%,核心概念“机器学习三步骤”(输入数据→训练模型→预测结果)掌握尚可,但“训练与预测区分”混淆率达38%;建议强化训练vs预测对比教学。`
|
|
|
+
|
|
|
+ if (!currentAnalysis.value) {
|
|
|
+ aiAnalysisData.value.push({
|
|
|
+ pid: props.workId + (props.cid ? ',' + props.cid : ''),
|
|
|
+ index: props.showData.workIndex,
|
|
|
+ loading: true,
|
|
|
+ generatingContent: true,
|
|
|
+ json: { text: '', echartsData: '' },
|
|
|
+ noEnd: true,
|
|
|
+ update_at: '',
|
|
|
+ create_at: '',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).loading = true
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).json = { text: '', echartsData: '' }
|
|
|
+ }
|
|
|
+
|
|
|
+ chat_stream(msg, 'a7741704-ba56-40b7-a6b8-62a423ef9376', props.userId, lang.lang, (event) => {
|
|
|
+ if (event.type === 'message') {
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).json.text = event.data
|
|
|
+
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).loading = false
|
|
|
+ }
|
|
|
+ else if (event.type === 'messageEnd') {
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).json.text = event.data
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).noEnd = false
|
|
|
+ aiAnalysisData.value.find((item: any) => {
|
|
|
+ return item.pid === props.workId + (props.cid ? ',' + props.cid : '') && item.index === props.showData.workIndex
|
|
|
+ }).update_at = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')
|
|
|
+ saveAnalysis()
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ console.log('err', err)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
// 问答题
|
|
|
const aiAnalysisRefresh15 = () => {
|
|
|
let flag = 0
|