فهرست منبع

登录和首页问题修复

zyp 2 هفته پیش
والد
کامیت
725ef67394

+ 383 - 0
docs/登录与首页仪表盘-问题清单.md

@@ -0,0 +1,383 @@
+# 租户总后台(saasadminui + fs-admin-saas)登录与首页仪表盘 — 问题清单
+
+> **范围**:`saasadminui` 登录链路、路由守卫、`/index` 首页仪表盘(`src/views/index.vue`)  
+> **后端**:`fs-admin-saas:8004`(profile=`admin`),业务实现 `fs-service`  
+> **排查日期**:2026-05-27  
+> **说明**:本文档记录问题点与修复状态。  
+> **修复批次**:2026-05-27(登录 + 首页 P0/P1 首批)
+
+---
+
+## 修复状态(2026-05-27)
+
+| 编号 | 状态 |
+|------|------|
+| P0-2 getFirstLogin | ✅ 已在 `SysLoginController` 实现 |
+| P0-3 dealerChart 初始化 | ✅ 已移除无效图表初始化 |
+| P0-5 authorizationInfo | ✅ 已修正返回对象 |
+| P0-6 trafficLog null | ✅ 已保证返回空 DTO |
+| P0-8 登出 tenantCode | ✅ 已清理 Cookie |
+| P1-4/5 路由守卫 | ✅ GetInfo/菜单失败跳转登录 |
+| P1-6~8 首页展示 | ✅ 短信/流量/较昨日绑定数据 |
+| P1-11 收款图表 option | ✅ 已修正 |
+| P0-4 统计任务 NPE | ✅ `statis.config` 空 JSON 防护 |
+| setPassword API | ✅ 改用 `/system/user/profile/updatePwd` |
+
+---
+
+## 一、链路总览
+
+```mermaid
+sequenceDiagram
+  participant UI as saasadminui
+  participant API as fs-admin-saas:8004
+  participant Redis as Redis
+  participant DB as 租户库/主库
+
+  UI->>API: POST /login (tenantCode+账号密码)
+  API->>DB: 主库查租户 + 切租户库认证
+  API-->>UI: token
+  UI->>API: GET /getInfo
+  UI->>API: GET /getRouters (AdminMenu)
+  UI->>UI: 进入 /index
+  UI->>API: 并行 N 个 /index/statistics/*
+  API->>Redis: 读统计缓存
+  API-->>UI: 仪表盘数据
+```
+
+| 环节 | 前端 | 后端(fs-admin-saas) |
+|------|------|------------------------|
+| 登录 | `views/login.vue` → `api/login.js` | `SysLoginController`(@Profile admin) |
+| 验证码 | `getCodeImg` | `CaptchaController` |
+| 用户信息 | `store/user.js` GetInfo | `GET /getInfo` |
+| 动态菜单 | `store/permission.js` | `GET /getRouters` → `IAdminMenuService` |
+| 首页 | `views/index.vue` | `com.fs.api.controller.IndexStatisticsController` |
+| 红包概览 | `api/company/redPacket.js` | `FsRedPacketController` `/his/redPacket/info` |
+
+---
+
+## 二、问题统计摘要
+
+| 级别 | 数量 | 说明 |
+|------|------|------|
+| **P0** | 8 | 阻塞登录/首页白屏/核心数据全空 |
+| **P1** | 12 | 功能错误、数据不准、易引发线上故障 |
+| **P2** | 10 | 体验、规范、技术债 |
+| **配置/环境** | 5 | 代理、Redis、定时任务、JDK |
+
+---
+
+## 三、P0 — 必须优先处理
+
+### P0-1 前端代理曾指向错误服务(已局部修正,需验证)
+
+| 项 | 内容 |
+|----|------|
+| **现象** | 开发环境请求打到 `fs-company:8006`,租户总后台接口 404 或行为与 company 端混淆 |
+| **正确** | `saasadminui` → `fs-admin-saas:8004` |
+| **相关文件** | `saasadminui/vue.config.js`、`saasadminui/nginx.conf` |
+| **状态** | 已改为 8004;需在本地 `npm run dev` + 启动 8004 后回归验证 |
+| **建议** | 生产 Nginx 同步检查,勿再指向 8006 |
+
+### P0-2 `GET /getFirstLogin` 在 fs-admin-saas 上不存在(404)
+
+| 项 | 内容 |
+|----|------|
+| **现象** | 登录成功后调用 `getFirstLogin` 失败;`login.vue` 的 `catch` 仍跳转首页,首次改密流程失效 |
+| **原因** | `getFirstLogin` 仅在 `CompanyLoginController`(`@Profile("company")`)中实现,且该类在 `com.fs.company.controller.*` 被启动类 **排除扫描** |
+| **活跃登录** | `SysLoginController`(admin)**无** `getFirstLogin` |
+| **前端** | `api/login.js` → `GET /getFirstLogin`;`login.vue` `checkFirstLogin()` |
+| **建议** | 在 `SysLoginController` 或独立 admin Controller 中实现租户总后台版「首次登录改密」(基于 `SysUser` + `his.login` 配置),或前端暂时关闭该流程 |
+
+### P0-3 首页 ECharts 初始化访问已注释的 DOM(可能白屏/控制台报错)
+
+| 项 | 内容 |
+|----|------|
+| **现象** | `mounted` 中仍调用 `initDealerChart()`、`handleDealerChartData()`,但模板中 `ref="dealerChart"` 的图表区域已被注释 |
+| **文件** | `saasadminui/src/views/index.vue`(约 1027–1028、1451–1463 行 vs 412–426 行注释块) |
+| **影响** | `echarts.init(undefined)` 抛错,可能中断同 `mounted` 内其它图表初始化 |
+| **建议** | 删除或恢复对应 DOM;仅保留 `dealerChartNew` |
+
+### P0-4 仪表盘数据强依赖 Redis 缓存,定时任务存在 NPE
+
+| 项 | 内容 |
+|----|------|
+| **现象** | 企业数据、资产、分析概览等卡片长期为 0 |
+| **后端** | `IndexStatisticsController` 多数接口从 Redis 读 `DATA_OVERVIEW_*` 等 key |
+| **写入** | 依赖 `statisticsService.dataOverviewTask()` 等 Quartz 任务 |
+| **日志** | `sys-error.log`:`StatisticsServiceImpl.rechargeConsumption` 中 `jsonObject` 为 null → 租户任务失败 |
+| **其它** | `No bean named 'qwTask'` 等任务 Bean 缺失,可能影响调度器整体稳定性 |
+| **建议** | 修复 `fs-service` 统计任务 NPE;确认 SaaS 租户任务分发器正常;缓存未命中时降级查库或返回明确提示 |
+
+### P0-5 `authorizationInfo` 部门聚合分支返回错误对象(后端逻辑 Bug)
+
+| 项 | 内容 |
+|----|------|
+| **文件** | `fs-admin-saas/.../api/controller/IndexStatisticsController.java` `authorizationInfo()` |
+| **现象** | `else` 分支累加结果写入 `authorizationInfoDTO1`,但 `return` 的是未赋值的 `authorizationInfoDTO` |
+| **影响** | 按部门筛选时「平台今日看课人数 / 配额上限」恒为空或 0 |
+| **建议** | 返回 `authorizationInfoDTO1` 或统一赋值后返回 |
+
+### P0-6 `trafficLog` 接口可能返回 `null` 响应体
+
+| 项 | 内容 |
+|----|------|
+| **文件** | 同上 `getTrafficLog()` |
+| **现象** | `result == null \|\| sysConfig == null` 时 `return null` |
+| **影响** | 前端 `trafficLog().then` 可能异常;且 UI 上「剩余流量」为写死 `100.00GB`(见 P1-8),接口失败用户无感知 |
+| **建议** | 统一 `R.ok().put("data", emptyDto)`;前端绑定真实字段 |
+
+### P0-7 `X-Frontend-Type` 与后端 profile 曾不一致(已改 admin,需联调)
+
+| 项 | 内容 |
+|----|------|
+| **原状** | 前端发 `company`,后端为 `admin` profile |
+| **影响** | Token 无 `tenantId` 时,`tenant-code` 回退切库行为与菜单数据源(`AdminMenu` vs `CompanyMenu`)不一致 |
+| **现状** | `request.js` 已改为 `admin`;登录必须带 `tenantCode` 以保证 `LoginUser.tenantId` |
+| **建议** | 联调确认 `getRouters` 读的是租户库 `admin_menu` 数据 |
+
+### P0-8 登出未清除 `tenantCode` Cookie
+
+| 项 | 内容 |
+|----|------|
+| **文件** | `store/modules/user.js` `LogOut` / `FedLogOut` |
+| **现象** | 仅 `removeToken()`,未 `Cookies.remove('tenantCode')` |
+| **影响** | 换租户登录可能携带旧 `tenant-code` 请求头(与 body 不一致) |
+| **建议** | 登出时同步清理 `tenantCode` |
+
+---
+
+## 四、P1 — 功能/数据错误
+
+### P1-1 登录文案与校验矛盾
+
+| 文件 | `login.vue` |
+|------|-------------|
+| **现象** | placeholder「企业编号(选填)」 vs `loginRules.tenantCode` **required** |
+| **建议** | 租户总后台应必填;改文案为「请输入企业编号」 |
+
+### P1-2 短信二次验证未实现
+
+| 文件 | `login.vue` `handleLogin` |
+|------|---------------------------|
+| **现象** | `needSms: true` 时仅提示「验证组件未启用」 |
+| **后端** | `checkIsNeedCheck` 在 admin 端存在,但前端无弹窗流程 |
+
+### P1-3 `checkIsNeedCheck` 返回类型与拦截器
+
+| 项 | 内容 |
+|----|------|
+| **后端** | 返回原始 `boolean` |
+| **前端** | `if (!resp)` 依赖拦截器返回体为布尔值;若将来改为 `AjaxResult` 会失效 |
+| **建议** | 约定统一 `AjaxResult` 或文档化 |
+
+### P1-4 路由守卫失败后的跳转逻辑
+
+| 文件 | `permission.js` |
+|------|-----------------|
+| **现象** | `GetInfo` 失败 → `LogOut` → `next({ path: '/' })`,仍可能再次触发 GetInfo |
+| **建议** | 失败应 `next('/login')` 并带 redirect |
+
+### P1-5 动态路由 `getRouters` 无错误处理
+
+| 文件 | `store/modules/permission.js` |
+|------|-------------------------------|
+| **现象** | `getRouters()` 无 `.catch`,菜单接口失败时 Promise 悬挂,页面卡在 NProgress |
+| **建议** | 增加 catch + 提示 |
+
+### P1-6 首页短信余额未绑定接口数据
+
+| 文件 | `index.vue` 约 224–226 行 |
+|------|---------------------------|
+| **现象** | 已调用 `smsBalance()` 赋值 `smsRemainCount`,模板写死 `0` |
+| **建议** | 使用 `{{ smsRemainCount }}` |
+
+### P1-7 资产「较昨日」写死
+
+| 文件 | `index.vue` 约 78–79 行 |
+|------|---------------------------|
+| **现象** | 显示「较昨日 +1」,未使用 `yesterdayComsumption` |
+| **建议** | 计算真实环比 |
+
+### P1-8 流量卡片 UI 写死
+
+| 文件 | `index.vue` 约 197–204 行 |
+|------|---------------------------|
+| **现象** | 「剩余流量 100.00GB」、进度 90% 硬编码;仅「今日/本月消耗」用接口 |
+| **建议** | 对接 `trafficLog` 的 `traffic` 等字段 |
+
+### P1-9 看课配额进度条分子分母相同
+
+| 文件 | `index.vue` 约 159–163 行 |
+|------|---------------------------|
+| **现象** | 配额展示 `todayWatchUserCount / versionLimit`,但分子也绑定了 `todayWatchUserCount`(应为当前使用 vs 上限) |
+| **建议** | 核对产品设计后改绑定字段 |
+
+### P1-10 `thisMonthOrderCount` / `thisMonthRecvCount` 返回结构不统一
+
+| 项 | 内容 |
+|----|------|
+| **后端** | 默认分支:`return redisCache.getCacheObject(...)` 可能为顶层含 `dates` 的 `R`;部门聚合:`R.ok().put("dates",...)` |
+| **前端** | 使用 `res.dates`、`res.orderCount`(非 `res.data.dates`) |
+| **风险** | Redis 存的对象结构变化会导致图表无数据 |
+| **建议** | 统一 `R.ok().put("data", chartDto)`;前端统一读 `res.data` |
+
+### P1-11 `initThisMonthRecvChart` 使用了错误 option
+
+| 文件 | `index.vue` `initThisMonthRecvChart` |
+|------|--------------------------------------|
+| **现象** | `setOption(thisMonthOrderCountOption)` 应为 `thisMonthRecvCountOption` |
+| **影响** | 「本月收款数」图表轴/系列配置错误 |
+
+### P1-12 红包接口遍历全量公司
+
+| 文件 | `FsRedPacketController.info()` |
+|------|--------------------------------|
+| **现象** | `companyService.selectCompanyList(new Company())` 无租户/权限过滤 |
+| **影响** | 租户总后台可能汇总到越权数据或性能差 |
+| **建议** | 按当前租户/数据权限过滤;逻辑下沉 `fs-service` |
+
+---
+
+## 五、P2 — 体验与规范
+
+### P2-1 `$runtimeConfig` 初始化时机
+
+| 项 | 内容 |
+|----|------|
+| **现象** | `index.vue` `data()` 使用 `this.$runtimeConfig.VUE_APP_COURSE_DEFAULT`,登录前为 `{}`,默认会员/企微可能不准 |
+| **依赖** | 登录后 `reloadRuntimeConfig()` 读 `his.adminUi.config` |
+| **建议** | 进入首页前 await 配置加载,或 GetInfo 后刷新 |
+
+### P2-2 头像 URL 拼接
+
+| 文件 | `store/modules/user.js` |
+|------|-------------------------|
+| **现象** | `VUE_APP_BASE_API + user.avatar`,若 avatar 已是完整 URL 会重复 |
+| **建议** | 判断 `http` 前缀 |
+
+### P2-3 请求超时 20 分钟
+
+| 文件 | `utils/request.js` `timeout: 1200000` |
+|------|----------------------------------------|
+| **建议** | 登录/统计接口单独合理超时(如 30s) |
+
+### P2-4 环境变量命名误导
+
+| 文件 | `.env.development` 中 `ENV = 'production'` |
+|------|---------------------------------------------|
+
+### P2-5 缺少 `.catch` 的仪表盘并行请求
+
+| 文件 | `index.vue` `refresh()` |
+|------|-------------------------|
+| **现象** | 多个 API 无 catch,单个 500 仅控制台/拦截器弹窗,卡片静默为 0 |
+| **建议** | 统一错误态或骨架屏 |
+
+### P2-6 重复/死代码
+
+| 项 | 内容 |
+|----|------|
+| `initDealerChart` / `handleDealerChartData` | 对应 UI 已注释 |
+| `api/tenant.js` vs `api/tenant/tenant.js` | 路径重复(非本页核心) |
+
+### P2-7 后端双份 `IndexStatisticsController`
+
+| 路径 | Profile | 是否加载 |
+|------|---------|----------|
+| `com.fs.api.controller.IndexStatisticsController` | **admin** | ✅ fs-admin-saas 使用 |
+| `com.fs.company.controller.company.IndexStatisticsController` | company | ❌ 排除扫描 |
+
+**建议**:避免误改 company 包下文件;文档标明以 `api` 包为准。
+
+### P2-8 拼写与命名技术债
+
+| 位置 | 说明 |
+|------|------|
+| `rechargeComsumption` | 应为 Consumption |
+| `dealderCount` | 应为 dealer |
+| 前后端需保持一致以免改 URL |
+
+### P2-9 注释与 JavaDoc 不足
+
+| 建议 |
+|------|
+| `IndexStatisticsController` 各接口补充:Redis key、租户范围、依赖定时任务 |
+| `SysLoginController` 注明租户总后台登录与 company 端差异 |
+
+### P2-10 JDK 版本
+
+| 项 | 内容 |
+|----|------|
+| **目标** | JDK 17 |
+| **现状** | 父 POM `java.version=1.8` |
+| **建议** | 功能稳定后单独立项升级 |
+
+---
+
+## 六、配置与环境依赖
+
+| 编号 | 检查项 | 说明 |
+|------|--------|------|
+| E-1 | `fs-admin-saas` 端口 **8004** 已启动 | profile `dev,admin` |
+| E-2 | Redis 可连 | 统计接口几乎全依赖缓存 |
+| E-3 | MySQL 主库 + 租户库 | 登录 `tenantCode` 切库 |
+| E-4 | `tenant_info` 中租户 status=1 | 否则「企业已禁用」 |
+| E-5 | Quartz / `statisticsService.dataOverviewTask` | 缓存写入;需先修 NPE |
+
+---
+
+## 七、首页 API 对照表(前端 → 后端)
+
+| # | 前端方法 | URL | 后端类 | 主要风险 |
+|---|----------|-----|--------|----------|
+| 1 | `login` | POST `/login` | `SysLoginController` | 租户码错误 |
+| 2 | `getCodeImg` | GET `/captchaImage` | `CaptchaController` | 403 若未放行 |
+| 3 | `checkIsNeedCheck` | POST `/checkIsNeedCheck` | `SysLoginController` | 返回格式 |
+| 4 | `getFirstLogin` | GET `/getFirstLogin` | **缺失** | **404** |
+| 5 | `getInfo` | GET `/getInfo` | `SysLoginController` | 租户库用户/角色 |
+| 6 | `getRouters` | GET `/getRouters` | `SysLoginController` | AdminMenu 数据 |
+| 7 | `getConfigByKey` | GET `/system/config/getConfigByKey/his.adminUi.config` | SysConfig | 运行时配置 |
+| 8 | `rechargeComsumption` | GET `/index/statistics/rechargeComsumption` | IndexStatisticsController | Redis 空 |
+| 9 | `redPacketInfo` | GET `/his/redPacket/info` | FsRedPacketController | 全表公司汇总 |
+| 10 | `trafficLog` | GET `/index/statistics/trafficLog` | IndexStatisticsController | **可 null** |
+| 11 | `dealerAggregated` | GET `/index/statistics/dealerAggregated` | 同上 | Redis 空 |
+| 12 | `analysisPreview` | POST `/index/statistics/analysisPreview` | 同上 | Redis 空 |
+| 13 | `smsBalance` | GET `/index/statistics/smsBalance` | 同上 | 前端未展示 |
+| 14 | `authorizationInfo` | GET `/index/statistics/authorizationInfo` | 同上 | **返回错对象** |
+| 15 | `watchEndPlayTrend` | POST `.../watchEndPlayTrend` | 同上 | Redis 空 |
+| 16 | `deaMemberTopTen` | POST `.../deaMemberTopTen` | 同上 | ref 已删 |
+| 17 | `watchCourseTopTen` | POST `.../watchCourseTopTen` | 同上 | — |
+| 18 | `getWatchCourseStatisticsData` | POST `.../getWatchCourseStatisticsData` | 同上 | 实时查库 |
+| 19 | `rewardMoneyTopTen` | POST `.../rewardMoneyTopTen` | 同上 | — |
+| 20 | `rewardMoneyTrend` | POST `.../rewardMoneyTrend` | 同上 | — |
+| 21 | `thisMonthOrderCount` | GET `.../thisMonthOrderCount` | 同上 | 返回结构 |
+| 22 | `thisMonthRecvCount` | GET `.../thisMonthRecvCount` | 同上 | option 用错 |
+
+---
+
+## 八、建议修复顺序(供下一阶段开发)
+
+1. **环境**:确认 8004 + Redis + 修复统计定时任务 NPE  
+2. **登录**:补 `getFirstLogin`(admin)、登出清 Cookie、路由失败跳登录页  
+3. **首页 P0**:修 `dealerChart` 初始化、修 `authorizationInfo` return、修 `trafficLog` null  
+4. **首页 P1**:短信/流量/较昨日绑定真实数据、修收款图表 option  
+5. **数据**:缓存未命中降级 + 前端 loading/错误态  
+6. **规范**:接口注释、统一 R 返回结构、逻辑收拢 `fs-service`  
+
+---
+
+## 九、验证清单(修复后自检)
+
+- [ ] 正确 `tenantCode` + 账号密码可登录,验证码开关开/关均正常  
+- [ ] 登录后侧边栏菜单正常,刷新页面不掉线  
+- [ ] 首页无控制台 ECharts 报错  
+- [ ] 企业数据/资产/经营数据非全 0(或明确提示「统计任务未跑」)  
+- [ ] 分析概览切换「今日/昨日/本周」有变化  
+- [ ] 本月订单/收款图表有曲线  
+- [ ] 换租户登录后数据隔离正确  
+- [ ] 登出再登录另一租户,请求头 `tenant-code` 正确  
+
+---
+
+*文档维护:随修复进展更新对应条目的「状态」列。*

+ 2 - 2
nginx.conf

@@ -27,7 +27,7 @@ http {
 
         # 关键:反向代理 API(解决跨域,替换为你的真实后端地址)
         location /prod-api/ {
-            proxy_pass http://192.168.58.159:7772/;  # 后端 API 地址(末尾加 / 避免路径拼接问题)
+            proxy_pass http://192.168.58.159:8004/;  # fs-admin-saas 租户总后台(末尾加 / 避免路径拼接问题)
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -35,4 +35,4 @@ http {
         }
 
      }
-}
+}

+ 6 - 1
src/permission.js

@@ -26,11 +26,16 @@ router.beforeEach((to, from, next) => {
             // 根据roles权限生成可访问的路由表
             router.addRoutes(accessRoutes) // 动态添加可访问路由表
             next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
+          }).catch(err => {
+            store.dispatch('LogOut').then(() => {
+              Message.error(err)
+              next({ path: '/login', query: { redirect: to.fullPath } })
+            })
           })
         }).catch(err => {
             store.dispatch('LogOut').then(() => {
               Message.error(err)
-              next({ path: '/' })
+              next({ path: '/login', query: { redirect: to.fullPath } })
             })
           })
       } else {

+ 3 - 1
src/store/modules/permission.js

@@ -64,6 +64,8 @@ const permission = {
           commit('SET_DEFAULT_ROUTES', sidebarRoutes)
           commit('SET_TOPBAR_ROUTES', sidebarRoutes)
           resolve(rewriteRoutes)
+        }).catch(err => {
+          reject(err)
         })
       })
     }
@@ -143,4 +145,4 @@ export const loadView = (view) => { // 路由懒加载
   return (resolve) => require([`@/views/${view}`], resolve)
 }
 
-export default permission
+export default permission

+ 2 - 0
src/store/modules/user.js

@@ -119,6 +119,7 @@ const user = {
           commit('SET_PERMISSIONS', [])
           commit('SET_TENANT_CODE', null)
           removeToken()
+          Cookies.remove('tenantCode')
           resolve()
         }).catch(error => {
           reject(error)
@@ -132,6 +133,7 @@ const user = {
         commit('SET_TOKEN', '')
         commit('SET_TENANT_CODE', null)
         removeToken()
+        Cookies.remove('tenantCode')
         resolve()
       })
     }

+ 3 - 2
src/utils/request.js

@@ -23,8 +23,9 @@ service.interceptors.request.use(config => {
 
   // 是否需要设置 token
   const isToken = (config.headers || {}).isToken === false
-  // 始终发送 X-Frontend-Type 和 tenant-code(登录时也需要)
-  config.headers['X-Frontend-Type'] = 'company'
+  // 租户总后台(saasadminui) → fs-admin-saas(profile=admin);登录后 token 含 tenantId 切租户库
+  // 租户销售端(companyUI) → fs-company(profile=company),使用 X-Frontend-Type: company
+  config.headers['X-Frontend-Type'] = 'admin'
   const tenantCode = getTenantCode()
   if (tenantCode) {
     config.headers['tenant-code'] = tenantCode

+ 43 - 43
src/views/index.vue

@@ -76,7 +76,7 @@
                 <count-to :start-val="0" :end-val="todayComsumption" :duration="3600" class="card-panel-num" />
               </div>
               <div class="card-compare">
-                较昨日 <span>+1</span>
+                较昨日 <span>{{ consumptionDayCompareText }}</span>
               </div>
             </div>
           </div>
@@ -195,11 +195,11 @@
                   <img src="../assets/images/liuliang.png" alt=""><span>剩余流量</span>
                 </div>
                 <div class="cardtopnumber">
-                  100.00GB
+                  {{ trafficRemainText }}
                 </div>
               </div>
-              <div class="progress">
-                <el-progress :percentage="90" :show-text="false" define-back-color="#000">
+              <div class="progress" v-if="trafficUsagePercent != null">
+                <el-progress :percentage="trafficUsagePercent" :show-text="false" define-back-color="#000">
 
                 </el-progress>
               </div>
@@ -222,7 +222,7 @@
                 </span>
               </div>
               <div class="internet-number">
-                0
+                {{ smsRemainCount }}
               </div>
             </div>
           </div>
@@ -552,7 +552,7 @@ import CountTo from "vue-count-to";
 import {
   analysisPreview,
   authorizationInfo,
-  dealerAggregated, deaMemberTopTen, rechargeComsumption, rewardMoneyTopTen, rewardMoneyTrend,
+  dealerAggregated, rechargeComsumption, rewardMoneyTopTen, rewardMoneyTrend,
   smsBalance, thisMonthOrderCount, thisMonthRecvCount, trafficLog,
   watchCourseTopTen, watchEndPlayTrend,getWatchCourseStatisticsData,
 } from "@/api/statistics/statistics";
@@ -1018,14 +1018,29 @@ export default {
       // 商品总数
       goodsTotalNum: 0,
       // 今日商品总数
-      todayGoodsNum: 0
+      todayGoodsNum: 0,
+      trafficRemainText: '--',
+      trafficUsagePercent: null
+    }
+  },
+  computed: {
+    consumptionDayCompareText() {
+      const today = Number(this.todayComsumption) || 0
+      const yesterday = Number(this.yesterdayComsumption) || 0
+      const diff = today - yesterday
+      if (diff > 0) {
+        return '+' + diff.toFixed(2)
+      }
+      if (diff < 0) {
+        return diff.toFixed(2)
+      }
+      return '0'
     }
   },
   mounted() {
     this.$nextTick(() => {
       this.initViewerChart()
       this.initDealerChartNew();
-      this.initDealerChart()
       this.initCourseWatchChart();
       this.initAnswerRedPackViewerChart();
       this.initAnswerRedPackMoneyViewerChart();
@@ -1035,9 +1050,8 @@ export default {
       // 监听窗口大小变化,重新渲染图表
       window.addEventListener('resize', () => {
         this.viewerChart && this.viewerChart.resize()
-        this.dealerChart && this.dealerChart.resize()
         this.dealerChartNew && this.dealerChartNew.resize()
-
+        this.courseWatchChart && this.courseWatchChart.resize()
       })
     })
   },
@@ -1184,10 +1198,19 @@ export default {
       })
 
       trafficLog().then(res=>{
-        if(res.code === 200) {
-          this.todayTraffic = res.data.today;
-          this.thisMonthTraffic = res.data.thisMonth;
+        if(res.code === 200 && res.data) {
+          this.todayTraffic = res.data.today || 0;
+          this.thisMonthTraffic = res.data.thisMonth || 0;
+          if (res.data.traffic) {
+            this.trafficRemainText = res.data.traffic
+          } else if (this.thisMonthTraffic > 0) {
+            this.trafficRemainText = this.formatBytes(this.thisMonthTraffic)
+          } else {
+            this.trafficRemainText = '--'
+          }
         }
+      }).catch(() => {
+        this.trafficRemainText = '--'
       })
 
       dealerAggregated().then(res=>{
@@ -1248,9 +1271,6 @@ export default {
       this.handleViewChartData()
       this.handleDealerChartDataNew()
 
-      // 经销商会员观看TOP10
-      this.handleDealerChartData()
-
       this.handleAnswerRedPackViewerChart()
 
       this.handleAnswerRedPackMoneyViewerChart()
@@ -1298,7 +1318,7 @@ export default {
       else if (selected === 0) {
         this.$nextTick(() => {
           if (this.viewerChart) this.viewerChart.resize();
-          if (this.dealerChart) this.dealerChart.resize();
+          if (this.dealerChartNew) this.dealerChartNew.resize();
         });
       } else if (selected === 2) {
         this.$nextTick(() => {
@@ -1308,7 +1328,6 @@ export default {
       }
       if (this.selectedDiv === 0) {
         this.handleViewChartData()
-        this.handleDealerChartData()
         this.handleDealerChartDataNew()
       } else if (this.selectedDiv === 1) {
         this.handleCourseWatchChart()
@@ -1384,7 +1403,6 @@ export default {
 
       if (this.selectedDiv === 0) {
         this.handleViewChartData()
-        this.handleDealerChartData()
         this.handleDealerChartDataNew()
       } else if (this.selectedDiv === 1) {
         this.handleCourseWatchChart()
@@ -1446,23 +1464,6 @@ export default {
         }
       })
     },
-    handleDealerChartData(){
-      let param = this.getParam();
-
-      // 经销商会员观看TOP10
-      deaMemberTopTen({...param,statisticalType: this.viewerType}).then(res=>{
-        if(res.code === 200){
-          let data = res.data;
-          let companyNameList = data.map(e=>e.companyName);
-          let watchUserList = data.map(e=>e.watchUserCount);
-          dealerOption.yAxis.data = companyNameList;
-          dealerOption.series[0].data = watchUserList;
-
-          this.dealerChart.setOption(dealerOption)
-        }
-      })
-
-    },
     handleDealerChartDataNew() {
       let param = this.getParam();
 
@@ -1542,17 +1543,12 @@ export default {
     },
     initThisMonthRecvChart(){
       this.thisMonthRecvChart = echarts.init(this.$refs.viewerReceiveChart)
-      this.thisMonthRecvChart.setOption(thisMonthOrderCountOption)
+      this.thisMonthRecvChart.setOption(thisMonthRecvCountOption)
     },
     initViewerChart() {
       this.viewerChart = echarts.init(this.$refs.viewerChart)
       this.viewerChart.setOption(viewCharOption)
     },
-    initDealerChart() {
-      this.dealerChart = echarts.init(this.$refs.dealerChart)
-
-      this.dealerChart.setOption(dealerOption)
-    },
     initCourseWatchChart() {
       this.courseWatchChart = echarts.init(this.$refs.courseWatchChart)
 
@@ -1578,8 +1574,12 @@ export default {
     }
     // window.removeEventListener('resize', this.resizeHandler)
     this.viewerChart && this.viewerChart.dispose()
-    this.dealerChart && this.dealerChart.dispose()
     this.dealerChartNew && this.dealerChartNew.dispose()
+    this.courseWatchChart && this.courseWatchChart.dispose()
+    this.answerRedPackViewerChart && this.answerRedPackViewerChart.dispose()
+    this.answerRedPackMoneyViewerChart && this.answerRedPackMoneyViewerChart.dispose()
+    this.thisMonthOrderChart && this.thisMonthOrderChart.dispose()
+    this.thisMonthRecvChart && this.thisMonthRecvChart.dispose()
 
   }
 }

+ 1 - 1
src/views/login.vue

@@ -16,7 +16,7 @@
         <div class="title">{{vueAppTitle}}</div>
         <div class="title-line"></div>
         <el-form-item prop="tenantCode">
-          <el-input v-model="loginForm.tenantCode" type="text" auto-complete="off" placeholder="企业编号(选填,如 test001)" class="tenantCode" >
+          <el-input v-model="loginForm.tenantCode" type="text" auto-complete="off" placeholder="请输入企业编号(如 test001)" class="tenantCode" >
             <img slot="prefix" src="../assets/images/user.png" class="input-icon "/>
           </el-input>
         </el-form-item>

+ 1 - 1
src/views/setPassword.vue

@@ -27,7 +27,7 @@
 </template>
 
 <script>
-import { updateUserPwd } from "@/api/company/companyUser";
+import { updateUserPwd } from "@/api/system/user";
 import { removeToken } from "@/utils/auth";
 
 export default {

+ 2 - 655
vue.config.js

@@ -40,660 +40,6 @@ module.exports = {
     open: true,
     disableHostCheck: true,
     proxy: {
-
-
-      // ===== 前端路径与后端不一致的路径重写 → fs-admin-saas(8004) =====
-      //
-      // saasadminui 前端 API 路径与 fs-admin-saas 后端控制器路径存在以下不一致:
-      // 1. /store/store/* → 后端是 /store/* (前端多了一层 store)
-      // 2. /store/his/* → 后端是 /his/* (前端 store/his 实际是 his)
-      // 3. /his/fsXxx → 后端是 /store/xxx (his/fs 前缀映射到 store)
-      // 4. /his_store/* → 后端是 /hisStore/* (下划线 vs 驼峰)
-      // 5. /admin/medical/* → 路由到 fs-admin(8003)
-      // 6. /fast_gpt/* → 后端是 /fastGpt/*
-      // 7. /wx/wxSop* → 后端是 /qwSop/sopUserLogs*
-      // 8. /wxSop/sopUserLogsWx → 后端是 /qwSop/sopUserLogs
-      // 9. /sop/companySopRole → 后端是 /companySopRole
-      //
-
-      // === 批量路径重写:/store/store/ → /store/ (仅匹配 hisStore 二级目录下的 store 前缀) ===
-      // 注意:此规则仅匹配前端 api/hisStore/store*.js 中 url 以 /store/store/ 开头的请求
-      // 不匹配 /store/storeProduct 等路径
-      [process.env.VUE_APP_BASE_API + '/store/store/']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/store/']: '/store/' }
-      },
-      // === /store/store/storeOrder → /hisStore/fsStoreOrderScrm (hisStore订单API在fs-admin-saas) ===
-      [process.env.VUE_APP_BASE_API + '/store/store/storeOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/store/storeOrder']: '/hisStore/fsStoreOrderScrm' }
-      },
-      // === 批量路径重写:/store/his/* → /his/* ===
-      [process.env.VUE_APP_BASE_API + '/store/his']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/his']: '/his' }
-      },
-      // === 批量路径重写:/store/doctor/* → /his/doctor/* ===
-      [process.env.VUE_APP_BASE_API + '/store/doctor']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/doctor']: '/his/doctor' }
-      },
-      // === 批量路径重写:/store/healthTongue/* → /his/healthTongue/* ===
-      [process.env.VUE_APP_BASE_API + '/store/healthTongue']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/healthTongue']: '/his/healthTongue' }
-      },
-      // === 批量路径重写:/store/inquiryOrder/* → /his/inquiryOrder/* ===
-      [process.env.VUE_APP_BASE_API + '/store/inquiryOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/inquiryOrder']: '/his/inquiryOrder' }
-      },
-      // === 批量路径重写:/store/prescribeDrug/* → /his/prescribeDrug/* ===
-      [process.env.VUE_APP_BASE_API + '/store/prescribeDrug']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/prescribeDrug']: '/his/prescribeDrug' }
-      },
-      // === 批量路径重写:/store/healthStoreOrder/* → /hisStore/fsStoreOrderScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/healthStoreOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/healthStoreOrder']: '/hisStore/fsStoreOrderScrm' }
-      },
-      // === 批量路径重写:/store/operlogScrm/* → /hisStore/operlogScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/operlogScrm']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/operlogScrm']: '/hisStore/operlogScrm' }
-      },
-      // === 批量路径重写:/store/storeOrderOffline/* → /hisStore/fsStoreOrderOfflineScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/storeOrderOffline']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/storeOrderOffline']: '/hisStore/fsStoreOrderOfflineScrm' }
-      },
-      // === 批量路径重写:/store/storeOrderAudit/* → /hisStore/fsStoreOrderAuditScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/storeOrderAudit']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/storeOrderAudit']: '/hisStore/fsStoreOrderAuditScrm' }
-      },
-      // === 批量路径重写:/store/recommend/* → /store/storeRecommend/* ===
-      [process.env.VUE_APP_BASE_API + '/store/recommend']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/recommend']: '/store/storeRecommend' }
-      },
-      // === 批量路径重写:/store/storeActivity/* → /hisStore/fsStoreActivityScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/storeActivity']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/storeActivity']: '/hisStore/fsStoreActivityScrm' }
-      },
-      // === 批量路径重写:/store/collectionSchedule/* → /hisStore/fsCollectionScheduleScrm/* ===
-      [process.env.VUE_APP_BASE_API + '/store/collectionSchedule']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/store/collectionSchedule']: '/hisStore/fsCollectionScheduleScrm' }
-      },
-      // === his_store/* → hisStore/* (下划线转驼峰) ===
-      [process.env.VUE_APP_BASE_API + '/his_store']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his_store']: '/hisStore' }
-      },
-      // === /admin/medical/* → fs-admin(8003) ===
-      [process.env.VUE_APP_BASE_API + '/admin/medical']: {
-        target: 'http://localhost:8003',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/admin/medical']: '/admin/medical' }
-      },
-      // === /fast_gpt/* → /fastGpt/* ===
-      [process.env.VUE_APP_BASE_API + '/fast_gpt']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/fast_gpt']: '/fastGpt' }
-      },
-      // === /wxSop/sopUserLogsWx → /qwSop/sopUserLogs ===
-      [process.env.VUE_APP_BASE_API + '/wxSop/sopUserLogsWx']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/wxSop/sopUserLogsWx']: '/qwSop/sopUserLogs' }
-      },
-      // === /sop/companySopRole → /companySopRole ===
-      [process.env.VUE_APP_BASE_API + '/sop/companySopRole']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/sop/companySopRole']: '/companySopRole' }
-      },
-      // === /company/ 路径无需特殊重写,走全局代理(只去掉 /dev-api 前缀,保留 /company/xxx)===
-      // === /qw/qwInformation → /qw/information ===
-      [process.env.VUE_APP_BASE_API + '/qw/qwInformation']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/qwInformation']: '/qw/information' }
-      },
-      // === /qw/qwAppContactWayLogs → /qw/appContactWayLogs ===
-      [process.env.VUE_APP_BASE_API + '/qw/qwAppContactWayLogs']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/qwAppContactWayLogs']: '/qw/appContactWayLogs' }
-      },
-      // === /qw/qwPushCount → /qw/pushCount ===
-      [process.env.VUE_APP_BASE_API + '/qw/qwPushCount']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/qwPushCount']: '/qw/pushCount' }
-      },
-      // === /qw/records → /qw/record ===
-      [process.env.VUE_APP_BASE_API + '/qw/records']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/records']: '/qw/record' }
-      },
-      // === /qw/workLinkUser → /qw/workLink ===
-      [process.env.VUE_APP_BASE_API + '/qw/workLinkUser']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/workLinkUser']: '/qw/workLink' }
-      },
-      // === /qw/workUser → /qw/work ===
-      [process.env.VUE_APP_BASE_API + '/qw/workUser']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/workUser']: '/qw/work' }
-      },
-      // === /qw/analyze → /qw/analyze (直接透传) ===
-      // === /qw/customerProperty → /qw/customerProperty (直接透传) ===
-      // === /crm/assist → /crm/assist (直接透传) ===
-      // === /crm/analyze → /crm/analyze (直接透传) ===
-      // === /crm/third → /crm/third (直接透传) ===
-      // === /crm/event → /crm/event (直接透传) ===
-      // === /crm/report → /crm/report (直接透传) ===
-      // === /crm/customerHisOrder → /crm/customerHisOrder (直接透传) ===
-      // === /crm/msg → /crm/msg (直接透传) ===
-      // === /his/aiWorkflow → /his/aiWorkflow (直接透传) ===
-
-      // his/fsXxx → store/xxx(saasadminui 用 his/fs 前缀,后端用 store)
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreOrder']: '/store/storeOrder' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsInquiryOrderReport']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsInquiryOrderReport']: '/store/inquiryOrderReport' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsInquiryOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsInquiryOrder']: '/store/inquiryOrder' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsDrugReportCount']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsDrugReportCount']: '/store/drugReportCount' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsDrugReport']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsDrugReport']: '/store/drugReport' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsHealthData']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsHealthData']: '/store/healthData' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsHealthRecord']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsHealthRecord']: '/store/healthRecord' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsUserOnlineState']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsUserOnlineState']: '/store/userOnlineState' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsUserCoupon']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsUserCoupon']: '/store/userCoupon' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsUserAddress']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsUserAddress']: '/store/userAddress' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsUser']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsUser']: '/store/user' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsMaterialGroup']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsMaterialGroup']: '/store/materialGroup' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsMaterial']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsMaterial']: '/store/material' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsExportTask']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsExportTask']: '/store/exportTask' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsCoupon']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsCoupon']: '/store/coupon' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsPatient']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsPatient']: '/store/patient' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsPackage']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsPackage']: '/store/package' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreProductCategory']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreProductCategory']: '/store/storeProductCategory' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreProduct']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreProduct']: '/store/storeProduct' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreAfterSales']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreAfterSales']: '/store/storeAfterSales' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsPayment']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsPayment']: '/store/storePayment' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreOrderOffline']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreOrderOffline']: '/hisStore/fsStoreOrderOfflineScrm' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreOrderAudit']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreOrderAudit']: '/hisStore/fsStoreOrderAuditScrm' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreOrderBillLog']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreOrderBillLog']: '/bill/billLog' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsStoreStatistics']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsStoreStatistics']: '/hisStore/fsStoreStatisticsScrm' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsIcd']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsIcd']: '/store/icd' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsPrescribe']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsPrescribe']: '/store/prescribe' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsFollowTemp']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsFollowTemp']: '/store/followTemp' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsCollectionSchedule']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsCollectionSchedule']: '/store/collectionSchedule' }
-      },
-      [process.env.VUE_APP_BASE_API + '/his/fsCollection']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsCollection']: '/store/collection' }
-      },
-      // his/fsFirstDiagnosis → his/diagnosis
-      [process.env.VUE_APP_BASE_API + '/his/fsFirstDiagnosis']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/his/fsFirstDiagnosis']: '/his/diagnosis' }
-      },
-      // hisStore/collection → store/collection
-      [process.env.VUE_APP_BASE_API + '/hisStore/collection']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/collection']: '/store/collection' }
-      },
-      // wx/wxSop* → qwSop/sopUserLogs* (企微SOP)
-      [process.env.VUE_APP_BASE_API + '/wx/wxSopUserInfo']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/wx/wxSopUserInfo']: '/qwSop/sopUserLogsInfo' }
-      },
-      [process.env.VUE_APP_BASE_API + '/wx/wxSopUser']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/wx/wxSopUser']: '/qwSop/sopUserLogs' }
-      },
-      [process.env.VUE_APP_BASE_API + '/wx/wxSopLogs']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/wx/wxSopLogs']: '/qwSop/sopUserLogsInfo' }
-      },
-      [process.env.VUE_APP_BASE_API + '/wx/wxSop']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/wx/wxSop']: '/qwSop/sopUserLogs' }
-      },
-      // === /live/coupon → /live/coupon (直接透传,后端已有) ===
-      // === /live/liveLotteryProductConf → /live/liveLotteryProductConf (直接透传) ===
-      // === /live/liveAfterSalesLogs → /live/liveAfterSalesLogs (直接透传) ===
-      // === /live/liveEventConf → /live/liveEventConf (直接透传) ===
-      // === /live/liveOrderStatus → /live/liveOrderStatus (直接透传) ===
-      // === /live/liveUserRedRecord → /live/liveUserRedRecord (直接透传) ===
-      // === /live/trafficLog → /live/trafficLog (直接透传) ===
-      // === /live/comment → /live/comment (直接透传) ===
-      // === /course/userVideoComment → /course/userVideoComment (直接透传) ===
-      // === /course/userCourseComment → /course/userCourseComment (直接透传) ===
-      // === /course/userCourseNote → /course/userCourseNote (直接透传) ===
-      // === /course/userCourseStudy → /course/userCourseStudy (直接透传) ===
-      // === /course/userTalent → /course/userTalent (直接透传) ===
-      // === /course/statistics → /course/statistics (直接透传) ===
-      // === /course/courseQuestionCategory → /course/courseQuestionCategory (直接透传) ===
-      // === /course/fsCourseProduct → /course/fsCourseProduct (直接透传) ===
-      // === /course/fsUserCoursePeriodDays → /course/fsUserCoursePeriodDays (直接透传) ===
-      // === /course/courseWatchComment → /course/courseWatchComment (直接透传) ===
-      // === /course/videoTags → /course/videoTags (直接透传) ===
-      // === /course/videoResource → /course/videoResource (直接透传) ===
-      // === /his/patient → /his/patient (直接透传) ===
-      // === /his/store → /his/store (直接透传) ===
-      // === /his/coupon → /his/coupon (直接透传) ===
-      // === /his/doctorBill → /his/doctorBill (直接透传) ===
-      // === /his/storeBill → /his/storeBill (直接透传) ===
-      // === /his/storeLog → /his/storeLog (直接透传) ===
-      // === /his/storeExtract → /his/storeExtract (直接透传) ===
-      // === /his/storeSubOrder → /his/storeSubOrder (直接透传) ===
-      // === /his/storeAfterSales → /his/storeAfterSales (直接透传) ===
-      // === /his/storeProduct → /his/storeProduct (直接透传) ===
-      // === /his/storeProductPackage → /his/storeProductPackage (直接透传) ===
-      // === /his/storeActivity → /his/storeActivity (直接透传) ===
-      // === /his/storeOrder → /his/storeOrder (直接透传) ===
-      // === /his/user → /his/user (直接透传) ===
-      // === /his/userBill → /his/userBill (直接透传) ===
-      // === /his/userExtract → /his/userExtract (直接透传) ===
-      // === /his/userRecharge → /his/userRecharge (直接透传) ===
-      // === /his/userIntegralLogs → /his/userIntegralLogs (直接透传) ===
-      // === /his/companyRecharge → /his/companyRecharge (直接透传) ===
-      // === /his/companyDeduct → /his/companyDeduct (直接透传) ===
-      // === /his/company → /his/company (直接透传) ===
-      // === /his/doctorExtract → /his/doctorExtract (直接透传) ===
-      // === /his/doctorArticle → /his/doctorArticle (直接透传) ===
-      // === /his/doctorArticleCate → /his/doctorArticleCate (直接透传) ===
-      // === /his/doctorOperLog → /his/doctorOperLog (直接透传) ===
-      // === /his/doctorPrescribeDrug → /his/doctorPrescribeDrug (直接透传) ===
-      // === /his/doctorPrescribe → /his/doctorPrescribe (直接透传) ===
-      // === /his/doctorProduct → /his/doctorProduct (直接透传) ===
-      // === /his/disease → /his/disease (直接透传) ===
-      // === /his/illnessLibrary → /his/illnessLibrary (直接透传) ===
-      // === /his/inquiryDisease → /his/inquiryDisease (直接透传) ===
-      // === /his/inquiryOrderPing → /his/inquiryOrderPing (直接透传) ===
-      // === /his/inquiryTemp → /his/inquiryTemp (直接透传) ===
-      // === /his/hospital → /his/hospital (直接透传) ===
-      // === /his/department → /his/department (直接透传) ===
-      // === /his/vessel → /his/vessel (直接透传) ===
-      // === /his/chineseMedicine → /his/chineseMedicine (直接透传) ===
-      // === /his/famousPrescribe → /his/famousPrescribe (直接透传) ===
-      // === /his/medicatedFood → /his/medicatedFood (直接透传) ===
-      // === /his/healthLife → /his/healthLife (直接透传) ===
-      // === /his/healthHistoryTemp → /his/healthHistoryTemp (直接透传) ===
-      // === /his/physicalReportTemplate → /his/physicalReportTemplate (直接透传) ===
-      // === /his/physicalReportTemplateField → /his/physicalReportTemplateField (直接透传) ===
-      // === /his/testReport → /his/testReport (直接透传) ===
-      // === /his/testTemp → /his/testTemp (直接透传) ===
-      // === /his/testTempItem → /his/testTempItem (直接透传) ===
-      // === /his/template → /his/template (直接透传) ===
-      // === /his/questions → /his/questions (直接透传) ===
-      // === /his/answer → /his/answer (直接透传) ===
-      // === /his/packageCate → /his/packageCate (直接透传) ===
-      // === /his/packageSolarTerm → /his/packageSolarTerm (直接透传) ===
-      // === /his/packageFavorite → /his/packageFavorite (直接透传) ===
-      // === /his/packageOrder → /his/packageOrder (直接透传) ===
-      // === /his/dfAccount → /his/dfAccount (直接透传) ===
-      // === /his/hfpayConfig → /his/hfpayConfig (直接透传) ===
-      // === /his/doctorAdvice → /his/doctorAdvice (直接透传) ===
-      // === /his/homeView → /his/homeView (直接透传) ===
-      // === /his/homeArticle → /his/homeArticle (直接透传) ===
-      // === /his/homeCategory → /his/homeCategory (直接透传) ===
-      // === /his/articleCate → /his/articleCate (直接透传) ===
-      // === /his/articleViews → /his/articleViews (直接透传) ===
-      // === /his/caseArticle → /his/caseArticle (直接透传) ===
-      // === /his/adv → /his/adv (直接透传) ===
-      // === /his/price → /his/price (直接透传) ===
-      // === /his/appVersion → /his/appVersion (直接透传) ===
-      // === /his/express → /his/express (直接透传) ===
-      // === /his/userAddress → /his/userAddress (直接透传) ===
-      // === /his/userCoupon → /his/userCoupon (直接透传) ===
-      // === /his/merchantAppConfig → /his/merchantAppConfig (直接透传) ===
-      // === /his/pharmacist → /his/pharmacist (直接透传) ===
-      // === /his/complaint → /his/complaint (直接透传) ===
-      // === /his/healthArticle → /his/healthArticle (直接透传) ===
-      // === /his/promotionActive → /his/promotionActive (直接透传) ===
-      // === /his/promotionActiveLog → /his/promotionActiveLog (直接透传) ===
-      // === /his/logs → /his/logs (直接透传) ===
-      // === /his/userNewTask → /his/userNewTask (直接透传) ===
-      // === /his/divItem → /his/divItem (直接透传) ===
-      // === /his/icd → /his/icd (直接透传) ===
-      // === /his/aiWorkflow → /his/aiWorkflow (直接透传) ===
-      // === /his/healthData → /his/healthData (直接透传) ===
-      // === /his/inquiryOrder → /his/inquiryOrder (直接透传) ===
-      // === /his/drugReportCount → /his/drugReportCount (直接透传) ===
-      // === /his/doctor → /his/doctor (直接透传) ===
-      // === /his/prescription → /his/prescription (直接透传) ===
-      // === /his/drugReport → /his/drugReport (直接透传) ===
-      // === /his/exportTask → /his/exportTask (直接透传) ===
-      // === /his/healthTongue → /his/healthTongue (直接透传) ===
-      // === /his/healthRecord → /his/healthRecord (直接透传) ===
-      // === /his/diagnosis → /his/diagnosis (直接透传) ===
-      // === /his/healthRecordTemplate → /his/healthRecordTemplate (直接透传) ===
-      // === /his/healthTongueQuestion → /his/healthTongueQuestion (直接透传) ===
-      // === /his/followPlan → /his/followPlan (直接透传) ===
-      // === /his/recoveryRecord → /his/recoveryRecord (直接透传) ===
-      // === /his/recoveryPlan → /his/recoveryPlan (直接透传) ===
-      // === /his/healthReport → /his/healthReport (直接透传) ===
-      // === /his/inquiryOrderReport → /his/inquiryOrderReport (直接透传) ===
-      // === /his/inquiryDisease → /his/inquiryDisease (直接透传) ===
-      // === /his/integralGoods → /his/integralGoods (直接透传) ===
-      // === /his/integralOrder → /his/integralOrder (直接透传) ===
-      // === /his/redPacket → /his/redPacket (直接透传) ===
-
-      // === /company/wxAccount → /company/wxUser (微信账号) ===
-      [process.env.VUE_APP_BASE_API + '/company/wxAccount']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/company/wxAccount']: '/company/wxUser' }
-      },
-      // === /user/darkRoom → /store/user/darkRoomList (小黑屋) ===
-      [process.env.VUE_APP_BASE_API + '/user/darkRoom']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/user/darkRoom']: '/store/user/darkRoomList' }
-      },
-      // === /user/transfer → /system/approval (转接管理) ===
-      [process.env.VUE_APP_BASE_API + '/user/transfer']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/user/transfer']: '/system/approval' }
-      },
-      // === /lobster/billing → /workflow/lobster/billing (龙虾计费) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/billing']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/billing']: '/workflow/lobster/billing' }
-      },
-      // === /lobster/prompt → /workflow/lobster/prompt (提示词) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/prompt']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/prompt']: '/workflow/lobster/prompt' }
-      },
-      // === /lobster/api-registry → /workflow/lobster/api-registry (接口注册中心) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/api-registry']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/api-registry']: '/workflow/lobster/api-registry' }
-      },
-      // === /lobster/dead-letter → /workflow/lobster/dead-letter (死信队列) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/dead-letter']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/dead-letter']: '/workflow/lobster/dead-letter' }
-      },
-      // === /lobster/event-audit → /workflow/lobster/event-audit (节点审核) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/event-audit']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/event-audit']: '/workflow/lobster/event-audit' }
-      },
-      // === /lobster/optimization → /workflow/lobster/optimization (AI优化建议) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/optimization']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/optimization']: '/workflow/lobster/optimization' }
-      },
-      // === /lobster/sales-corpus → /workflow/lobster/sales-corpus (销冠语料) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/sales-corpus']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/sales-corpus']: '/workflow/lobster/sales-corpus' }
-      },
-      // === /lobster/model-config → /company/aiProvider (模型配置→AI供应商) ===
-      [process.env.VUE_APP_BASE_API + '/lobster/model-config']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/lobster/model-config']: '/company/aiProvider' }
-      },
-      // === /hisStore/storeOrder → /store/storeOrder (商城订单) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeOrder']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeOrder']: '/store/storeOrder' }
-      },
-      // === /hisStore/storeProduct → /store/storeProduct (商城商品) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeProduct']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeProduct']: '/store/storeProduct' }
-      },
-      // === /hisStore/storeProductPackage → /store/storeProductPackage (商品套餐) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeProductPackage']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeProductPackage']: '/store/storeProductPackage' }
-      },
-      // === /hisStore/storePayment → /store/storePayment (门店支付) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storePayment']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storePayment']: '/store/storePayment' }
-      },
-      // === /hisStore/userOnlineState → /store/userOnlineState (用户在线状态) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/userOnlineState']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/userOnlineState']: '/store/userOnlineState' }
-      },
-      // === /hisStore/storeProductCategory → /store/storeProductCategory (商品分类) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeProductCategory']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeProductCategory']: '/store/storeProductCategory' }
-      },
-      // === /live/liveData → /liveData/liveData (直播数据) ===
-      [process.env.VUE_APP_BASE_API + '/live/liveData']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/live/liveData']: '/liveData/liveData' }
-      },
-      // === /live/liveConfig → /live/config (直播配置) ===
-      [process.env.VUE_APP_BASE_API + '/live/liveConfig']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/live/liveConfig']: '/live/config' }
-      },
-      // === /live/liveConsole → /live/liveVideo (直播控制台→直播视频) ===
-      [process.env.VUE_APP_BASE_API + '/live/liveConsole']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/live/liveConsole']: '/live/liveVideo' }
-      },
-      // === /course/courseAnswerlogs → /course/courseAnswerLog (答题记录) ===
-      [process.env.VUE_APP_BASE_API + '/course/courseAnswerlogs']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/course/courseAnswerlogs']: '/course/courseAnswerLog' }
-      },
-      // === /course/coursePlaySourceConfig → /course/playSourceConfig (播放源配置) ===
-      [process.env.VUE_APP_BASE_API + '/course/coursePlaySourceConfig']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/course/coursePlaySourceConfig']: '/course/playSourceConfig' }
-      },
-      // === /course/courseUserStatistics → /course/userWatchStatistics (用户统计) ===
-      [process.env.VUE_APP_BASE_API + '/course/courseUserStatistics']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/course/courseUserStatistics']: '/course/userWatchStatistics' }
-      },
-      // === /course/category → /course/userCourseCategory (课程分类) ===
-      [process.env.VUE_APP_BASE_API + '/course/category']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/course/category']: '/course/userCourseCategory' }
-      },
-      // === /hisStore/storeOrderAudit → /store/storeOrderAudit (订单审核) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeOrderAudit']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeOrderAudit']: '/hisStore/fsStoreOrderAuditScrm' }
-      },
-      // === /hisStore/storeOrderOffline → /hisStore/fsStoreOrderOfflineScrm (线下订单) ===
-      [process.env.VUE_APP_BASE_API + '/hisStore/storeOrderOffline']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/hisStore/storeOrderOffline']: '/hisStore/fsStoreOrderOfflineScrm' }
-      },
-      // === /qw/QwWorkTask/qw/list → /qw/workTask/list (企微任务) ===
-      [process.env.VUE_APP_BASE_API + '/qw/QwWorkTask/qw']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/qw/QwWorkTask/qw']: '/qw/workTask' }
-      },
-      // === /crm/customer/list → /crm/customer/getCustomerList (客户管理) ===
-      [process.env.VUE_APP_BASE_API + '/crm/customer/list']: {
-        target: 'http://localhost:8004',
-        changeOrigin: true,
-        pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/crm/customer/list']: '/crm/customer/getCustomerList' }
-      },
-
       // watch-api → fs-watch 微服务(需要单独启动 fs-watch)
       [process.env.VUE_APP_BASE_API + '/watch-api']: {
         target: 'http://localhost:8010',
@@ -701,7 +47,8 @@ module.exports = {
         pathRewrite: { ['^' + process.env.VUE_APP_BASE_API + '/watch-api']: '' }
       },
 
-      // ===== 默认所有其他请求 → fs-admin-saas(8004) 租户服务端 =====
+      // ===== 默认所有其他请求 → fs-admin-saas(8004) 租户总后台 =====
+      // 租户销售端(总公司/分公司)走 fs-company(8006) + ylrz_saas_his_scrm_companyUI
       [process.env.VUE_APP_BASE_API]: {
         target: 'http://localhost:8004',
         changeOrigin: true,