feat: 新增本月经营态势弹窗+千问TTS语音播报

- 新增 BusinessReportDialog 组件,展示整体经营/成本费用/风险态势/利润机会四部分文字报告
- BossPage 标题栏新增「本月经营态势」按钮
- 后端新增 /api/tts 路由,调用千问 CosyVoice TTS API 合成语音
- 前端按句分段合成、逐句顺序播放,边播边合成
- 报告含待确认门店数量
This commit is contained in:
freedakgmail
2026-08-03 22:55:50 +08:00
parent c15ca07b7c
commit 6bc2f43da7
5 changed files with 329 additions and 2 deletions
+31 -2
View File
@@ -7,9 +7,10 @@ import { MetricCard } from '@/components/MetricCard'
import { LoadingSpinner } from '@/components/LoadingSpinner'
import { CollapsibleSection } from '@/components/CollapsibleSection'
import { formatCurrency, formatNumber, formatPercent } from '@/lib/utils'
import { Crown, TrendingDown, AlertTriangle, TrendingUp, Building2, Receipt, Target, ChevronDown } from 'lucide-react'
import { Crown, TrendingDown, AlertTriangle, TrendingUp, Building2, Receipt, Target, ChevronDown, Volume2 } from 'lucide-react'
import { MonthPicker } from '@/components/MonthPicker'
import { KPISection } from '@/components/KPISection'
import { BusinessReportDialog } from '@/components/BusinessReportDialog'
const RISK_COLORS: Record<string, string> = { '红色': '#ef4444', '黄色': '#eab308', '绿色': '#22c55e' }
@@ -67,6 +68,7 @@ function ProfitOppItem({ index, o, opp, pct, confColor }: { index: number; o: an
export function BossPage() {
const navigate = useNavigate()
const [month, setMonth] = useState('2026-04')
const [showReport, setShowReport] = useState(false)
const { data: overview, isLoading: odLoading } = useQuery({
queryKey: ['overview', month],
@@ -219,7 +221,16 @@ export function BossPage() {
<p className="mt-0.5 text-xs text-muted-foreground"> · {month}</p>
</div>
</div>
<MonthPicker month={month} onChange={setMonth} />
<div className="flex items-center gap-2">
<button
onClick={() => setShowReport(true)}
className="flex items-center gap-1.5 rounded-md border border-blue-200 bg-blue-50 px-3 py-1.5 text-xs font-medium text-blue-600 transition hover:bg-blue-100"
>
<Volume2 className="h-4 w-4" />
</button>
<MonthPicker month={month} onChange={setMonth} />
</div>
</div>
{/* ① 核心经营指标 */}
@@ -516,6 +527,24 @@ export function BossPage() {
</LineChart>
</ResponsiveContainer>
</CollapsibleSection>
{/* 本月经营态势弹窗 */}
<BusinessReportDialog
open={showReport}
onClose={() => setShowReport(false)}
data={{
month,
overview: od,
expense: ex,
waterfall: wf,
riskRows,
priorityRows,
costOverview: costOv,
profitOpp,
totalOpportunity: totalOpportunity,
trendReceived,
}}
/>
</div>
)
}