feat: BossAi 老板AI助手初始版本

包含功能:
- 法务参谋/经营决策/生活助理/情绪中心四大AI对话模块
- 专家咨询系统(用户选定→专家确认→咨询→回复→评价)
- 角色登录(用户/专家/管理员)+ ProtectedRoute 权限控制
- 管理后台(用户管理/专家管理/AI使用统计/专家活跃度)
- 专家工作台(待确认服务/待回复咨询/已回复咨询/服务中用户)
- 服务关系取消(用户和专家均可取消,需自己确认)
- 全页面移动端响应式适配
- 知识库RAG检索
- 对话历史(普通/保密模式)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
selfrelease
2026-08-29 23:57:26 +08:00
co-authored by Devin
commit 5c21e8fcd0
101 changed files with 25273 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
import { useState } from 'react'
import { PageLayout } from '@/components/common/PageLayout'
import { ChatPanel } from '@/components/common/ChatPanel'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Lightbulb, Scale, TrendingUp, Wallet, Store, Handshake, Tag, UserPlus, Repeat } from 'lucide-react'
import { cn } from '@/lib/utils'
const FRAMEWORK = [
{ icon: TrendingUp, title: '预期收益', desc: '各方案的收益估算与时间线' },
{ icon: Scale, title: '主要风险', desc: '每个方案的核心风险点' },
{ icon: Wallet, title: '现金流影响', desc: '对短期和长期现金流的冲击' },
{ icon: Lightbulb, title: '推荐程度', desc: '综合评估后的推荐等级' },
]
/** 决策话题:每个话题对应不同的示例问题 */
const TOPICS = [
{
icon: Store,
title: '扩张收缩',
desc: '开店、关店、业务线调整',
samples: [
'现在适合扩张开第二家店吗?',
'要不要关闭亏损的业务线?',
'新业务线该自营还是加盟?',
'应该先扩张还是先巩固现有市场?',
],
},
{
icon: Handshake,
title: '项目承接',
desc: '大单、长期合同、付款条件',
samples: [
'是否应该接一个付款周期 90 天的大单?',
'长期框架合同要不要签?',
'预付款比例低的项目能接吗?',
'客户要求独家合作,利弊怎么权衡?',
],
},
{
icon: Tag,
title: '定价策略',
desc: '降价、涨价、促销',
samples: [
'该不该降价 15% 抢竞品的客户?',
'产品涨价 10% 会流失多少客户?',
'要不要做满减促销活动?',
'新产品定价应该走高端还是性价比?',
],
},
{
icon: UserPlus,
title: '招人裁员',
desc: '关键岗位、团队扩张、减员',
samples: [
'应该招一个销售总监吗?',
'要不要招应届生自己培养?',
'团队人效低,该裁谁?',
'核心员工被挖,要不要加薪留人?',
],
},
{
icon: Wallet,
title: '融资合伙',
desc: '投资、入股、融资',
samples: [
'要不要接受天使投资?',
'合伙人要退股,怎么谈条件?',
'朋友要入股,股权怎么分?',
'银行贷款还是股权融资更合适?',
],
},
{
icon: Repeat,
title: '转型外包',
desc: '业务转型、外包、合作',
samples: [
'传统业务要不要转型线上?',
'非核心业务外包还是自己做?',
'要不要和同行做联合采购?',
'代工还是自建生产线?',
],
},
]
/** 经营决策助手:情景推演、方案对比、收益/风险/现金流/推荐程度 */
export function Decisions() {
const [selectedTopic, setSelectedTopic] = useState(0)
return (
<PageLayout
title="经营决策助手"
description="项目承接、扩张收缩、招人、降价、业务线调整、融资合伙。情景推演,把利弊讲透。"
>
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-base">决策推演框架</CardTitle>
</CardHeader>
<CardContent>
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
{FRAMEWORK.map((f) => (
<div key={f.title} className="rounded-md border p-3">
<f.icon className="mb-2 h-5 w-5 text-primary" aria-hidden />
<p className="text-sm font-medium">{f.title}</p>
<p className="mt-1 text-xs text-muted-foreground">{f.desc}</p>
</div>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-base">决策话题</CardTitle>
</CardHeader>
<CardContent>
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
{TOPICS.map((t, i) => (
<button
key={t.title}
onClick={() => setSelectedTopic(i)}
className={cn(
'flex items-start gap-3 rounded-md border p-3 text-left transition-colors',
selectedTopic === i
? 'border-primary bg-primary/5 ring-1 ring-primary'
: 'border-input hover:bg-accent',
)}
>
<t.icon className="mt-0.5 h-5 w-5 shrink-0 text-primary" aria-hidden />
<div>
<p className="text-sm font-medium">{t.title}</p>
<p className="mt-0.5 text-xs text-muted-foreground">{t.desc}</p>
</div>
</button>
))}
</div>
</CardContent>
</Card>
<ChatPanel
scene="decision"
samples={TOPICS[selectedTopic].samples}
topic={TOPICS[selectedTopic].title}
defaultMode="normal"
placeholder={`描述你的${TOPICS[selectedTopic].title}问题…`}
showRiskCard={false}
enableUpload={false}
/>
<p className="text-center text-xs text-muted-foreground">
AI 提供情景推演和利弊分析,最终决策由老板做出。
</p>
</PageLayout>
)
}