Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
1cc0254a
提交
1cc0254a
authored
11月 26, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
e041a8c4
全部展开
显示空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
111 行增加
和
69 行删除
+111
-69
package-lock.json
package-lock.json
+0
-0
RecordDialog.vue
src/modules/live/test/components/RecordDialog.vue
+1
-1
api.ts
src/modules/score/api.ts
+2
-2
useScore.ts
src/modules/score/composables/useScore.ts
+95
-0
prompt.ts
src/modules/score/prompt.ts
+2
-2
prompt2.ts
src/modules/score/prompt2.ts
+2
-2
Index.vue
src/modules/score/views/Index.vue
+7
-60
View.vue
src/modules/score/views/View.vue
+2
-2
没有找到文件。
package-lock.json
浏览文件 @
1cc0254a
差异被折叠。
点击展开。
src/modules/live/test/components/RecordDialog.vue
浏览文件 @
1cc0254a
...
@@ -121,7 +121,7 @@ useIntervalFn(() => {
...
@@ -121,7 +121,7 @@ useIntervalFn(() => {
>直播视频回放
>直播视频回放
</router-link>
</router-link>
</el-button>
</el-button>
<template
v-if=
"row.ai_status == '已完成'"
>
<template
v-if=
"row.ai_status == '已完成'
|| row.ai_analyze
"
>
<br
/>
<br
/>
<el-button
text
type=
"primary"
>
<el-button
text
type=
"primary"
>
<router-link
:to=
"
{ path: 'test/view', query: { ...$route.query, id: data.id, record_id: row.id } }"
<router-link
:to=
"
{ path: 'test/view', query: { ...$route.query, id: data.id, record_id: row.id } }"
...
...
src/modules/score/api.ts
浏览文件 @
1cc0254a
...
@@ -6,7 +6,7 @@ export function getScoreDetail(params?: { id: string }) {
...
@@ -6,7 +6,7 @@ export function getScoreDetail(params?: { id: string }) {
}
}
// 获取直播成绩列表
// 获取直播成绩列表
export
function
getScoreList
(
params
?:
{
name
?:
string
})
{
export
function
getScoreList
(
params
?:
{
name
?:
string
;
check_status
?:
number
;
'per-page'
?:
number
;
page
?:
number
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/live-student-record/list'
,
{
params
})
return
httpRequest
.
get
(
'/api/lab/v1/experiment/live-student-record/list'
,
{
params
})
}
}
...
@@ -16,7 +16,7 @@ export function exportScore(params?: { name?: string }) {
...
@@ -16,7 +16,7 @@ export function exportScore(params?: { name?: string }) {
}
}
// 更新成绩
// 更新成绩
export
function
updateScore
(
data
:
{
id
:
string
;
check_status
:
number
;
total_score
:
number
;
score_details
:
string
})
{
export
function
updateScore
(
data
:
{
id
:
string
;
check_status
:
number
;
total_score
?:
number
;
score_details
?
:
string
})
{
return
httpRequest
.
post
(
'/api/lab/v1/experiment/live-student-record/score'
,
data
)
return
httpRequest
.
post
(
'/api/lab/v1/experiment/live-student-record/score'
,
data
)
}
}
...
...
src/modules/score/composables/useScore.ts
0 → 100644
浏览文件 @
1cc0254a
import
{
getScoreList
,
getScoreDetail
,
updateScore
}
from
'../api'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useChat
}
from
'@ezijing/ai-vue'
import
{
generatePrompt
}
from
'../prompt'
import
{
generatePrompt
as
generatePrompt2
}
from
'../prompt2'
interface
ScoreDetail
{
is_ai
?:
boolean
checker_id
?:
string
checker_name
?:
string
scores
:
Record
<
string
,
ScoreItem
>
total_score
:
number
updated_at
:
string
}
interface
ScoreItem
{
score
:
number
comment
:
string
}
export
function
useScore
()
{
const
userStore
=
useUserStore
()
const
isLoading
=
ref
(
false
)
const
{
generateText
}
=
useChat
({
provider
:
'volcano'
})
const
fetchScoreList
=
async
()
=>
{
const
res
=
await
getScoreList
({
'per-page'
:
200
,
check_status
:
0
})
return
res
.
data
.
list
}
const
fetchScoreDetail
=
async
(
id
:
string
)
=>
{
const
res
=
await
getScoreDetail
({
id
})
const
detail
=
res
.
data
.
detail
// 仅保留两条记录,并按时间顺序排序
detail
.
live_data
.
practices
=
detail
.
live_data
.
practices
.
slice
(
0
,
2
).
reverse
()
const
parsed
=
detail
.
score_details
?
JSON
.
parse
(
detail
.
score_details
)
:
[]
const
scores
=
Array
.
isArray
(
parsed
)
?
parsed
:
[]
return
{
...
detail
,
scores
}
}
const
handleAIScoreList
=
async
()
=>
{
isLoading
.
value
=
true
const
list
=
await
fetchScoreList
()
for
(
const
item
of
list
)
{
console
.
log
(
'AI评分中'
,
item
.
id
)
const
detail
=
await
fetchScoreDetail
(
item
.
id
)
// 修改为评分中
await
updateScore
({
id
:
detail
.
id
,
check_status
:
1
})
await
handleAIScore
(
detail
)
}
isLoading
.
value
=
false
}
const
handleAIScore
=
async
(
detail
:
any
)
=>
{
const
prompt
=
detail
.
competition_rule
?.
questions
==
1
?
generatePrompt
(
detail
.
live_data
)
:
generatePrompt2
(
detail
.
live_data
)
const
result
=
await
generateText
({
prompt
,
response_format
:
{
type
:
'json_object'
}
}
as
any
)
if
(
!
result
)
return
try
{
const
scoreDetails
:
Record
<
string
,
ScoreItem
>
=
JSON
.
parse
(
result
.
content
)
const
totalScore
=
Object
.
values
(
scoreDetails
).
reduce
((
acc
,
curr
)
=>
acc
+
(
curr
.
score
||
0
),
0
)
console
.
log
(
scoreDetails
)
const
myScore
:
ScoreDetail
=
{
is_ai
:
true
,
checker_id
:
userStore
.
user
?.
id
,
checker_name
:
userStore
.
user
?.
name
,
scores
:
scoreDetails
,
total_score
:
totalScore
,
updated_at
:
new
Date
().
toLocaleString
(),
}
const
scores
=
[...
detail
.
scores
.
filter
((
item
:
any
)
=>
item
.
checker_id
!=
userStore
.
user
?.
id
),
myScore
]
// 总平均分,过滤掉AI评分
const
validScores
=
scores
.
filter
((
item
)
=>
!
item
.
is_ai
)
const
totalAverageScore
=
validScores
.
reduce
((
acc
,
curr
)
=>
acc
+
(
curr
.
total_score
||
0
),
0
)
/
validScores
.
length
await
updateScore
({
id
:
detail
.
id
,
check_status
:
2
,
total_score
:
totalAverageScore
,
score_details
:
JSON
.
stringify
(
scores
),
})
console
.
log
(
'AI评分完成'
,
{
id
:
detail
.
id
,
check_status
:
2
,
total_score
:
totalAverageScore
,
score_details
:
JSON
.
stringify
(
scores
),
})
}
catch
(
error
)
{
console
.
log
(
'评分失败'
,
error
)
}
}
return
{
isLoading
,
fetchScoreList
,
fetchScoreDetail
,
handleAIScoreList
,
handleAIScore
}
}
src/modules/score/prompt.ts
浏览文件 @
1cc0254a
...
@@ -503,7 +503,7 @@ export const generatePracticeRecordPrompt = (data: any) => {
...
@@ -503,7 +503,7 @@ export const generatePracticeRecordPrompt = (data: any) => {
const
firstLivePracticeRecord
=
firstLivePractice
?.
records
[
0
]
const
firstLivePracticeRecord
=
firstLivePractice
?.
records
[
0
]
return
`请根据选手提交的内容进行评分(满分20分)
return
`请根据选手提交的内容进行评分(满分20分)
选手提交内容:
选手提交内容:
${
JSON
.
stringify
(
firstLivePracticeRecord
)}
${
JSON
.
stringify
(
firstLivePracticeRecord
?.
subtitle
)}
`
`
}
}
...
@@ -527,7 +527,7 @@ export const generatePracticeRecord2Prompt = (data: any) => {
...
@@ -527,7 +527,7 @@ export const generatePracticeRecord2Prompt = (data: any) => {
return `
return `
请根据选手提交的二次直播演练内容进行评分(满分
15
分)
请根据选手提交的二次直播演练内容进行评分(满分
15
分)
选手提交内容:
选手提交内容:
$
{
JSON
.
stringify
(
secondLivePracticeRecord
)}
$
{
JSON
.
stringify
(
secondLivePracticeRecord
?.
subtitle
)}
`
`
}
}
...
...
src/modules/score/prompt2.ts
浏览文件 @
1cc0254a
...
@@ -602,7 +602,7 @@ export const generatePracticeRecordPrompt = (data: any) => {
...
@@ -602,7 +602,7 @@ export const generatePracticeRecordPrompt = (data: any) => {
const
firstLivePracticeRecord
=
firstLivePractice
?.
records
[
0
]
const
firstLivePracticeRecord
=
firstLivePractice
?.
records
[
0
]
return
`请根据选手提交的内容进行评分(满分15分)
return
`请根据选手提交的内容进行评分(满分15分)
选手提交内容:
选手提交内容:
${
JSON
.
stringify
(
firstLivePracticeRecord
)}
${
JSON
.
stringify
(
firstLivePracticeRecord
?.
subtitle
)}
评分规则
评分规则
1
.
开场与氛围营造(
2
分)
1
.
开场与氛围营造(
2
分)
...
@@ -772,7 +772,7 @@ export const generatePracticeRecord2Prompt = (data: any) => {
...
@@ -772,7 +772,7 @@ export const generatePracticeRecord2Prompt = (data: any) => {
return `
return `
请根据选手提交的二次直播演练内容进行评分(满分
30
分)
请根据选手提交的二次直播演练内容进行评分(满分
30
分)
选手提交内容:
选手提交内容:
$
{
JSON
.
stringify
(
secondLivePracticeRecord
)}
$
{
JSON
.
stringify
(
secondLivePracticeRecord
?.
subtitle
)}
评分说明
评分说明
以改进方案列出的措施和首次直播
AI
评价报告中的问题为基准,逐条对照二次直播字幕
/
话术确认改进落实与否。
以改进方案列出的措施和首次直播
AI
评价报告中的问题为基准,逐条对照二次直播字幕
/
话术确认改进落实与否。
...
...
src/modules/score/views/Index.vue
浏览文件 @
1cc0254a
<
script
setup
>
<
script
setup
>
import
LiveProductCategory
from
'@/components/LiveProductCategory.vue'
import
LiveProductCategory
from
'@/components/LiveProductCategory.vue'
import
{
getScoreList
,
getScoreDetail
,
publishAll
,
updateScore
}
from
'../api'
import
{
getScoreList
,
publishAll
}
from
'../api'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
{
useChat
}
from
'@ezijing/ai-vue'
import
{
generatePrompt
}
from
'../prompt'
import
{
generatePrompt
as
generatePrompt2
}
from
'../prompt2'
import
{
useIntervalFn
}
from
'@vueuse/core'
import
{
useIntervalFn
}
from
'@vueuse/core'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useScore
}
from
'../composables/useScore'
const
userStore
=
useUserStore
()
const
{
isLoading
,
handleAIScoreList
}
=
useScore
()
const
route
=
useRoute
()
const
route
=
useRoute
()
const
appList
=
ref
(
null
)
const
appList
=
ref
(
null
)
...
@@ -73,59 +71,6 @@ const handleExport = () => {
...
@@ -73,59 +71,6 @@ const handleExport = () => {
window
.
open
(
`/api/lab/v1/experiment/live-student-record/export?experiment_id=
${
route
.
query
.
experiment_id
}
`
)
window
.
open
(
`/api/lab/v1/experiment/live-student-record/export?experiment_id=
${
route
.
query
.
experiment_id
}
`
)
}
}
const
{
isLoading
,
generateText
}
=
useChat
({
provider
:
'volcano'
})
const
handleAIScore
=
async
()
=>
{
console
.
log
(
'AI一键评分'
)
const
res
=
await
getScoreList
({
'per-page'
:
200
,
check_status
:
0
})
const
list
=
res
.
data
.
list
list
.
forEach
(
async
(
item
)
=>
{
const
detailRes
=
await
getScoreDetail
({
id
:
item
.
id
})
const
detail
=
detailRes
.
data
.
detail
// 仅保留两条记录,并按时间顺序排序
detail
.
live_data
.
practices
=
detail
.
live_data
.
practices
.
slice
(
0
,
2
).
reverse
()
const
parsed
=
detail
.
score_details
?
JSON
.
parse
(
detail
.
score_details
)
:
[]
let
scores
=
Array
.
isArray
(
parsed
)
?
parsed
:
[]
const
prompt
=
detail
.
competition_rule
?.
questions
==
1
?
generatePrompt
(
detail
.
live_data
)
:
generatePrompt2
(
detail
.
live_data
)
// 修改为评分中
updateScore
({
id
:
item
.
id
,
check_status
:
1
})
const
result
=
await
generateText
({
prompt
,
response_format
:
{
type
:
'json_object'
}
})
try
{
const
scoreDetails
=
JSON
.
parse
(
result
.
content
)
const
totalScore
=
Object
.
values
(
scoreDetails
).
reduce
((
acc
,
curr
)
=>
acc
+
(
curr
.
score
||
0
),
0
)
console
.
log
(
scoreDetails
)
const
myScore
=
{
is_ai
:
true
,
checker_id
:
userStore
.
user
.
id
,
checker_name
:
userStore
.
user
.
name
,
scores
:
scoreDetails
,
total_score
:
totalScore
,
updated_at
:
new
Date
().
toLocaleString
(),
}
scores
=
[...
scores
.
filter
((
item
)
=>
item
.
checker_id
!=
userStore
.
user
.
id
),
myScore
]
// 总平均分,过滤掉AI评分
const
validScores
=
scores
.
filter
((
item
)
=>
!
item
.
is_ai
)
const
totalAverageScore
=
validScores
.
reduce
((
acc
,
curr
)
=>
acc
+
(
curr
.
total_score
||
0
),
0
)
/
validScores
.
length
updateScore
({
id
:
item
.
id
,
check_status
:
2
,
total_score
:
totalAverageScore
,
score_details
:
JSON
.
stringify
(
scores
),
}).
then
(()
=>
{
console
.
log
(
'AI评分完成'
)
})
}
catch
(
error
)
{
console
.
log
(
'评分失败'
,
error
)
}
})
}
const
handlePublishScore
=
()
=>
{
const
handlePublishScore
=
()
=>
{
publishAll
().
then
(()
=>
{
publishAll
().
then
(()
=>
{
ElMessage
.
success
(
'发布成绩成功'
)
ElMessage
.
success
(
'发布成绩成功'
)
...
@@ -145,7 +90,9 @@ useIntervalFn(() => {
...
@@ -145,7 +90,9 @@ useIntervalFn(() => {
<el-row
justify=
"space-between"
>
<el-row
justify=
"space-between"
>
<el-button
type=
"primary"
@
click=
"handleExport"
>
导出成绩
</el-button>
<el-button
type=
"primary"
@
click=
"handleExport"
>
导出成绩
</el-button>
<div>
<div>
<el-button
type=
"primary"
@
click=
"handleAIScore"
:loading=
"isLoading"
v-if=
"hasAI"
>
AI一键评分
</el-button>
<el-button
type=
"primary"
@
click=
"handleAIScoreList"
:loading=
"isLoading"
v-if=
"hasAI"
>
AI一键评分
</el-button
>
<el-button
type=
"primary"
@
click=
"handlePublishScore"
v-if=
"false"
>
一键发布成绩
</el-button>
<el-button
type=
"primary"
@
click=
"handlePublishScore"
v-if=
"false"
>
一键发布成绩
</el-button>
</div>
</div>
</el-row>
</el-row>
...
...
src/modules/score/views/View.vue
浏览文件 @
1cc0254a
...
@@ -40,8 +40,8 @@ const fetchDetail = async () => {
...
@@ -40,8 +40,8 @@ const fetchDetail = async () => {
scores
=
[]
scores
=
[]
}
}
const
myScore
=
scores
.
find
((
item
)
=>
item
.
checker_id
==
userStore
.
user
.
id
)?.
scores
const
myScore
=
scores
.
find
((
item
)
=>
item
.
checker_id
==
userStore
.
user
.
id
)?.
scores
const
firstScore
=
cloneDeep
(
scores
[
0
]?.
scores
)
const
aiScore
=
scores
.
find
((
item
)
=>
item
.
is_ai
)?.
scores
Object
.
assign
(
scoreDetails
,
myScore
||
firstScore
||
{}
)
Object
.
assign
(
scoreDetails
,
cloneDeep
(
myScore
||
aiScore
||
{})
)
}
}
onMounted
(()
=>
{
onMounted
(()
=>
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论