diff --git a/.gitignore b/.gitignore index acee5b2..e6a909f 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,8 @@ logs/ # ======================== tmp/ .cache/ +.tsbuild/ +*.tsbuildinfo *.tmp *.swp *~ diff --git a/docs/upgrade-plans/2026-05-11-ui-change-small-version-plan.md b/docs/upgrade-plans/2026-05-11-ui-change-small-version-plan.md new file mode 100644 index 0000000..9856d97 --- /dev/null +++ b/docs/upgrade-plans/2026-05-11-ui-change-small-version-plan.md @@ -0,0 +1,369 @@ +# SHBL-ERP CRM 小版本升级审查与执行计划 + +生成日期: 2026-05-11 +当前分支: `ui-change` +适用范围: 下一个小版本迭代,重点是 UI 改进、测试流程补强、安全加固,以及为后续去除 Dify 依赖做架构准备。 + +## 1. 目标与边界 + +本轮小版本不建议直接替换 Dify,也不建议一次性重构所有业务页面。当前系统已经存在可运行的业务骨架,下一步更适合先把基础质量稳住,再做可见的 UI 改进。 + +本轮目标: + +- 建立更可信的测试与 CI 流程,避免失败被吞掉。 +- 修复 AI 回调和工具接口中明显的鉴权风险。 +- 建立前端设计基座,让后续页面改版有统一标准。 +- 优先重做首页、客户、订单、财务等高频页面的视觉和交互体验。 +- 抽出 AI Provider 适配层,让 Dify 仍可用,同时为后续 OpenAI 标准接口迁移铺路。 + +本轮不做: + +- 不立即删除 Dify。 +- 不做数据库大迁移。 +- 不大规模改动所有业务逻辑。 +- 不把旧页面全部一次性重写。 + +### UI 参考包审查结论: Aura Finance CRM + +参考资产: `stitch_aura_finance_crm.zip`。该包包含 `code.html`、`DESIGN.md`、`screen.png` 三个文件,可作为小版本 UI 改进的视觉方向参考。 + +结论: 该方案部分符合本系统改版目标,适合作为“清爽、高端、低噪音、数据表格优先”的视觉标杆,但不能直接作为生产实现照搬。 + +可采纳内容: + +- 浅色工作台背景、低饱和蓝色主色、深色文字和弱边框的整体基调。 +- 左侧导航、顶部搜索、页面标题、主操作按钮、表格卡片的页面组织方式。 +- 状态标签、金额右对齐、客户名称加辅助信息的表格扫描体验。 +- `DESIGN.md` 中的色彩、间距、字号、阴影、表格密度等 token 思路。 +- `screen.png` 中客户列表页的干净层级,可作为客户、订单、财务列表页的首批改版参考。 + +必须调整内容: + +- 当前项目是 Vue 3、Vite、Element Plus 技术栈,不能引入 Tailwind CDN 作为生产依赖,也不要直接复制 `code.html`。 +- 不能依赖 Google Fonts、Material Symbols、`lh3.googleusercontent.com` 等远程字体和图片资源;图标优先使用 `@element-plus/icons-vue`,字体使用本地系统字体或经批准的本地字体方案。 +- 参考包是英文静态样张,实际页面必须使用 SHBL CRM 的中文业务文案、现有路由和真实字段。 +- 样张大量使用 `h-screen`、固定侧边栏、固定顶部栏和 12 列表格,必须补充窄屏笔记本和低分辨率下的响应式策略。 +- `DESIGN.md` 建议 16px 到 20px 容器圆角,和本项目业务系统的紧凑风格略有冲突;小版本默认收敛为 8px 主圆角,少量重点容器最高 12px。 +- Glassmorphism 和大阴影只能轻量使用,避免影响性能、可读性和长时间办公体验。 +- 表格必须补齐真实系统需要的加载态、空态、错误态、分页、批量选择、权限控制和操作列,而不是只保留静态展示。 + +## 2. 当前主要问题 + +| 优先级 | 模块 | 现象与证据 | 风险 | 建议 | +| --- | --- | --- | --- | --- | +| P0 | AI 回调安全 | `server/app/api/dify_tools.py` 中 Authorization 目前可选,且注释仍提示生产需要补 Dify secret;`ai_coaching.py`、`reports.py`、`customers.py` 中多个 Dify 回调可以写入业务数据。 | 外部请求可能伪造回调,写入客户画像、AI 辅导、报告草稿等数据。 | 所有写入型回调必须增加共享密钥、签名校验或内部网关校验,并记录调用来源。 | +| P0 | CI 可信度 | `.gitea/workflows/test.yml` 中后端测试命令使用 `pytest ... || echo ...`,测试失败仍可能继续通过;workflow 触发分支未覆盖当前 `ui-change`。 | 真实测试失败不会阻断合并,后续 UI 或接口调整风险放大。 | 去掉吞错逻辑,明确测试失败即失败;补充分支触发规则。 | +| P1 | Dify 耦合 | `chat.py` 直接调用 Dify chat/workflow 接口,`intent_service.py` 中路由目标硬编码为 `dify_agent`,同时前端 action card、persona、report 等流程依赖 Dify 回调。 | 后续替换 OpenAI 时会牵动前后端多个入口,迁移成本高。 | 先抽 `AIProvider`、`WorkflowRunner`、`ToolAdapter`,保持 Dify 为默认实现。 | +| P1 | 前端视觉与体验 | `frontend/src/views` 中大量页面使用内联样式,表格高度多处使用固定 `calc(100vh - ...)`,首页和业务页缺少统一布局、间距、色彩和响应式策略。 | 页面观感不统一,窄屏体验差,后续每个页面都要重复修样式。 | 先建立设计变量、页面壳、工具栏、数据表格容器、KPI 卡片等基础组件。 | +| P1 | 构建环境不一致 | CI 使用 Node 20,`Dockerfile.frontend` 使用 Node 18;Docker 使用 `npm install`,CI 使用 `npm ci`。 | 本地、CI、Docker 构建结果可能不一致。 | 统一 Node 版本和依赖安装方式,优先使用锁文件驱动的 `npm ci`。 | +| P2 | 配置默认值偏生产风险 | `server/app/core/config.py` 默认 JWT secret、默认 DEBUG 为 true,并写有内部 Ollama 地址;`server/app/main.py` 中 CORS 地址固定。 | 新环境部署时容易沿用不安全默认配置。 | 敏感配置必须由环境变量提供,生产缺失时启动失败。 | +| P2 | 项目入口历史包袱 | 根目录存在 `app.py`,同时有 `backend/` 和 `server/`,当前 Docker 与 CI 主要使用 `server/`。 | 新开发者容易误判真实后端入口,维护成本上升。 | 文档明确活跃入口;后续小步清理或归档旧入口。 | + +## 3. 小版本迭代范围建议 + +建议把下一个小版本命名为 `v0.3.0-ui-foundation` 或 `v0.2.1-quality-ui`。如果希望强调 UI 改进,使用 `v0.3.0-ui-foundation` 更清晰。 + +推荐包含 5 条工作线: + +1. 安全与 CI 加固 +2. 前端设计基座 +3. 高频页面 UI 改进 +4. AI 调用适配层准备 +5. 测试、验收和发布流程 + +## 4. 分阶段执行计划 + +### 阶段 0: 基线确认 + +目标: 确认当前分支、依赖、构建、测试和页面现状,形成可比较基线。 + +任务: + +- 确认 `ui-change` 分支可正常拉取、提交和推送。 +- 分别执行后端基础检查、前端构建检查。 +- 记录当前首页、客户、订单、财务页面截图,作为 UI 改版对比材料。 +- 将 `stitch_aura_finance_crm.zip` 中的 `screen.png` 作为客户列表视觉参考,但以本项目业务字段和组件体系重新实现。 +- 明确当前部署入口以 `server/`、`frontend/`、`docker-compose.yml` 为准。 + +交付物: + +- 一组基线截图。 +- 一份当前测试结果记录。 +- 确认可复现的本地启动步骤。 + +### 阶段 1: 安全与 CI 加固 + +目标: 让明显风险先收敛,让自动化测试结果可信。 + +任务: + +- 修改 `.gitea/workflows/test.yml`,去掉后端测试失败后的吞错逻辑。 +- workflow 触发规则覆盖 `ui-change` 或后续约定的 feature 分支。 +- 统一前端 Node 版本,建议 Docker 与 CI 使用同一大版本。 +- Docker 前端构建改为基于锁文件的 `npm ci`。 +- 为 Dify 回调类接口增加鉴权策略: + - 请求头共享密钥。 + - 时间戳与签名。 + - 失败请求记录审计日志。 +- 生产环境中强制要求 `SECRET_KEY`、Dify secret、数据库连接等关键配置显式提供。 + +验收标准: + +- 后端测试失败时 CI 必须失败。 +- 前端构建失败时 CI 必须失败。 +- 未携带合法凭证的写入型 AI 回调返回 401 或 403。 +- 生产模式缺少关键 secret 时服务拒绝启动。 + +### 阶段 2: 前端设计基座 + +目标: 先统一 UI 语言,再改具体页面。 + +建议新增或梳理: + +- `frontend/src/styles/tokens.css`: 色彩、字号、间距、阴影、圆角、边框、状态色。 +- `frontend/src/styles/layout.css`: 页面宽度、内容区、响应式网格、表格区高度策略。 +- `frontend/src/components/PageShell.vue`: 页面标题、操作区、筛选区、主体区。 +- `frontend/src/components/DataTableShell.vue`: 表格外壳、加载态、空态、分页布局。 +- `frontend/src/components/KpiCard.vue`: 首页和统计页使用的统一指标卡。 +- `frontend/src/components/SectionHeader.vue`: 业务分区标题和辅助操作。 +- Element Plus 主题覆盖文件: 将 Aura 参考包的蓝色、浅色背景、状态色和输入框 focus 效果转译为 Element Plus 变量。 + +设计方向: + +- 以 Aura Finance CRM 样张为视觉参考,但保留 SHBL CRM 的中文业务系统属性。 +- 保持业务系统的安静、清晰、可扫描,不做营销页风格。 +- 降低深色大面积侧边栏的压迫感,调整为更现代的浅色或低饱和导航。 +- 表格、筛选、操作按钮保持密集但有秩序。 +- 页面内少用嵌套卡片,避免视觉碎片化。 +- 支持至少两档宽度: 桌面端和窄屏笔记本。 +- 主色优先参考 `#0066CC` 和 `#004E9F`,背景参考 `#F5F5F7`、`#F9F9FF`,文字参考深 slate;避免整站变成单一蓝色主题。 +- 主容器圆角以 8px 为默认,重点弹窗或浮层可放宽到 12px;不要使用大面积 16px 到 20px 圆角卡片堆叠。 + +验收标准: + +- 新页面不再依赖大量内联样式。 +- 高频页面共享同一组布局组件。 +- 主要按钮、表格、筛选区、状态标签风格一致。 +- 1366px、1440px、1920px 宽度下无明显遮挡和错位。 +- 不引入 Tailwind CDN、外部 Google 字体、远程样张图片或与当前 Vue/Element Plus 栈冲突的 UI 依赖。 + +### 阶段 3: 高频页面 UI 改进 + +建议顺序: + +1. 首页 Dashboard +2. 客户列表与客户详情 +3. 订单列表与订单详情 +4. 财务相关页面 +5. 产品与设置页面 + +Dashboard 改进方向: + +- 使用统一 KPI 卡片展示关键指标。 +- 将当前固定 4 列布局改为响应式网格。 +- 把趋势、提醒、待办和最近活动拆成清晰分区。 +- 减少装饰性元素,突出经营信息。 + +客户页面改进方向: + +- 客户列表优先参考 Aura 样张的结构: 左侧导航、顶部搜索、页面标题、筛选按钮、主操作按钮、表格卡片和底部分页。 +- 强化搜索、筛选、状态、负责人、最近跟进等字段的扫描效率。 +- 客户详情页采用信息区、联系人、跟进记录、AI 画像等分区。 +- AI 画像内容要有更新时间和来源提示。 +- 样张中的 `Customer Index`、`Leads`、`Total Spend` 等英文与金融字段必须映射为本项目真实中文字段,例如客户名称、客户类型、联系人、负责人、订单金额、最近跟进、状态和操作。 + +订单与财务页面改进方向: + +- 表格操作列更紧凑,金额、状态、日期字段更易读。 +- 固定高度表格改为更稳定的内容区布局。 +- 批量操作和导出入口统一放入工具栏。 + +验收标准: + +- 至少完成 Dashboard 和一个核心业务列表页的新版 UI。 +- 新旧页面交互流程保持兼容。 +- 表格分页、筛选、查看详情、创建或编辑入口可用。 +- 通过桌面和窄屏截图检查。 +- 客户列表新版截图需要与 Aura 参考图做并排验收: 允许业务字段不同,但层级、留白、表格扫描效率和按钮状态必须达到同一质量级别。 + +### 阶段 4: AI 适配层准备 + +目标: 不移除 Dify,但把未来替换成本降下来。 + +建议后端增加抽象: + +- `AIProvider`: 统一 chat、stream、structured output 的入口。 +- `WorkflowRunner`: 统一报告生成、客户画像、销售辅导等流程调用。 +- `ToolAdapter`: 统一 CRM 内部工具调用和 action card 生成。 +- `ConversationStore`: 保存会话 ID、provider、外部 conversation ID 的映射关系。 + +第一步实现: + +- `DifyProvider` 作为默认实现,保持现有行为。 +- `OpenAIProvider` 先提供最小可运行骨架,可通过环境变量关闭。 +- 前端 `FloatingChat` 的响应结构保持稳定,例如 `text`、`conversation_id`、`action_card`。 + +未来大版本迁移方向: + +- 使用 OpenAI Responses API 作为 chat 和工具编排入口。 +- 使用 OpenAI function calling 映射 CRM 工具能力。 +- 把 Dify workflow 的报告、画像、辅导流程迁移为内部 job 或后端 orchestrator。 +- RAG 或知识库能力可以评估 OpenAI file search、向量库或自建检索方案。 +- 保留 provider 切换能力,避免再次绑定到单一平台。 + +验收标准: + +- Dify 仍为默认 provider,现有聊天流程不回退。 +- 新增 provider 接口后,业务代码不再直接散落调用 Dify URL。 +- OpenAI provider 可以在测试环境完成最小 chat smoke test。 + +### 阶段 5: 验收、发布与回归 + +目标: 形成每次小版本都能复用的检查清单。 + +必须执行: + +```powershell +cd server +python -m py_compile app/main.py +python -m compileall app +python -m pytest tests/ -v --tb=short +``` + +```powershell +cd frontend +npm ci +npm run build +``` + +建议执行: + +```powershell +docker compose build +docker compose up -d +``` + +浏览器回归范围: + +- 登录页。 +- 首页 Dashboard。 +- 客户列表和详情。 +- 订单列表和详情。 +- 财务列表。 +- 悬浮 AI 聊天入口。 +- 文件导入模板下载。 +- 客户列表 Aura 风格改版页。 + +截图检查尺寸: + +- 1366 x 768 +- 1440 x 900 +- 1920 x 1080 +- 390 x 844,仅用于确认不会严重溢出,不作为完整移动端目标。 + +UI 参考对比: + +- 使用 `stitch_aura_finance_crm.zip` 中的 `screen.png` 作为目标风格参考。 +- 新版客户列表需要输出同尺寸或近似比例截图,检查导航、搜索、标题、表格、分页、状态标签和主按钮是否达到参考图的秩序感。 +- 若参考图与业务可用性冲突,优先满足业务效率和真实数据完整性。 + +## 5. 测试流程建议 + +### 后端测试 + +基础检查: + +```powershell +cd server +python -m py_compile app/main.py +python -m compileall app +``` + +单元与接口测试: + +```powershell +cd server +python -m pytest tests/ -v --tb=short +``` + +重点补测: + +- AI 回调鉴权失败场景。 +- AI 回调鉴权成功但 payload 异常场景。 +- 客户画像写入。 +- 报告草稿写入。 +- 导入模板下载。 +- 登录与 token 校验。 + +### 前端测试 + +基础检查: + +```powershell +cd frontend +npm ci +npm run build +``` + +建议补充: + +- 引入 Playwright smoke test,覆盖登录、首页、客户列表、订单列表、AI 聊天入口。 +- 对新版 Dashboard 和客户页保留截图,用于后续 UI 回归对比。 + +### 集成测试 + +建议通过 Docker Compose 做一次完整启动: + +```powershell +docker compose build +docker compose up -d +``` + +检查项: + +- 前端能访问后端 API。 +- CORS 配置符合当前环境。 +- 数据库连接正常。 +- AI provider 配置缺失时有明确错误提示。 +- 生产环境 secret 缺失时服务拒绝启动。 + +## 6. 建议拆分 PR + +建议按风险从小到大拆分: + +| PR | 名称 | 内容 | +| --- | --- | --- | +| 1 | `ci-test-hardening` | 修正 CI 吞错、统一 Node 版本、补充分支触发。 | +| 2 | `security-ai-callback-auth` | 为 Dify 回调和工具接口增加鉴权、审计日志和测试。 | +| 3 | `ui-foundation` | 增加设计变量、页面壳、通用表格容器和 KPI 卡片。 | +| 4 | `dashboard-refresh` | 重做首页 Dashboard,建立 UI 改版标杆。 | +| 5 | `customer-page-refresh` | 重做客户列表和详情的关键布局。 | +| 6 | `ai-provider-interface` | 抽出 AI provider 接口,Dify 作为默认实现,OpenAI provider 保留最小骨架。 | + +## 7. 完成定义 + +本小版本达到以下条件后可以进入发布候选: + +- CI 能真实反映后端测试和前端构建结果。 +- 所有写入型 AI 回调都有鉴权。 +- Docker 和 CI 的前端 Node 版本一致。 +- 至少 Dashboard 和一个核心业务页面完成新版 UI。 +- 新 UI 使用统一组件和样式变量。 +- Dify 仍可正常工作,同时后端已有 provider 抽象入口。 +- 后端测试、前端构建、Docker 构建通过。 +- 关键页面完成截图验收。 + +## 8. 推荐先做的第一批任务 + +第一周建议只做基础质量和 UI 基座,不急着改所有页面: + +1. 修 CI,让失败能失败。 +2. 修 AI 回调鉴权,先堵住 P0 风险。 +3. 统一 Node 和依赖安装流程。 +4. 建立 `tokens.css`、`PageShell.vue`、`DataTableShell.vue`、`KpiCard.vue`。 +5. 将 Aura Finance CRM 的视觉 token 转译为本项目 Element Plus 主题和基础 CSS 变量。 +6. 先重做客户列表页,验证 Aura 风格能否适配真实业务字段。 +7. 重做 Dashboard,形成后续页面参考样式。 +8. 写 3 到 5 个最小 Playwright smoke test。 + +这样做的收益是: 小版本能立刻提升安全性、可维护性和视觉一致性,同时不会把后续 OpenAI 迁移和当前 UI 改版强行绑成一个高风险大改。 diff --git a/frontend/e2e/customers.spec.ts b/frontend/e2e/customers.spec.ts index e6dd3b4..9981638 100644 --- a/frontend/e2e/customers.spec.ts +++ b/frontend/e2e/customers.spec.ts @@ -9,6 +9,13 @@ test.describe('客户管理', () => { await page.waitForLoadState('networkidle'); }); + test('新版客户页信息架构可见', async ({ page }) => { + await expect(page.getByTestId('customers-page')).toBeVisible({ timeout: 5000 }); + await expect(page.getByRole('heading', { name: '客户管理' })).toBeVisible(); + await expect(page.getByTestId('customers-summary')).toBeVisible(); + await expect(page.getByTestId('customers-table-card')).toBeVisible(); + }); + test('客户列表正确加载', async ({ page }) => { await expect(page.locator('.el-table').first()).toBeVisible({ timeout: 5000 }); await expect(page.getByRole('button', { name: '新增客户' })).toBeVisible(); diff --git a/frontend/src/App.vue b/frontend/src/App.vue index b6f7b27..dc62d20 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -5,21 +5,6 @@ */ - - - - - + + + diff --git a/frontend/src/components/DataTableShell.vue b/frontend/src/components/DataTableShell.vue new file mode 100644 index 0000000..6677894 --- /dev/null +++ b/frontend/src/components/DataTableShell.vue @@ -0,0 +1,79 @@ + + + + + + + {{ title }} + {{ description }} + + + + + + + + + + + + + + + + diff --git a/frontend/src/components/KpiCard.vue b/frontend/src/components/KpiCard.vue new file mode 100644 index 0000000..caa8058 --- /dev/null +++ b/frontend/src/components/KpiCard.vue @@ -0,0 +1,61 @@ + + + + + {{ label }} + {{ value }} + {{ helper }} + + + + diff --git a/frontend/src/components/PageShell.vue b/frontend/src/components/PageShell.vue new file mode 100644 index 0000000..c86787f --- /dev/null +++ b/frontend/src/components/PageShell.vue @@ -0,0 +1,115 @@ + + + + + + + SHBL CRM Workspace + {{ title }} + {{ description }} + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/layout/index.vue b/frontend/src/layout/index.vue index 70409ea..83c2f21 100644 --- a/frontend/src/layout/index.vue +++ b/frontend/src/layout/index.vue @@ -1,5 +1,5 @@ - - - - - - - + + + 刷新 + 导入客户 + 导出 + 新增客户 + + + + + + + + + + + + 客户索引 + 优先处理重点客户、活跃跟进和归档恢复,不再把关键信息埋在表格里。 + + + + + + + + - - - + + - - + + + + + 搜索 - - - 搜索 - 导入客户 - 导出 - 新增客户 - - + - - - - + + + + + + 当前页 {{ customerData.length }} 条 + + + + + + - {{ scope.row.name }} + + {{ (scope.row.name || '客').slice(0, 1) }} + + {{ scope.row.name || '-' }} + {{ scope.row.contact || '暂无联系人' }} · {{ scope.row.phone || '未录入电话' }} + + - - + + - + + {{ getCustomerStatusLabel(scope.row) }} + + + + + + + {{ getLevelLabel(scope.row.level) }} - - - - - - - - + - 查看档案 - - 编辑 - 转移 - 归档 - - 恢复 + {{ scope.row.industry || '未填写行业' }} + + + + + + {{ scope.row.address || '未填写地址' }} + + + + + + {{ formatCreatedAt(scope.row.created_at) }} + + + + + + + 查看档案 + + 编辑 + 转移 + 归档 + + 恢复 + - - - - - + + + 显示第 {{ customerData.length ? (currentPage - 1) * pageSize + 1 : 0 }} 到 {{ (currentPage - 1) * pageSize + customerData.length }} 条,共 {{ total }} 条 + + + + @@ -582,56 +701,158 @@ onMounted(() => { 确认转移 - + diff --git a/frontend/src/views/dashboard/index.vue b/frontend/src/views/dashboard/index.vue index 83e5001..d92a001 100644 --- a/frontend/src/views/dashboard/index.vue +++ b/frontend/src/views/dashboard/index.vue @@ -3,6 +3,9 @@ import { ref, onMounted } from 'vue' import { Plus, Van, Box, EditPen } from '@element-plus/icons-vue' import { useRouter } from 'vue-router' import request from '@/api/request' +import PageShell from '@/components/PageShell.vue' +import KpiCard from '@/components/KpiCard.vue' +import DataTableShell from '@/components/DataTableShell.vue' const router = useRouter() @@ -29,110 +32,34 @@ onMounted(fetchStats) - - - + + 新建订单 安排发货 库存入库 - 写销售日志 - + 写销售日志 + - - - - - 本月新增订单 - {{ stats.orders_count }} 单 - - - - - 待出库发货 - {{ stats.pending_shipping }} 单 - - - - - 库存预警 SKU - {{ stats.warning_skus }} 个 - - - - - 本月预计营收 - {{ formatMoney(stats.monthly_revenue) }} - - - + + + + + + - - - - - 近期业务动态 - - - - - + + + + + + diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index d6c012f..8f46f75 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -7,12 +7,13 @@ "DOM", "DOM.Iterable" ], - "moduleResolution": "bundler", - "strict": true, - "jsx": "preserve", - "resolveJsonModule": true, - "isolatedModules": true, - "esModuleInterop": true, + "moduleResolution": "bundler", + "strict": true, + "jsx": "preserve", + "noEmit": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "baseUrl": ".", @@ -32,4 +33,4 @@ "path": "./tsconfig.node.json" } ] -} \ No newline at end of file +} diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json index 861a256..823524d 100644 --- a/frontend/tsconfig.node.json +++ b/frontend/tsconfig.node.json @@ -1,16 +1,18 @@ { "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "bundler", - "verbatimModuleSyntax": true, - "composite": true, - "declaration": true, - "declarationMap": true, - "strict": true, - "skipLibCheck": true + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "composite": true, + "declaration": true, + "declarationMap": true, + "outDir": "./.tsbuild/node", + "tsBuildInfoFile": "./.tsbuild/tsconfig.node.tsbuildinfo", + "strict": true, + "skipLibCheck": true }, "include": [ "vite.config.ts" ] -} \ No newline at end of file +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 2dc91c5..465733b 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,15 +1,16 @@ -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import { resolve } from 'path' - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [vue()], - resolve: { - alias: { - '@': resolve(__dirname, 'src'), // @ 指向 src 目录 - }, - }, +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +const srcPath = decodeURIComponent(new URL('./src', import.meta.url).pathname).replace(/^\/([A-Za-z]:)/, '$1') + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue()], + resolve: { + alias: { + '@': srcPath, // @ 指向 src 目录 + }, + }, server: { port: 5173, // 开发环境代理:将 /api 请求转发到后端,避免 CORS 问题
{{ description }}
{{ label }}
{{ helper }}
SHBL CRM Workspace
客户索引
优先处理重点客户、活跃跟进和归档恢复,不再把关键信息埋在表格里。