|
|
4 dienas atpakaļ | |
|---|---|---|
| build | 4 dienas atpakaļ | |
| public | 4 dienas atpakaļ | |
| src | 4 dienas atpakaļ | |
| .editorconfig | 4 dienas atpakaļ | |
| .env.development | 4 dienas atpakaļ | |
| .env.production | 4 dienas atpakaļ | |
| .env.qingpu | 4 dienas atpakaļ | |
| .env.test | 4 dienas atpakaļ | |
| .eslintignore | 4 dienas atpakaļ | |
| .eslintrc.js | 4 dienas atpakaļ | |
| .gitignore | 4 dienas atpakaļ | |
| .prettierrc.cjs | 4 dienas atpakaļ | |
| README.md | 4 dienas atpakaļ | |
| index.html | 4 dienas atpakaļ | |
| jest.config.js | 4 dienas atpakaļ | |
| package-lock.json | 4 dienas atpakaļ | |
| package.json | 4 dienas atpakaļ | |
| redirect.html | 4 dienas atpakaļ | |
| tsconfig.json | 4 dienas atpakaļ | |
| tsconfig.node.json | 4 dienas atpakaļ | |
| vite.config.ts | 4 dienas atpakaļ |
面向青浦区企业的政策匹配与办事指引智能助手前端。用户用自然语言提问,助手检索政策知识库, 以「开场概述 + 政策卡片 + 综合说明 + 参考资料」的形式给出有原文依据的回答;涉及具体企业时, 会先让用户确认公司主体,再结合工商信息给出针对性判断。
| 能力 | 说明 |
|---|---|
| AI 对话 | 自然语言问答,流式返回;支持普通咨询、政策匹配、办事指引 |
| 政策卡片 | 按匹配度列出政策/服务事项,含支持对象、支持方式与标准、申报条件、原文引用 |
| 政策详情 | 卡片可展开详情,含条件核验、匹配依据、原文引用 |
| 参考资料 | 回答附引用来源,可展开查看来源机构、更新时间与介绍 |
| 公司补问 | 需要企业事实时,引导用户补充/确认公司主体,支持候选选择 |
| 语音输入 | 语音识别转文字后发送(ASR) |
<script setup>)+ TypeScript + Vite 5unplugin-vue-components 按需自动引入)useBusinessAssistantChat 组合式函数内,
会话与消息持久化到 localStorage@microsoft/fetch-event-source(旧协议,保留未用)与原生 fetch + ReadableStream(现行)marked;3D/语音:Three.js、alloyfinger
(Three.js 用于粒子背景与语音识别,项目内没有 3D 虚拟人渲染)当前使用接口 POST /api/chat(SSE)。三条最容易踩的规则:
{thread_id, question} 两个字段,多一个返回 422。
旧协议的 transmission.files / file_pos 发不出去(这是"文件上传"功能待定的原因)。src/components/api-chat-coordinator.ts 是协议适配层,
把 SSE 事件翻译成既有渲染组件能识别的内容标记:
<scope> / <!-- POLICY_TABLE --> / <ref_links> / <question-cards>。
渲染层(BusinessRecord / PolicyMatch / QuestionCard / ScopeContent)不需要感知新协议。kind + status 字段决定,
而不是拿 input_help 的中文措辞做正则——后端改一个字判定就会失效。npm install
npm run dev # 开发服务器 → https://localhost:8083
npm run build # 生产构建(提交前必过)
npm run build:test # 测试环境构建
npm run build:qingpu # 青浦环境构建 + 打包 zip
npm run test # jest(可选)
开发环境注意:
/chat-api → http://192.168.2.23:8000(见 vite.config.ts)。
代理由服务端发起,因此局域网同事访问也不会有混合内容或跨域问题| 变量 | 用途 |
|---|---|
VITE_API |
主业务 API 网关 |
VITE_CHAT_API |
对话接口。兼容两种写法:服务前缀(/chat-api、http://host:8000)会自动追加 /api/chat;已是完整地址则原样使用 |
VITE_MODEL_SERVER |
模型服务 |
VITE_ASR / VITE_STREAM_SERVER |
语音识别 / 流媒体 |
src/
├── components/
│ ├── Chat/ 消息渲染、政策卡片、补问问卷等
│ ├── Common/ 通用组件(MediaViewer、ScrollList、Toast…)
│ ├── business-assistant/ 对话编排(useBusinessAssistantChat、上传、滚动等)
│ ├── api-chat-coordinator.ts ★ 协议适配层(现行)
│ └── stream-message-coordinator.ts 旧协议实现(保留未用,勿改)
├── network/api/ 接口封装(chat-sessions、enterprise、assistant-statistics、card)
├── types/ TypeScript 类型定义
├── utils/ 工具(runtime-config、stream-xml-filter、scope-record-rows…)
└── three-libs/asr/ 语音识别
本机另有
docs/reference/(接口契约与参考资料)、harness/(开发工作流文件)、CLAUDE.md/agents.md(agent 指令)。这些按.gitignore约定不入库, 缺失属正常。
后续新增改动,参考「华新镇产权单位和企业信息采集小程序」20260909 版本的工程实践。 该版本做了如下升级,可作为本仓库后续重构的对照基准:
vue-cli-service)+ Babel 迁移到 Vitevue-tsc 类型检查core-js / babel 相关依赖| 目录 | 说明 |
|---|---|
api |
后端接口封装(auth、content) |
composables |
可复用逻辑(表单、草稿、提示、滚动定位) |
constants |
集中管理 API 基地址、栏目 id、模型 id 等常量 |
layouts |
页面框架布局(TabBarLayout) |
stores |
Pinia 状态管理 |
styles |
抽离的全局样式(style.css、form.css) |
types |
TypeScript 类型定义(property、enterprise 等) |
utils |
通用工具(request、crypto、format、validators) |
auth store 统一维护登录态(token / user)passwordTabBarLayout 作为主框架,home / property / enterprise / myrecord 改为嵌套子路由requiresAuth)未登录时跳转登录页并携带 redirect视图只保留页面骨架,表单逻辑抽离为 composable + 子组件:
EnterprisePage 由 2586 行精简至 333 行,逻辑抽离到 useEnterpriseForm,
拆出 LocationEditor、YearlyMoneyList 组件PropertyPage 由 2144 行精简至 288 行,逻辑抽离到 usePropertyForm,
拆出 BuildingCard、FloorCard、OperatorList 组件新增 FormField、RadioGroup、CheckboxGroup、SearchSelect、PageHeader、SuccessToast 等通用组件。
| composable | 作用 |
|---|---|
useDraft |
进入「查看」前保存草稿快照、退出时还原 |
useSuccessToast |
统一的成功提示 |
useScrollToError |
校验失败时滚动定位到错误项 |
utils/request 统一 axios 实例(内容平台基地址、urlencoded、请求拦截自动携带 Token)api/auth、api/content 统一封装登录与内容平台的增删改查对照本仓库时的注意:本项目是单模块 Vue 应用,且目前没有引入任何状态管理库 (对话状态在
useBusinessAssistantChat里)。上文的分层与 Pinia 改造适用于多页面小程序形态, 本项目是否需要照搬,应按实际规模判断,不要为了对齐而引入用不上的依赖。
/api/chatthread_id 复用同一会话窗口Content-Type: application/json| 参数 | 类型 | 说明 |
|---|---|---|
thread_id |
string | 会话窗口 ID,复用同一 ID 即接续上下文 |
question |
string | 用户本轮输入。只能是这两个字段,多余字段返回 422 |
text/event-stream,命名事件流
accepted → progress… → answer → source… → item… → summary → result → done
(补问流程为 … → interrupt → result → done(status=needs_input)){thread_id, request_id, data}answer.text 与 result.response 内容相同,只能展示一次(result 是快照)补问用 kind + status 描述,四种情况:
| kind | status | 含义 | 前端形态 |
|---|---|---|---|
company_selection |
found |
有候选待选择 | 候选列表 + 查看更多 / 取消公司查询 |
company_need |
not_found |
未找到候选,需补充信息 | 上方常驻输入框 + 跳过公司查询 |
company_need |
failed |
查询服务失败 | 上方常驻输入框 + 跳过公司查询(文案须说明是失败) |
company_need |
无 status |
初次询问是否需要公司信息 | 上方常驻输入框 + 不需要公司信息 |
空候选与查询失败必须分别展示,不能把失败说成"查无公司"。
VITE_CHAT_API/chat-api、http://host:8000)会自动追加 /api/chat;
已是完整接口地址则原样使用/chat-api(走 vite 同源代理,见 vite.config.ts)status 字段判定形态(found / not_found / failed / 无 status),
替掉原先靠"候选数是否为 0"和 input_help 文案正则的猜测式判断
failed(查询服务失败)此前会落进 not_found 分支,文案被填成"未查询到匹配的公司",
等于把失败说成查无公司,已改为独立分支并说明失败原因status(初次询问是否需要公司信息)此前给"跳过公司查询",改为"不需要公司信息"/skip 改为发送选项文本「跳过公司查询」CLAUDE.md 中与仓库实际不符的描述
(端口、状态管理、不存在的文件与目录等)<scope>、<!-- POLICY_TABLE -->、
<ref_links> 等原始标记一起复制出来priority.rank 排序harness/ 开发工作流文件与 docs/reference/ 接口参考POST /api/chat(SSE)
src/components/api-chat-coordinator.ts,把 SSE 事件翻译成既有渲染组件
可识别的内容标记,渲染层无需感知新协议{thread_id, question};answer 与 result.response 只展示一次;
未收到 done/error 即断流时按连接中断处理,不自动重试src/components/stream-message-coordinator.ts 保留未用VITE_CHAT_API,新增 dev 代理 /chat-api → http://192.168.2.23:8000thread_busy → 该问题还在处理中)变更记录见飞书文档:https://awbm.feishu.cn/docx/O2mVdW5q3oqhLGxzEdbcniIKnYb