# 2026-04-12 工作日志 ## 项目:小程序改造规划 ### 背景 用户需要为 websopy-mp 小程序增加: - 🛠️ **开发者中心** - 面向开发者,围绕项目展开 - 🏢 **企业控制台** - 面向企业客户 ### 关键决策 1. **用户角色分两类**: - 开发者 (Developer):独立于企业存在,申请审核制 - 企业客户 (Enterprise):属于企业组织,购买产品开通 2. **开发模式**:独立开发,不复用现有模块(商城/分销/用户订单) 3. **核心围绕"项目"展开**: - 项目类型:基础/专业/企业 - 项目成员、API Key、应用关联 ### Phase 1 开发完成 ✅ 已完成以下功能开发: #### 新增目录结构 ``` src/ ├── developer/ # 🛠️ 开发者模块 │ ├── index.tsx # 开发者工作台 │ ├── project/ # 项目管理 │ │ ├── index.tsx # 项目列表 │ │ ├── create.tsx # 创建项目 │ │ └── [id]/ # 项目详情 │ ├── app/ # 应用管理 │ │ ├── index.tsx # 应用列表 │ │ ├── create.tsx # 创建应用 │ │ ├── [id]/ # 应用详情 │ │ └── api-keys/ # API Key 管理 │ └── docs/ # 开发者文档 │ ├── enterprise/ # 🏢 企业模块 │ ├── index.tsx # 企业工作台 │ ├── apps/ # 企业应用 │ │ ├── index.tsx # 应用列表 │ │ ├── [id]/ # 应用详情 │ │ └── purchase/ # 购买应用 │ ├── members/ # 成员管理 │ │ ├── index.tsx # 成员列表 │ │ └── invite/ # 邀请成员 │ ├── orders/ # 订单账单 │ │ ├── index.tsx # 订单列表 │ │ └── detail/ # 订单详情 │ ├── billing/ # 费用中心 │ └── settings/ # 企业设置 │ ├── api/developer/ # API 模块 │ ├── index.ts │ ├── developer.ts # 开发者 API │ └── enterprise.ts # 企业 API │ └── types/developer.ts # 类型定义 ``` #### 新增页面 - 首页角色入口卡片(开发者中心/企业控制台) - 开发者工作台 + 统计卡片 + 快捷操作 - 项目列表/创建/详情 - 应用列表/创建/详情 - 企业工作台 + 统计卡片 + 快捷操作 - 企业应用列表/购买/详情 - 成员列表/邀请 - 订单列表/详情(占位) - 费用中心/企业设置(占位) #### 新增 API - 项目管理 API - 应用管理 API - API Key 管理 API - 企业成员 API - 订单账单 API ### 待确认 - 后端 API 接口地址是否正确 - 是否需要权限验证 - 微信小程序码支持 --- ## Phase 2 开发完成 ✅ (2026-04-12 19:49) ### 新增功能模块 #### 1. API Key 完整管理 - 列表展示(名称/类型/状态/创建时间) - 创建 Key(名称/类型/备注) - 复制 AppId/AppSecret - 删除 Key - 状态筛选 #### 2. 项目成员管理 - 成员列表展示(头像/名称/角色) - 角色统计(所有者/管理员/开发者/查看者) - 邀请成员(用户名/角色选择) - 修改成员角色 - 移除成员 #### 3. 应用版本发布 - 版本列表(版本号/状态/环境) - 环境 Tab 筛选(全部/开发/预发布/生产) - 发布新版本(名称/版本号/环境/更新日志) - 状态标签(构建中/已发布/已回滚/构建失败) #### 4. 消息通知中心 - 通知列表(类型/标题/内容/时间) - 类型筛选(全部/系统/应用/成员/订单) - 未读数量徽标 - 标记已读/全部已读 - 删除通知 - 点击跳转详情 #### 5. 开发者申请 - 申请表单(姓名/手机/邮箱/公司/职位/经验) - 申请记录列表 - 状态筛选(待审核/已通过/已拒绝) - 审核备注展示 #### 6. 权限审批 - 申请列表(申请人/类型/目标/状态) - Tab 筛选(待审核/已通过/已拒绝/全部) - 待审核数量徽标 - 通过/拒绝操作 - 审核备注展示 ### 新增/扩展的页面 ``` src/developer/ ├── project/[id]/ │ ├── members.tsx # 项目成员管理 ✅ │ ├── members.scss │ ├── api-keys.tsx # 项目级 API Key │ ├── api-keys.scss │ ├── api-keys.config.ts │ ├── settings.tsx # 项目设置 │ └── settings.scss ├── app/[id]/ │ ├── version.tsx # 版本管理 ✅ │ ├── version.scss │ ├── config.tsx # 应用配置 │ ├── publish.tsx # 发布管理 │ └── *.config.ts ├── notification/ # 消息通知 ✅ │ ├── index.tsx │ └── index.scss ├── developer/ │ ├── apply.tsx # 开发者申请 ✅ │ ├── apply.scss │ └── profile.tsx # 开发者资料 ├── docs/ │ ├── quickstart.tsx # 快速开始 │ └── api-docs.tsx # API 文档 └── market/ # 开发者市场 └── index.tsx src/enterprise/ ├── apps/[id]/ │ ├── monitor.tsx # 运营监控 │ ├── analytics.tsx # 数据分析 │ └── settings.tsx # 应用设置 ├── members/ │ ├── roles.tsx # 角色权限 │ └── audit.tsx # 权限审批 ✅ ├── orders/ │ ├── invoice.tsx # 发票管理 │ └── bills.tsx # 账单明细 ├── billing/ │ ├── consumption.tsx # 消费明细 │ ├── recharge.tsx # 充值中心 │ └── coupons.tsx # 优惠券 ├── settings/ │ ├── info.tsx # 企业信息 │ ├── domain.tsx # 域名配置 │ └── security.tsx # 安全设置 └── developer/ ├── index.tsx # 开发者入口 └── apply.tsx # 申请开发者 ``` ### 扩展的类型定义 ```typescript // 消息通知 interface Notification { id, type, title, content, data, isRead, readTime, createTime } // 权限申请 interface Apply { id, type, applicantId, applicantName, applicantAvatar, targetId, targetName, reason, status, reviewerId, reviewerName, reviewTime, reviewRemark, createTime } ``` ### 扩展的 API ```typescript // 通知相关 pageNotification, getUnreadCount, markAsRead, markAllAsRead, deleteNotification // 申请相关 pageApply, pageMyApply, createApply, reviewApply ``` ### 路由配置更新 新增 20+ 个页面路由 --- ## Phase 3 开发完成 ✅ (2026-04-12 20:15) ### 新增功能模块 #### 1. CI/CD 流水线 - **构建任务列表**:状态筛选/触发构建/取消构建/查看详情 - **构建详情**:构建信息/Git 信息/构建日志/构建产物 - **部署列表**:环境筛选/部署统计/触发部署/回滚操作 - **部署详情**:部署进度/日志/回滚功能 - **流水线配置**:启用/禁用、自动部署、分支规则、环境变量、Webhook #### 2. 运营监控/数据分析 - **实时数据看板**:UV/PV/API 调用/错误数/Live 指示器 - **今日概览**:UV/PV/API 调用统计卡片 - **数据趋势**:图表占位(可集成 ECharts) - **性能指标**:核心指标展示/趋势标签/错误统计 - **用户分析**:活跃用户/新增用户/留存率/地域分布/流量来源 - **页面排行**:PV/UV 排行 #### 3. 发票管理 - **发票列表**:状态筛选/发票详情/取消申请 - **可开票金额**:实时金额展示 - **申请发票**:抬头选择/金额输入/提交申请 - **发票抬头管理**:增删改查/默认设置 - **发票统计**:申请总数/已开票数量 #### 4. SSO 单点登录 - **SSO 配置**:OIDC/SAML/CAS/LDAP/OAuth2 提供商支持 - **连接配置**:Issuer/Client ID/Client Secret/授权 URL 等 - **用户同步**:同步开关/自动创建/默认角色 - **服务提供商信息**:Entity ID/ACS URL(可复制) - **操作日志**:登录/登出/错误记录 ### 新增类型定义 ``` src/types/ ├── index.ts # 统一导出 ├── cicd.ts # CI/CD 流水线类型 ├── analytics.ts # 数据分析类型 ├── invoice.ts # 发票管理类型 └── sso.ts # SSO 单点登录类型 ``` ### 新增 API ``` src/api/ ├── cicd.ts # CI/CD 流水线 API ├── analytics.ts # 数据分析 API ├── invoice.ts # 发票管理 API └── sso.ts # SSO 单点登录 API ``` ### 新增页面 ``` src/developer/app/[id]/ ├── builds.tsx # 构建列表 ├── builds.scss ├── build/[id].tsx # 构建详情 ├── build/[id].scss ├── deploys.tsx # 部署列表 ├── deploys.scss ├── deploy/[id].tsx # 部署详情 ├── deploy/[id].scss ├── pipeline.tsx # 流水线配置 ├── pipeline.scss ├── analytics.tsx # 运营监控 └── analytics.scss src/enterprise/ ├── orders/ │ ├── invoice.tsx # 发票管理 │ └── invoice.scss └── settings/ ├── sso.tsx # SSO 配置 └── sso.scss ``` ### Phase 3 完成的功能 | 功能 | 页面 | 状态 | |------|------|------| | **CI/CD 构建** | 构建列表/详情 | ✅ 完整 | | **CI/CD 部署** | 部署列表/详情/回滚 | ✅ 完整 | | **流水线配置** | 流水线设置 | ✅ 完整 | | **运营监控** | 数据看板/趋势 | ✅ 完整 | | **发票管理** | 发票列表/申请/抬头 | ✅ 完整 | | **SSO 单点登录** | SSO 配置/日志 | ✅ 完整 | --- ### 待开发 (Phase 4) | 功能 | 说明 | |------|------| | SDK 下载 | 各语言 SDK 下载页面 | | 工单系统 | 客服工单/技术支持 | | 账单导出 | 账单 Excel 导出 | | 数据导入 | 企业数据批量导入 | --- ## Phase 4 开发完成 ✅ (2026-04-12 20:25) ### 新增功能模块 #### 1. SDK 下载中心 - **SDK 分类浏览**:Web/移动/服务端/小程序 - **SDK 列表展示**:图标/版本/下载量/Star - **搜索功能**:按名称/描述搜索 - **SDK 详情弹窗**:版本/依赖/更新日志 - **一键安装**:NPM 命令复制/直接下载 #### 2. 工单系统 - **工单列表**:状态/类型/优先级筛选 - **工单统计**:总数/待处理/处理中/已解决 - **创建工单**:类型/优先级/标题/内容 - **工单详情**:沟通记录/解决方案/回复 - **工单评价**:满意度评分/反馈 #### 3. FAQ 常见问题 - **分类浏览**:API/账单/账户/SDK 等分类 - **搜索功能**:关键词搜索 - **展开查看**:问题详情/回答 - **有帮助/没帮助**:用户反馈 #### 4. 数据导入 - **导入记录列表**:状态/进度/错误统计 - **模板下载**:各类数据导入模板 - **字段说明**:必填/类型/示例 - **错误详情**:行号/字段/错误原因/建议 #### 5. 账单导出 - **导出记录**:任务列表/状态/文件信息 - **新建导出**:类型/格式/时间范围 - **下载管理**:文件下载/过期提醒 - **格式支持**:Excel/CSV/PDF ### 新增类型定义 ``` src/types/ ├── sdk.ts # SDK 下载类型 ├── ticket.ts # 工单系统类型 └── import.ts # 导入导出类型 ``` ### 新增 API ``` src/api/ ├── sdk.ts # SDK 下载 API ├── ticket.ts # 工单系统 API └── import.ts # 导入导出 API ``` ### 新增页面 ``` src/developer/ ├── sdk/ │ └── index.tsx # SDK 下载中心 ├── ticket/ │ ├── index.tsx # 工单中心 │ ├── detail.tsx # 工单详情 │ └── faq.tsx # FAQ 常见问题 src/enterprise/ ├── settings/ │ └── import.tsx # 数据导入 └── orders/ └── bills.tsx # 账单导出 ``` ### Phase 4 完成的功能 | 功能 | 页面 | 状态 | |------|------|------| | **SDK 下载中心** | 列表/详情/下载 | ✅ 完整 | | **工单系统** | 列表/创建/详情/评价 | ✅ 完整 | | **FAQ 常见问题** | 分类/搜索/反馈 | ✅ 完整 | | **数据导入** | 导入记录/模板下载 | ✅ 完整 | | **账单导出** | 导出记录/新建导出 | ✅ 完整 | --- ## 📊 四个 Phase 累计完成 | Phase | 功能数 | 页面数 | API 数 | |-------|--------|--------|--------| | Phase 1 | 基础框架 | 15+ | 10+ | | Phase 2 | API Key/成员/通知等 | 20+ | 15+ | | Phase 3 | CI-CD/监控/发票/SSO | 10+ | 20+ | | Phase 4 | SDK/工单/导入/导出 | 10+ | 15+ | | **合计** | - | **55+** | **60+** | --- ## Bug 修复 (2026-04-12 21:00) ### 已修复的问题 #### 1. JSX 语法错误 - 修复 8 个被截断的 `.tsx` 文件(appCredential、appEvent、appUser、appVersion) - 修复 `user/apps/index.tsx` 中的 `>` token 问题 #### 2. API 导入问题 - 修复 `analytics.ts`、`cicd.ts`、`invoice.ts`、`sso.ts` 的 request 导入 - 添加缺失的 `ImportType` 导入 - 修复 `sdk.ts` 未使用的导入 #### 3. Config 文件错误 - 修复所有 `defineComponentConfig` → `definePageConfig` - 涉及 12 个 config 文件 #### 4. 组件命名错误 - 修复 `PullRefresh` → `PullToRefresh`(nutui 组件) - 涉及 4 个文件 #### 5. taro-ui 依赖问题 - 将 `taro-ui` 替换为 `nutui-react-taro` - 重写 `invoice.tsx`、`sso.tsx` 页面 #### 6. SCSS 导入问题 - 修复 `notification/index.tsx` 的 scss 导入路径 #### 7. 类型定义 - 创建 `src/types/developer.ts` 缺失类型文件 - 修复 `RequestConfig` 缺少 `params` 属性 ### 项目状态 - ✅ 编译成功 - ✅ 开发服务器运行中 (端口: dist) --- ## 任务:改造 invite/index.tsx 登录流程 ### 需求 - `loginByOpenId` 已注册 → 显示**「确认加入」**按钮 - `loginByOpenId` 未注册 → 显示**「微信手机号快速加入」**按钮(走授权流程) ### 关键逻辑 1. `checkLoginStatus`:调用 `loginByOpenId` 检查用户是否已注册 2. 已注册:`isLoggedIn = true`,显示「确认加入」按钮 3. 未注册:`isLoggedIn = false`,显示「微信手机号授权」按钮 4. 授权成功 → 调用 `loginByMpWxPhone` 完成注册/登录 → 自动执行加入应用 ### 文件修改 - `src/passport/invite/index.tsx` - 完整重写,区分已登录/未注册两种按钮状态 --- ## 任务:未注册用户在邀请页内完成授权注册,不跳登录页 ### 需求 - loginByOpenId 未注册 → 在页面内显示「微信手机号授权」按钮 - 授权成功 → 调用 `loginByMpWxPhone` 注册/登录 → 自动执行加入应用 - 不再跳转 passport/login 页面 ### 关键逻辑 1. `checkLoginStatus`:已注册 isLoggedIn=true,未注册 isLoggedIn=false,**两种情况都显示邀请页** 2. 未注册按钮:`open-type="getPhoneNumber"` → `handleGetPhoneNumber` - 授权码调 `SERVER_API_URL/wx-login/loginByMpWxPhone` 完成注册登录 - 保存 token → isLoggedIn=true → 立即调 `doJoinApp` 3. 已注册按钮:普通 `onClick` → `handleConfirmJoin` → `doJoinApp(access_token)` 4. `doJoinApp`:统一加入接口,请求头带 `Authorization: Bearer {access_token}` ### 文件修改 - `src/passport/invite/index.tsx` - 完整重写(彻底移除跳登录页逻辑) --- ## 修复:「授权码不能为空」报错 ### 问题 后端 `/api/_app/developer/invite/accept` 接口强制要求传 `code`(微信授权码),不传就报「授权码不能为空」。 ### 解决 统一用一个 `getPhoneNumber` 按钮处理两种场景: - **已注册**:文字「确认加入」→ 触发 getPhoneNumber → `doJoinApp(code, accessToken)` - **未注册**:文字「微信手机号快速加入」→ 触发 getPhoneNumber → 先 `loginByMpWxPhone` 注册 → 再 `wx.login()` 获 code → `doJoinApp(newCode, access_token)` ### doJoinApp 参数 ```ts doJoinApp(wxCode: string, accessToken: string) // 请求体带 code,请求头带 Authorization: Bearer xxx ``` --- ## 优化:已登录用户不弹手机号授权 ### 改动 - 已登录按钮:普通 `onClick`,文字「确认加入」 - 未注册按钮:`getPhoneNumber` 授权,文字「微信手机号快速加入」 ### 逻辑差异 | 用户状态 | 按钮类型 | 获取 code 方式 | |------|------|------| | 已登录 | 普通 onClick | `wx.login()` | | 未注册 | getPhoneNumber | 授权回调的 `code` | ### 文件修改 - `src/passport/invite/index.tsx` - 按钮区分两种类型,已登录用普通 onClick --- ## 优化:已登录用户不强制勾选协议 ### 改动 - 已登录用户点击「确认加入」时,不再检查 `agreementChecked` - 未注册用户仍需勾选协议后才能授权手机号 ### 文件修改 - `src/passport/invite/index.tsx` - `handleConfirmJoin` 移除协议检查 --- ## 修复:后端需要手机号授权码 ### 问题 后端 `invite/accept` 接口只接受 `getPhoneNumber` 获取的手机号授权码,用 `wx.login()` 的 code 会报「获取手机号失败」。 ### 解决 两种用户状态都走 `getPhoneNumber` 按钮: - 已登录:文字「确认加入」,回调 `handleConfirmJoinGetPhoneNumber` - 未注册:文字「微信手机号快速加入」,回调 `handleGetPhoneNumber` ### 差异 | 用户状态 | 回调 | 行为 | |------|------|------| | 已登录 | `handleConfirmJoinGetPhoneNumber` | 直接用 `code + access_token` 调加入接口 | | 未注册 | `handleGetPhoneNumber` | 先 `loginByMpWxPhone` 注册登录,再调加入接口 | ### 文件修改 - `src/passport/invite/index.tsx` - 两种状态都用 getPhoneNumber 按钮 --- ## 任务:后端改造支持已登录用户直接加入 ### 问题 后端 `/api/_app/developer/invite/accept` 接口强制要求传 `code`(手机号授权码),导致已登录用户也需要弹手机号授权。 ### 后端改造方案 修改 `AppMpInviteController.acceptInvite` 方法: #### 1. 参数校验调整 - `code` 改为可选参数 - 不传 `code` 时,从 `Authorization` 头获取当前登录用户 #### 2. 双模式支持 ```java if (StrUtil.isBlank(code)) { // 模式一:已登录用户(通过 Authorization 头识别) userId = getCurrentUserId(); } else { // 模式二:未注册用户(通过手机号授权码获取手机号,创建用户) String phone = getPhoneByCode(code); userId = getOrCreateUserByPhone(phone); } ``` #### 3. getCurrentUserId 方法 - 尝试从 Spring Security Context 获取 - 如果获取不到(免登录接口),手动解析 `Authorization` 头的 JWT Token ### 前端配合改造 - 已登录用户:普通 `onClick` 按钮 → `handleConfirmJoin` → `doJoinAppForLoggedInUser`(不传 `code`) - 未注册用户:`getPhoneNumber` 按钮 → `handleGetPhoneNumber` → `doJoinAppForNewUser`(传 `code`) ### 文件修改 **后端:** - `/Users/gxwebsoft/JAVA/websopy-java/src/main/java/com/gxwebsoft/app/controller/AppMpInviteController.java` - `acceptInvite` 方法支持 `code` 可选 - 使用 `BaseController.getLoginUserId()` 获取当前登录用户(无需额外方法) **前端:** - `/Users/gxwebsoft/VUE/websopy-mp/src/passport/invite/index.tsx` - 已登录按钮改为普通 `onClick` - 新增 `handleConfirmJoin` 方法 - 拆分 `doJoinApp` 为 `doJoinAppForLoggedInUser` 和 `doJoinAppForNewUser` --- ## 修复:开发者中心加载不到应用 ### 问题 用户通过邀请加入应用后,开发者中心显示「加载中...」,无法显示应用列表。 ### 原因 - 前端 `developer/index.tsx` 只调用了 `pageMyApp` 接口(查询用户**创建**的应用) - 用户通过邀请加入的应用属于**参与**的应用,不是创建的应用 - 后端 `loginByOpenId` 返回了应用列表,但前端没有使用这个数据 ### 解决 1. **前端改造**:`loadData` 同时调用两个接口: - `pageMyApp` - 查询创建的应用 - `pageJoinedApp` - 查询参与的应用(新增 API) - 合并两个列表,根据 `productId` 去重 2. **新增 API**:`src/api/developer/developer.ts` 添加 `pageJoinedApp` 方法 ### 文件修改 - `src/developer/index.tsx` - `loadData` 同时查询创建和参与的应用 - `src/api/developer/developer.ts` - 新增 `pageJoinedApp` 方法