agent_9art/frontend/sidebar/src/components/ScriptRecommend.tsx
jiao 5f44136c85 feat(05-06): Phase 5-6 - 前端 + 管理后台 + 部署配置
- sidebar H5: React18+TypeScript+Vite+AntDesignMobile, 学员画像/话术推荐/一键发送
- admin后台: React18+AntDesign, 登录/数据看板/话术库管理CRUD
- kb-admin-service: 话术CRUD API、分页查询
- analytics-service: 数据统计Dashboard API
- 所有服务的Dockerfile + nginx.conf + 完整docker-compose编排
2026-05-12 18:12:20 +08:00

95 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState } from 'react'
import { Button, Toast, SpinLoading } from 'antd-mobile'
import type { Recommendation } from '../types'
export default function ScriptRecommend() {
const [scripts, setScripts] = useState<Recommendation[]>([])
const [loading, setLoading] = useState(false)
useEffect(() => {
loadRecommendations()
}, [])
const loadRecommendations = async () => {
setLoading(true)
try {
// TODO: 调用真实API
// const res = await fetch('/api/v1/recommend/get?sessionId=xxx&...')
// const data = await res.json()
// 模拟数据
setScripts([
{
utteranceId: 'UTT-S03-001',
title: '推荐3D场景UE地编就业班(零基础)',
content: '根据您的情况,我强烈推荐我们的【3D场景UE地编就业班】!\n\n为什么适合您:\n✅ 零基础入学:从软件操作开始教,无需任何基础\n✅ 六大模块系统学习\n✅ 5个月培训+2个月企业实训\n\n就业数据:往期学员平均薪资12-18K,就业推荐率95%+',
successRate: 0.72,
source: '规则匹配'
},
{
utteranceId: 'UTT-S04-003',
title: '强调实战教学模式',
content: '我们的教学模式是业内独一无二的"5+2"模式:\n\n📚 5个月技能培训 + 2个月企业实训\n\n这意味着什么?\n✅ 毕业时您已经有真实项目经验\n✅ 实训期间进入合作企业,表现优秀可直接留用\n✅ 500+合作企业就业推荐网络',
successRate: 0.74,
source: '热门推荐'
}
])
} catch (e) {
Toast.show({ content: '加载失败', icon: 'fail' })
} finally {
setLoading(false)
}
}
const handleSend = (script: Recommendation) => {
// 调用企微JS-SDK发送消息
if (typeof (window as any).wx !== 'undefined') {
(window as any).wx.invoke('sendChatMessage', {
msgtype: 'text',
text: { content: script.content }
}, (res: any) => {
if (res.err_msg === 'sendChatMessage:ok') {
Toast.show({ content: '发送成功', icon: 'success' })
} else {
Toast.show({ content: '发送失败: ' + res.err_msg, icon: 'fail' })
}
})
} else {
// 浏览器调试环境,复制到剪贴板
navigator.clipboard.writeText(script.content)
Toast.show({ content: '已复制到剪贴板', icon: 'success' })
}
}
if (loading) {
return (
<div style={{ padding: 40, textAlign: 'center' }}>
<SpinLoading />
</div>
)
}
return (
<div>
{scripts.map(script => (
<div key={script.utteranceId} className="script-card">
<div className="script-title">{script.title}</div>
<div className="script-content">{script.content}</div>
<div className="script-meta">
<span>成功率: {(script.successRate * 100).toFixed(0)}%</span>
<span>来源: {script.source}</span>
</div>
<div className="script-actions">
<Button color="primary" size="small" onClick={() => handleSend(script)}>
一键发送
</Button>
<Button size="small" fill="outline" onClick={() => navigator.clipboard.writeText(script.content)}>
复制
</Button>
</div>
</div>
))}
</div>
)
}