Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
a215af9e
提交
a215af9e
authored
11月 11, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: AI一键评分
上级
70de0f02
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
616 行增加
和
32 行删除
+616
-32
prompt.ts
src/modules/live/score/prompt.ts
+580
-0
Index.vue
src/modules/live/score/views/Index.vue
+1
-0
View.vue
src/modules/live/score/views/View.vue
+35
-32
没有找到文件。
src/modules/live/score/prompt.ts
0 → 100644
浏览文件 @
a215af9e
export
const
generateCommodityTypePrompt
=
(
data
:
any
)
=>
{
return
`请根据选手提交的商品品类信息进行评分(满分5分):
选手提交内容:
${
JSON
.
stringify
(
data
.
commodity_types
)}
评分标准:
1. 一级品类创建(2分)
检查项:
是否创建"护肤品类"(1分)
是否创建"彩妆品类"(1分)
2. 护肤品类二级分类(1.5分)
检查项:
"面膜系列"(0.5分)
"精华系列"(0.5分)
"水乳系列"(0.5分)
3. 彩妆品类二级分类(1.5分)
检查项:
"口红系列"(0.5分)
"眼影系列"(0.5分)
"腮红系列"(0.5分)
【整体评价】
(请对选手整体表现进行1-2句总结性评价)`
}
export
const
generateCommodityAttrsPrompt
=
(
data
:
any
)
=>
{
return
`
请根据选手提交的商品属性配置进行评分(满分5分):
选手提交内容:
${
JSON
.
stringify
(
data
.
commodity_attrs
)}
评分标准
1. 护肤品类属性配置(2.5分)
必须创建5个属性,每个0.5分:
属性1:适用肤质(0.5分)
属性名称正确(0.1分)
所属品类:护肤品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性2:核心成分(0.5分)
属性名称正确(0.1分)
所属品类:护肤品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性3:产品规格(0.5分)
属性名称正确(0.1分)
所属品类:护肤品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性4:产品功效(0.5分)
属性名称正确(0.1分)
所属品类:护肤品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性5:使用方法(0.5分)
属性名称正确(0.1分)
所属品类:护肤品类(0.1分)
重要性:非重要(0.1分)
必要性:非必须(0.1分)
状态:有效(0.1分)
2. 彩妆品类属性配置(2.5分)
必须创建5个属性,每个0.5分:
属性1:色号(0.5分)
属性名称正确(0.1分)
所属品类:彩妆品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性2:质地(0.5分)
属性名称正确(0.1分)
所属品类:彩妆品类(0.1分)
重要性:重要(0.1分)
必要性:必须(0.1分)
状态:有效(0.1分)
属性3:持久度(0.5分)
属性名称正确(0.1分)
所属品类:彩妆品类(0.1分)
重要性:重要(0.1分)
必要性:非必须(0.1分)
状态:有效(0.1分)
属性4:适用场景(0.5分)
属性名称正确(0.1分)
所属品类:彩妆品类(0.1分)
重要性:非重要(0.1分)
必要性:非必须(0.1分)
状态:有效(0.1分)
属性5:妆效风格(0.5分)
属性名称正确(0.1分)
所属品类:彩妆品类(0.1分)
重要性:非重要(0.1分)
必要性:非必须(0.1分)
状态:有效(0.1分)
评分细则
━━━━━━━━━━━━━━━━━━━━━━
【扣分规则】
- 属性名称完全匹配可得分
- 重要性、必要性设置错误,该属性扣50%分数(即扣0.2分)
- 关联品类错误,该属性不得分
- 状态未设置为"有效",该属性不得分
【注意事项】
1. 每个品类必须创建完整的5个属性
2. 属性必须正确关联到对应的品类
3. 重要性和必要性的配置必须完全符合要求
4. 所有属性的状态必须设置为"有效"`
}
export
const
generateCommoditiesPrompt
=
(
data
:
any
)
=>
{
return
`
请根据选手提交的商品信息维护内容进行评分(满分15分)
选手提交内容:
${
JSON
.
stringify
(
data
.
commodities
)}
选手需要完成2个主推商品的完整信息维护:
1. 玻尿酸补水面膜(引流款)
2. 烟酰胺精华液(利润款)
每个商品需完成5个板块的维护:
- 商品类目设置
- 基础信息维护(标题、短标题、商品属性)
- 图文信息维护(主图、3:4主图)
- 价格与库存信息
- 服务与履约
━━━━━━━━━━━━━━━━━━━━━━
评分标准(满分15分)
━━━━━━━━━━━━━━━━━━━━━━
一、商品类目关联(1分)
商品1:玻尿酸补水面膜(0.5分)
类目设置:_______________
正确关联:护肤品类 → 面膜系列(0.5分)
关联错误或未关联(0分)
商品2:烟酰胺精华液(0.5分)
类目设置:_______________
正确关联:护肤品类 → 精华系列(0.5分)
关联错误或未关联(0分)
━━━━━━━━━━━━━━━━━━━━━━
二、商品主图(1:1比例)(2分)
商品1:玻尿酸补水面膜(1分)
主图数量:___张
主图≥3张(1分)
主图2张(0.7分)
主图1张(0.3分)
主图0张(0分)
商品2:烟酰胺精华液(1分)
主图数量:___张
主图≥3张(1分)
主图2张(0.7分)
主图1张(0.3分)
主图0张(0分)
━━━━━━━━━━━━━━━━━━━━━━
三、3:4比例主图(2分)
商品1:玻尿酸补水面膜(1分)
3:4主图数量:___张
3:4主图≥2张(1分)
3:4主图1张(0.5分)
3:4主图0张(0分)
商品2:烟酰胺精华液(1分)
3:4主图数量:___张
3:4主图≥2张(1分)
3:4主图1张(0.5分)
3:4主图0张(0分)
━━━━━━━━━━━━━━━━━━━━━━
四、价格库存配置(6分)
商品1:玻尿酸补水面膜(3分)
1. 发货模式(0.5分)
发货模式:_______________
设置为"现货发货模式"(0.5分)
未设置或设置错误(0分)
2. 商品规格(0.8分)
设置的规格:_______________
设置了至少2个规格(0.8分)
只设置1个规格(0.4分)
未设置规格(0分)
3. 发货时效(0.5分)
发货时效:_______________
设置为"次日发"(0.5分)
未设置或设置错误(0分)
4. 价格设置(0.6分)
价格信息:_______________
设置了价格和参考价(0.6分)
只设置了价格,未设置参考价(0.3分)
未设置价格(0分)
5. 库存设置(0.3分)
库存信息:_______________
已设置库存数量(0.3分)
未设置库存(0分)
6. 订单库存扣减规则(0.3分)
扣减规则:_______________
选择"付款减库存"(0.3分)
未设置或设置错误(0分)
商品2:烟酰胺精华液(3分)
1. 发货模式(0.5分)
发货模式:_______________
设置为"现货发货模式"(0.5分)
未设置或设置错误(0分)
2. 商品规格(0.8分)
设置的规格:_______________
设置了至少2个规格(0.8分)
只设置1个规格(0.4分)
未设置规格(0分)
3. 发货时效(0.5分)
发货时效:_______________
设置为"次日发"(0.5分)
未设置或设置错误(0分)
4. 价格设置(0.6分)
价格信息:_______________
设置了价格和参考价(0.6分)
只设置了价格,未设置参考价(0.3分)
未设置价格(0分)
5. 库存设置(0.3分)
库存信息:_______________
已设置库存数量(0.3分)
未设置库存(0分)
6. 订单库存扣减规则(0.3分)
扣减规则:_______________
选择"付款减库存"(0.3分)
未设置或设置错误(0分)
━━━━━━━━━━━━━━━━━━━━━━
五、服务履约配置(4分)
商品1:玻尿酸补水面膜(2分)
1. 运费模板(1分)
运费模板:_______________
选择"指定条件包邮"模板(1分)
设置了其他运费模板(0.5分)
未设置运费模板(0分)
2. 售后政策(1分)
售后政策:_______________
至少选择了1项售后政策(1分)
未设置售后政策(0分)
━━━━━━━━━━━━━━━━━━━━━━
商品2:烟酰胺精华液(2分)
1. 运费模板(1分)
运费模板:_______________
选择"指定条件包邮"模板(1分)
设置了其他运费模板(0.5分)
未设置运费模板(0分)
2. 售后政策(1分)
售后政策:_______________
至少选择了1项售后政策(1分)
未设置售后政策(0分)
━━━━━━━━━━━━━━━━━━━━━━
【评分说明】
1. 商品类目关联是基础,必须正确关联到指定的二级品类
2. 图片评分以数量为主,质量为辅,数量达标即可得分
3. 价格库存配置是重点(6分),需要逐项检查6个配置项
4. 服务履约配置注重完整性,至少要有1项售后政策
5. 两个商品都必须完整维护,缺少任何一个商品都会大量失分
【整体评价】
(请对选手整体表现进行1-2句总结性评价)`
}
export
const
generateSpeechPrompt
=
(
data
:
any
)
=>
{
return
`
请根据选手提交的直播话术进行评分(满分15分)
选手提交内容内容:
${
JSON
.
stringify
(
data
.
speeches
)}
选手需要编写完整的直播话术,包括:
- 话术名称设置
- 商品选择
- 商品卖点提炼(至少3个)
- 营销活动设计(至少4个)
- 完整话术脚本(15分钟)
━━━━━━━━━━━━━━━━━━━━━━
评分标准(满分15分)
━━━━━━━━━━━━━━━━━━━━━━
一、话术名称(1分)
话术名称:_______________
评分标准:
字数5-20字(0.5分)
简洁明了(0.3分)
体现直播主题(0.2分)
二、商品选择(1分)
选择的商品:_______________
评分标准:
正确选择(1分)
未选择(0分)
━━━━━━━━━━━━━━━━━━━━━━
三、卖点提炼(3分)
要求:满足以下卖点中三个,每个卖点1分
【参考卖点】
卖点1:5%高浓度烟酰胺,科学配比,淡化细纹效果显著
卖点2:添加传明酸和维C衍生物,多重美白,提亮肤色
卖点3:7天见效,28天肌肤焕然一新(真实用户反馈)
卖点4:清爽质地,不油腻,吸收快,适合所有肤质
卖点5:30ml精华液相当于3瓶普通精华的量,超大容量
━━━━━━━━━━━━━━━━━━━━━━
四、营销活动设计(3分)
要求:至少设计4个营销活动,每个0.75分
【必须包含的活动类型检查】
限时秒杀活动
组合优惠活动
互动抽奖活动
下单福利
━━━━━━━━━━━━━━━━━━━━━━
五、话术结构完整性(2分)
话术脚本必须包含以下7个环节:
①开场白环节(0.3分)
- 热情问候、自我介绍
- 直播主题引入
- 福利活动预告
- 引导关注点赞
②品牌介绍环节(0.25分)
- 品牌故事和理念
- 品牌实力和成就
- 建立品牌信任度
③产品讲解环节(0.4分)
- 产品展示
- 成分讲解(5%烟酰胺、传明酸等)
- 卖点阐述
- 使用方法和效果
- 价格对比和优惠信息
④互动环节(0.3分)
- 回应观众提问
- 互动问答
- 抽奖活动执行
- 调动直播间氛围
⑤促销推动环节(0.3分)
- 强调组合优惠
- 满额包邮等促销政策
- 催单话术
⑥结束语环节(0.25分)
- 总结本场直播要点
- 感谢观众支持
- 最后提醒下单福利
⑦额外加分环节(0.2分)
- 预告下次直播
- 引导加粉丝群
- 其他创意环节
━━━━━━━━━━━━━━━━━━━━━━
六、话术内容质量(3分)
6.1 语言流畅自然(0.8分)
使用口语化表达(0.3分)
语言自然流畅,不生硬(0.3分)
表达亲切易懂(如"宝宝们"、"亲们")(0.2分)
6.2 逻辑清晰(0.7分)
各环节衔接顺畅(0.3分)
逻辑连贯,层次分明(0.2分)
节奏合理(0.2分)
6.3 卖点讲解充分(0.8分)
详细讲解产品卖点(0.3分)
有说服力,有具体案例或数据(0.3分)
突出5%烟酰胺等核心成分和功效(0.2分)
6.4 互动设计合理(0.7分)
互动环节设计合理(0.3分)
能调动氛围(0.2分)
互动方式多样(0.2分)
━━━━━━━━━━━━━━━━━━━━━━
七、时长设置(1分)
话术设置时长:___分钟
评分标准:
设置为15分钟(1分)
━━━━━━━━━━━━━━━━━━━━━━
八、话术规范性(1分)
【违禁词检测】
发现的违禁词:___________
常见违禁词类型:
- 绝对化用语:最、第一、唯一、极致、顶级、完美等
- 夸大宣传:100%、必然、保证、绝对、立即见效等
- 医疗用语:治疗、疗效、药用、治愈、医治等
- 虚假宣传:国家级、世界级、最高级、最低价等
评分标准:
零违禁词(1分)
1-2个违禁词(0.5-0.7分)
3-4个违禁词(0.3-0.4分)
5个以上违禁词(0-0.2分)
其他规范检查:
无夸大宣传
符合平台规范
表述真实可信
【评分说明】
1. 卖点提炼是核心(3分),至少3个卖点,要具体、有说服力
2. 营销活动设计(3分),至少4个活动,类型要多样
3. 话术内容质量(3分),重点看语言、逻辑、卖点讲解、互动
4. 话术结构必须包含7个环节,缺少任何环节都会扣分
5. 零违禁词是基本要求,发现违禁词将严重扣分
【整体评价】
(请对选手话术整体质量进行1-2句总结性评价)`
}
export
const
generatePracticeRecordPrompt
=
(
data
:
any
)
=>
{
return
`请根据选手提交的内容进行评分(满分20分)
选手提交内容:
${
JSON
.
stringify
(
data
.
practice_records
[
0
])}
`
}
export
const
generateImprovementPlanPrompt
=
(
data
:
any
)
=>
{
return
`请根据选手提交的改进方案进行评分(满分10分):
选手提交的改进方案:
${
JSON
.
stringify
(
data
.
practice_records
[
0
]?.
improvement_plan
)}
评分标准:
-
必须提出至少
5
条改进措施
-
每条改进措施
2
分
-
必须包含:问题描述、改进目标、改进方法
`
}
export const generatePracticeRecord2Prompt = (data: any) => {
return `
请根据选手提交的二次直播演练内容进行评分(满分
15
分)
选手提交内容:
$
{
JSON
.
stringify
(
data
.
practice_records
[
1
])}
`
}
export const generateReportPrompt = (data: any) => {
return `
请根据选手提交的直播总结报告进行评分(满分
15
分)
选手提交内容:
$
{
JSON
.
stringify
(
data
.
reports
)}
`
}
export const generatePrompt = (data: any) => {
return `
$
{
generateCommodityTypePrompt
(
data
)}
$
{
generateCommodityAttrsPrompt
(
data
)}
$
{
generateCommoditiesPrompt
(
data
)}
$
{
generateSpeechPrompt
(
data
)}
$
{
generatePracticeRecordPrompt
(
data
)}
$
{
generateImprovementPlanPrompt
(
data
)}
$
{
generateReportPrompt
(
data
)}
EXAMPLE
JSON
OUTPUT
:
{
"commodity_type"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"commodity_attr"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"commodity"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"speech"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"practice_record1"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"improvement_plan"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"practice_record2"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
"report"
:
{
"score"
:
5
,
"comment"
:
"这是评语"
},
}
`
}
src/modules/live/score/views/Index.vue
浏览文件 @
a215af9e
...
...
@@ -28,6 +28,7 @@ const listOptions = computed(() => {
],
columns
:
[
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'ID'
,
prop
:
'id'
},
{
label
:
'姓名'
,
prop
:
'student_name'
},
{
label
:
'专业'
,
prop
:
'specialty_name'
},
{
label
:
'班级'
,
prop
:
'class_name'
},
...
...
src/modules/live/score/views/View.vue
浏览文件 @
a215af9e
...
...
@@ -13,11 +13,15 @@ import {
import
ScoreCard
from
'../components/ScoreCard.vue'
import
ScoreCardLive
from
'../components/ScoreCardLive.vue'
import
Preview
from
'@/components/Preview.vue'
import
{
ElMessageBox
}
from
'element-plus'
import
{
ElMessageBox
,
ElMessage
}
from
'element-plus'
import
{
useChat
}
from
'@ezijing/ai-vue'
import
{
generatePrompt
}
from
'../prompt'
const
route
=
useRoute
()
const
id
=
route
.
query
.
id
const
{
isLoading
,
generateText
}
=
useChat
({
provider
:
'volcano'
})
const
statusList
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
detail
=
ref
(
null
)
...
...
@@ -100,6 +104,10 @@ const productList = computed(() => {
return
detail
.
value
.
live_data
?.
commodities
?.
map
((
item
)
=>
{
try
{
item
.
info
=
JSON
.
parse
(
item
.
info
)
item
.
info
.
delivery_mode_name
=
getNameByValue
(
item
.
info
.
delivery_mode
,
deliveryMode
)
item
.
info
.
delivery_time_name
=
getNameByValue
(
item
.
info
.
delivery_time
,
deliveryTime
)
item
.
info
.
shipping_template_name
=
getNameByValue
(
item
.
info
.
shipping_template
,
shippingTemplate
)
item
.
info
.
after_sales_policy_name
=
getNameByValue
(
item
.
info
.
after_sales_policy
,
afterSalesPolicy
)
item
.
live_commodity_attrs
=
JSON
.
parse
(
item
.
live_commodity_attrs
)
item
.
picture_34_addreses
=
JSON
.
parse
(
item
.
picture_34_addreses
)
item
.
picture_addreses
=
JSON
.
parse
(
item
.
picture_addreses
)
...
...
@@ -120,34 +128,10 @@ const productTableOptions = {
{
label
:
'商品标题'
,
prop
:
'title'
},
{
label
:
'所属商品品类'
,
prop
:
'live_commodity_type_full_name'
},
{
label
:
'参考价(¥)'
,
prop
:
'info.reference_price'
},
{
label
:
'发货模式'
,
prop
:
'delivery_mode'
,
computed
({
row
})
{
return
getNameByValue
(
row
.
info
.
delivery_mode
,
deliveryMode
)
},
},
{
label
:
'发货时效'
,
prop
:
'delivery_time'
,
computed
({
row
})
{
return
getNameByValue
(
row
.
info
.
delivery_time
,
deliveryTime
)
},
},
{
label
:
'运费模板'
,
prop
:
'shipping_template'
,
computed
({
row
})
{
return
getNameByValue
(
row
.
info
.
shipping_template
,
shippingTemplate
)
},
},
{
label
:
'售后政策'
,
prop
:
'after_sales_policy'
,
computed
({
row
})
{
return
getNameByValue
(
row
.
info
.
after_sales_policy
,
afterSalesPolicy
)
},
},
{
label
:
'发货模式'
,
prop
:
'info.delivery_mode_name'
},
{
label
:
'发货时效'
,
prop
:
'info.delivery_time_name'
},
{
label
:
'运费模板'
,
prop
:
'info.shipping_template_name'
},
{
label
:
'售后政策'
,
prop
:
'info.after_sales_policy_name'
},
],
}
// 商品规格
...
...
@@ -197,8 +181,24 @@ const talkTableOptions = {
}
const
activeTab
=
ref
(
1
)
const
handleAIScore
=
()
=>
{
const
handleAIScore
=
async
()
=>
{
console
.
log
(
'AI一键评分'
)
const
result
=
await
generateText
({
prompt
:
generatePrompt
(
detail
.
value
.
live_data
),
response_format
:
{
type
:
'json_object'
},
})
try
{
const
parsed
=
JSON
.
parse
(
result
.
content
)
Object
.
assign
(
scoreDetails
,
parsed
)
commitScore
(
0
).
then
(()
=>
{
ElMessage
.
success
(
'保存成功'
)
})
}
catch
(
error
)
{
console
.
log
(
error
)
ElMessage
.
error
(
'评分失败'
)
return
}
console
.
log
(
result
.
content
)
}
const
handleSave
=
(
key
,
params
)
=>
{
...
...
@@ -207,6 +207,7 @@ const handleSave = (key, params) => {
ElMessage
.
success
(
'保存成功'
)
})
}
const
handleNext
=
()
=>
{
activeTab
.
value
++
}
...
...
@@ -242,7 +243,9 @@ const handlePublishScore = () => {
<el-form-item
label=
"状态"
>
{{
detail
.
status_name
}}
</el-form-item>
<el-form-item
label=
"提交时间"
>
{{
detail
.
commit_time
}}
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
:disabled=
"detail.status == '2'"
@
click=
"handleAIScore"
>
AI一键评分
</el-button>
<el-button
type=
"primary"
:disabled=
"detail.status == '2'"
:loading=
"isLoading"
@
click=
"handleAIScore"
>
AI一键评分
</el-button
>
<el-button
type=
"primary"
:disabled=
"detail.status == '2'"
@
click=
"handlePublishScore"
>
发布成绩
</el-button>
</el-form-item>
</el-form>
...
...
@@ -411,7 +414,7 @@ const handlePublishScore = () => {
@
save=
"handleSave('report', $event)"
@
next=
"handleNext"
>
<
template
v-if=
"detail.live_data.reports.length > 0"
>
<div
v-for=
"item in detail.live_data.reports"
:key=
"item.report_url"
>
<div
v-for=
"item in detail.live_data.reports"
:key=
"item.report_url"
style=
"height: 600px"
>
<Preview
:url=
"item.report_url"
/>
</div>
</
template
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论