feat: BossAi v2.0 UI/UX 重构 + 看板断点续接 + 多轮上下文
- 新增 web2/ 前端:任务卡看板、风险雷达、决策日志、我的团队、快捷指令 - ChatPanel 增强:风险卡置顶、案卡接入、起诉状向导、语音输入 - 事项看板:点击查看详情弹窗、断点续接(恢复历史对话+matterId) - 保密模式恢复:密码验证后重建内存 session,保留多轮上下文 - 多轮对话:ask/ask-stream/ask-analyze 注入 session 历史,AI 有上下文 - 追问优化:紧扣用户问题,不再偏离主题(社保问社保,工伤问工伤) - 对话区可滚动,输入区固定可见 - 状态机放宽:允许从任意非终态转到 pending_expert - session 存活检查端点,后端重启后自动重建 session - DB migration:风险推送表、案卡表 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
-- BossAi 2.0 UIUX 重构 — 数据库迁移脚本
|
||||
-- TASK-001: 案卡表 + sessions 扩展
|
||||
-- TASK-002: 专家关系表
|
||||
-- 幂等:可重复执行,已存在的对象跳过
|
||||
-- 运行:psql -d mcp -f migrations/001_bossai_v2.sql
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ============================================================
|
||||
-- TASK-001: 案卡(matters)表
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS matters (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code TEXT NOT NULL UNIQUE, -- 唯一业务代码 MTR_{YYYYMMDD}_{seq}
|
||||
user_phone TEXT NOT NULL, -- 所属老板(手机号,关联 users.phone)
|
||||
scene TEXT NOT NULL, -- legal / decision / life / emotion
|
||||
title TEXT NOT NULL, -- 案卡标题(AI 生成或用户命名)
|
||||
status TEXT NOT NULL DEFAULT 'new', -- new / asking_facts / pending_confirm / analyzing / pending_expert / closed
|
||||
session_id TEXT, -- 关联会话 sid(可空,旧会话无案卡)
|
||||
risk_level TEXT, -- 可空: green / amber / orange / red
|
||||
summary TEXT, -- 可空: AI 结论摘要
|
||||
closed_at TIMESTAMPTZ, -- 闭环时间
|
||||
execution_result TEXT, -- 可空: 顺利 / 受阻 / 未执行
|
||||
execution_note TEXT, -- 可空: 执行情况备注
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_matters_user_phone ON matters(user_phone);
|
||||
CREATE INDEX IF NOT EXISTS idx_matters_status ON matters(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_matters_user_status ON matters(user_phone, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_matters_created ON matters(created_at DESC);
|
||||
|
||||
-- 案卡状态流转合法性约束(通过 CHECK)
|
||||
ALTER TABLE matters DROP CONSTRAINT IF EXISTS chk_matters_status;
|
||||
ALTER TABLE matters ADD CONSTRAINT chk_matters_status CHECK (
|
||||
status IN ('new', 'asking_facts', 'pending_confirm', 'analyzing', 'pending_expert', 'closed')
|
||||
);
|
||||
|
||||
ALTER TABLE matters DROP CONSTRAINT IF EXISTS chk_matters_scene;
|
||||
ALTER TABLE matters ADD CONSTRAINT chk_matters_scene CHECK (
|
||||
scene IN ('legal', 'decision', 'life', 'emotion')
|
||||
);
|
||||
|
||||
ALTER TABLE matters DROP CONSTRAINT IF EXISTS chk_matters_risk;
|
||||
ALTER TABLE matters ADD CONSTRAINT chk_matters_risk CHECK (
|
||||
risk_level IS NULL OR risk_level IN ('green', 'amber', 'orange', 'red')
|
||||
);
|
||||
|
||||
-- sessions 表扩展:关联案卡(若 sessions 表存在)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.tables WHERE table_name = 'sessions'
|
||||
) AND NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'sessions' AND column_name = 'matter_id'
|
||||
) THEN
|
||||
ALTER TABLE sessions ADD COLUMN matter_id INTEGER REFERENCES matters(id);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_matter ON sessions(matter_id);
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- chat_messages 表扩展:关联案卡(用于无 sessions 表时通过消息关联)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'chat_messages' AND column_name = 'matter_id'
|
||||
) THEN
|
||||
ALTER TABLE chat_messages ADD COLUMN matter_id INTEGER REFERENCES matters(id);
|
||||
CREATE INDEX IF NOT EXISTS idx_chat_messages_matter ON chat_messages(matter_id);
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- ============================================================
|
||||
-- TASK-002: 专家关系(expert_relations)表
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS expert_relations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_phone TEXT NOT NULL, -- 老板手机号
|
||||
expert_id INTEGER NOT NULL REFERENCES experts(id),
|
||||
consultation_count INTEGER NOT NULL DEFAULT 0, -- 咨询次数
|
||||
last_consulted_at TIMESTAMPTZ, -- 最近咨询时间
|
||||
last_topic TEXT, -- 最近咨询话题
|
||||
tags TEXT, -- 擅长领域标签(逗号分隔)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE(user_phone, expert_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_expert_relations_user ON expert_relations(user_phone);
|
||||
CREATE INDEX IF NOT EXISTS idx_expert_relations_expert ON expert_relations(expert_id);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ============================================================
|
||||
-- 回滚脚本(手动执行,需谨慎)
|
||||
-- 反向执行:psql -d mcp -f migrations/001_bossai_v2_rollback.sql
|
||||
-- ============================================================
|
||||
-- BEGIN;
|
||||
-- ALTER TABLE chat_messages DROP COLUMN IF EXISTS matter_id;
|
||||
-- ALTER TABLE sessions DROP COLUMN IF EXISTS matter_id;
|
||||
-- DROP TABLE IF EXISTS expert_relations;
|
||||
-- DROP TABLE IF EXISTS matters;
|
||||
-- COMMIT;
|
||||
@@ -0,0 +1,26 @@
|
||||
-- BossAi 2.0 回滚脚本 — 慎用,会删除案卡和专家关系数据
|
||||
-- 运行:psql -d mcp -f migrations/001_bossai_v2_rollback.sql
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- 移除 chat_messages 的 matter_id 列
|
||||
ALTER TABLE chat_messages DROP COLUMN IF EXISTS matter_id;
|
||||
|
||||
-- 移除 sessions 的 matter_id 列(若存在)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'sessions' AND column_name = 'matter_id'
|
||||
) THEN
|
||||
ALTER TABLE sessions DROP COLUMN matter_id;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- 删除专家关系表
|
||||
DROP TABLE IF EXISTS expert_relations;
|
||||
|
||||
-- 删除案卡表
|
||||
DROP TABLE IF EXISTS matters;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,32 @@
|
||||
-- BossAi 2.0 阶段三 — 风险推送表
|
||||
-- TASK-021: risk_alerts 表
|
||||
-- 幂等:可重复执行
|
||||
-- 运行:psql -d mcp -f migrations/002_risk_alerts.sql
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS risk_alerts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_phone TEXT NOT NULL, -- 推送对象(手机号)
|
||||
level TEXT NOT NULL, -- red / orange / blue
|
||||
title TEXT NOT NULL, -- 标题
|
||||
content TEXT NOT NULL, -- 详情
|
||||
source TEXT NOT NULL DEFAULT 'knowledge', -- knowledge / doc_scan / system
|
||||
related_matter_id INTEGER, -- 可空,关联案卡
|
||||
read_at TIMESTAMPTZ, -- 可空,标记已读时间
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_risk_alerts_user ON risk_alerts(user_phone);
|
||||
CREATE INDEX IF NOT EXISTS idx_risk_alerts_user_read ON risk_alerts(user_phone, read_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_risk_alerts_created ON risk_alerts(created_at DESC);
|
||||
|
||||
ALTER TABLE risk_alerts DROP CONSTRAINT IF EXISTS chk_risk_alerts_level;
|
||||
ALTER TABLE risk_alerts ADD CONSTRAINT chk_risk_alerts_level CHECK (
|
||||
level IN ('red', 'orange', 'blue')
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- 回滚:
|
||||
-- DROP TABLE IF EXISTS risk_alerts;
|
||||
Reference in New Issue
Block a user