# 服务商端小程序 登录(UI 重设计 + 专用登录接口)开发设计文档 - 模块:`hugray-partner-miniapp`(前端)、`ruoyi-auth` / `ruoyi-user` / `ruoyi-api-system` / `ruoyi-gateway`(后端) - 日期:2026-10-14 - 需求来源: 1. “现在开始服务商小程序的开发,先把服务商小程序的登录页样式参考用户小程序的样式重新设计 ui 并开发”; 2. “服务商小程序登录提示令牌不能为空,服务商只需要账号加密码登录就行,不需要其他参数,看是否重新写个接口区分开来”。 - 风格参照:`hugray-user-miniapp/pages/login/index.vue` + `doc/design/用户端_登录注册_20261012.md` §3.5 视觉还原规格 - 改造目标文件: - 前端:`hugray-partner-miniapp/pages/login/index.vue`、`hugray-partner-miniapp/api/index.js` - 后端:`ruoyi-auth`、`ruoyi-user`、`ruoyi-api-system`、网关白名单 - 已确认决策(用户确认): 1. **品牌区完整复刻用户端**:`欢迎来到` + 代谢300 Logo + 英文标语 + 医学双背书 + 产业4.0标语卡; 2. **底板沿用浅蓝渐变**:165°、rgba .8 叠白底(`#D3E4F8` → `#BCD6F4` → `#ABCCEC`)+ 3 处微透十字 + 3 处白色点阵; 3. **表单面板式平铺**:输入框直接铺在渐变底上,不使用白色卡片承载; 4. **新接口路径** `/miniapp/auth/partner/login`(服务内 `/partner/login`),与用户端接口彻底区分; 5. **强校验服务商身份**:仅 `provider_flag='1'` 的账号可登录服务商端; 6. **合并错误提示**:账号不存在与密码错误统一返回「账号或密码错误」,防账号枚举。 --- ## 一、功能概述 本次包含两部分: | 序号 | 项 | 变化 | | --- | --- | --- | | 1 | 登录页视觉 | 由「深蓝导航栏 + 白底表单 + 通栏深蓝按钮」改为「用户端同款浅蓝渐变登录页(装饰层 + 品牌区 + 面板式表单 + 渐变胶囊按钮 + Home 条)」 | | 2 | 登录方式 | **不变**:账号 + 密码 | | 3 | 登录接口 | **变更**:由不存在且未白名单的 `/miniapp/auth/login` 改为新增的服务商专用接口 `/miniapp/auth/partner/login`,入参仅 `username` + `password` | | 4 | 服务商身份校验 | **新增**:按 username 查 `account_user`,校验 `provider_flag='1'` + 账号状态 + BCrypt 密码 | | 5 | 忘记密码入口 | **不变**:跳转 `/pages/login/forgot` | | 6 | 协议勾选与确认弹窗 | **不变**:逻辑保留,样式对齐用户端 | --- ## 二、报错根因(问题定位) 服务商端登录报「令牌不能为空」,为**双重根因**: 1. **接口不存在**:前端调用 `POST /miniapp/auth/login`,而 `ruoyi-auth` 的 `AccountAuthController` 仅有 `/sms/code`、`/phone/login`、`/phone/code-login`、`/account/register`、`/invite-qrcode`,**无用户名密码登录端点**。 2. **白名单缺失**:`/miniapp/auth/login` 未登记在网关 `security.ignore.whites`,未携带 token 访问时被 `AuthFilter` 直接拦截,返回 `HTTP 401 + 令牌不能为空`。 --- ## 三、现状与差异点 ### 3.1 现状 `pages/login/index.vue` 当前为深蓝导航栏 + 白底表单风格,`pages.json` 中该页已配置 `"navigationStyle": "custom"`。 ### 3.2 与用户端的差异(决定本次实现差异) | 维度 | 用户端登录页 | 服务商端登录页 | | --- | --- | --- | | 登录方式 | 微信一键登录 / 手机验证登录 | **账号 + 密码** | | 登录接口 | `/miniapp/auth/phone/login`、`/miniapp/auth/phone/code-login` | **`/miniapp/auth/partner/login`** | | 底部操作区 | 两个渐变胶囊按钮 + 协议行 + 注册入口 + Home 条 | **账号输入 + 密码输入 + 忘记密码 + 协议行 + 登录按钮 + Home 条** | | 品牌区 | 完整(欢迎来到 + Logo + 标语 + 背书 + 标语卡) | 本次对齐为**同款** | | 顶部导航 | 无导航栏,内容区 `paddingTop = 状态栏 + 40px` | 同左(去掉原深蓝导航栏) | | 协议文案 | 《用户协议》《隐私与权限》 | **不变**(保持服务商端既有文案) | ### 3.3 素材缺口与处理 服务商端 `static/` 原仅有 `logo.png`(与用户端 `logo.png` 为同一「YiOUS」深蓝图,MD5 一致)。本次品牌区新增 4 个素材: | 素材 | 来源 | 用途 | | --- | --- | --- | | `metabolism-300-logo.png` | 复制自用户端 | 品牌区官方 Logo(440×152rpx) | | `medical-plus-icon.png` | 复制自用户端 | 医学双背书「严谨医学循证」 | | `check-icon.png` | 复制自用户端 | 医学双背书「传递健康价值」 | | `industry-4-0-slogan-card.png` | 复制自用户端 | 产业4.0核心标语卡 | > `logo.png` 保留不删(服务商端其他页面可能仍在引用)。 --- ## 四、视觉规格(复用用户端已落地设计体系) 换算基准:设计稿 375pt → 750rpx(pt × 2 = rpx)。 | 元素 | 实现规格 | | --- | --- | | 页面底板 | 渐变 165°、rgba .8 叠白底:`#D3E4F8` 0% → `#BCD6F4` 50% → `#ABCCEC` 100% | | 微透十字 ×3 | 右上 160rpx(条宽 44)/ 中左 136rpx(条宽 36)/ 左下 200rpx(条宽 56) | | 白色点阵 ×3 | 左上 / 右上 / 右下,radial-gradient 平铺,步距 26rpx | | 内容区顶距 | `paddingTop = statusBarHeight + 40px`;左右 56rpx;元素间距 40rpx | | 欢迎语 | 「欢迎来到」52rpx / 500 / `#0F172A`,居中 | | 官方 Logo | `metabolism-300-logo.png` 440×152rpx | | 英译标语 | 「RESET METABOLISM & DELIVER HEALTH」22rpx / 600 / `#003E7E` / 字距 3rpx | | 医学双背书 | 图标 30rpx / 36.4×30rpx,项内 gap 12rpx、两项 gap 48rpx;文案 24rpx 600 `#1E293B` | | 标语卡 | `industry-4-0-slogan-card.png` 759×304rpx,上下负边距 -48rpx / -72rpx | | 表单标签 | 26rpx / 500 / `#334155`,下间距 18rpx | | 输入框 | H88rpx / R16 / 描边 2rpx `#CBD5E1` / 底色 `#F8FAFC`,内嵌 44rpx 图标(账号 / 盾牌),左右内边距 28rpx | | 忘记密码 | 右对齐,26rpx / 600 / `#1E5EBC` | | 登录按钮 | H96rpx / R48,渐变 90° `#1E5EBC` → `#003E7E`,30rpx 600 白字,shadow `0 12rpx 28rpx rgba(0,62,126,.2)` | | 协议勾选行 | 复选框 32rpx / R8(选中 `#003E7E`)+ 文案 26rpx(正文 `#64748B` / 链接 `#1E5EBC`) | | 底部 Home 条 | 270×10rpx / R5 `rgba(15,23,42,.145)` | | 边距体系 | 底部区左右 56rpx,叠加安全区 32rpx | | 协议确认弹窗 | 560rpx 宽 / R24,标题 34rpx 600 `#003E7E`,正文 28rpx `#64748B`,按钮行「取消 `#334155` / 我已阅读并同意 `#1E5EBC`」 | --- ## 五、接口设计(本次核心变更) ### 5.1 接口一览 | 接口 | 方法 | 网关路径 | 服务内路径 | 入参 | 返回 | | --- | --- | --- | --- | --- | --- | | 服务商登录(新增) | POST | `/miniapp/auth/partner/login` | `/partner/login` | `{ username, password }` | `{ access_token, expires_in }` | > 网关路由 `ruoyi-miniapp-auth`(`Path=/miniapp/auth/**` + `StripPrefix=2`)已存在,无需新增路由;**仅需把新路径加入白名单**。 ### 5.2 服务商身份模型(关键认知) 服务商**不是独立用户体系**,而是「会员(`account_user`)的另一重身份」: - 登录账号 / 密码直接用 `account_user.username / password`(BCrypt 密文); - `account_provider` 表只存公司资质与权益配置,用 `user_id` 与账号 1:1 关联; - `account_user.provider_flag = '1'` 标识该账号为服务商。 ### 5.3 登录鉴权链路 ``` POST /miniapp/auth/partner/login { username, password } 1. 入参非空校验(@NotBlank) 2. Feign 调 ruoyi-user 内部接口 GET /member/info/username/{username} → AccountMember(含 password 密文、providerFlag、status) 3. 账号不存在 → 抛「账号或密码错误」 4. providerFlag != '1' → 抛「该账号不是服务商账号」 5. status == '1'(停用) → 抛「账号已停用,请联系管理员」 6. BCrypt matchesPassword(password, member.password) 失败 → 抛「账号或密码错误」 7. 组装 LoginUser → TokenService.createToken → 返回 { access_token, expires_in } ``` ### 5.4 跨服务契约变更 `AccountMember`(`ruoyi-api-system`)新增两个字段:`password`(BCrypt 密文,仅供 auth 校验,且 AccountMember 全程不下发到 C 端)、`providerFlag`(服务商标识)。 > 说明:`AccountMember` 仅用于内部登录链路,`AccountAuthController` 对外返回的是令牌 Map 或空 R,不会把 member 直接下发,故不存在密码泄露风险。 --- ## 六、影响范围 | 类型 | 文件 | 变更 | | --- | --- | --- | | 前端页面 | `hugray-partner-miniapp/pages/login/index.vue` | 重写模板与样式;登录收尾逻辑修正 token 字段(`data.access_token`)与入参简化 | | 前端接口 | `hugray-partner-miniapp/api/index.js` | `login()` 改指 `/miniapp/auth/partner/login`,入参简化为 `{ username, password }` | | 静态资源 | `hugray-partner-miniapp/static/*` | 新增 4 个图片素材(复制自用户端) | | 认证服务 | `ruoyi-auth` 新增 `PartnerLoginBody` / `PartnerLoginService` / `AccountAuthController#partnerLogin` | 新增服务商登录端点与编排逻辑 | | 会员服务 | `ruoyi-user`:`IAccountUserService` + impl 新增 `selectAccountUserByUsername`;`AccountMemberInnerController` 新增 `/info/username/{username}` 并补充 password/providerFlag 映射 | 提供按用户名查询内部能力 | | 跨服务契约 | `ruoyi-api-system`:`AccountMember` 加字段;`RemoteAccountUserService` 加 `getMemberByUsername`;`RemoteAccountUserFallbackFactory` 补降级 | Feign 契约扩展 | | 网关配置 | `doc/nacos/dev/ruoyi-gateway-dev.yml`(同步 Nacos 配置中心) | `security.ignore.whites` 追加 `/miniapp/auth/partner/login` | | 数据库 | — | **无变更** | --- ## 七、验收清单 1. 登录页呈现浅蓝渐变底 + 3 十字 + 3 点阵装饰,风格与用户端一致;✔ 2. 品牌区完整(欢迎来到 + 代谢300 Logo + 英文标语 + 医学双背书 + 标语卡);✔ 3. 账号 / 密码输入框为面板式平铺(H88 / R16 / 浅底描边),带品牌图标;✔ 4. 「忘记密码」右对齐可点击,跳转 `/pages/login/forgot`;✔ 5. 协议勾选行 + 未勾选时弹确认弹窗,逻辑与现状一致;✔ 6. 登录按钮为渐变胶囊(`#1E5EBC → #003E7E`),点击可正常登录并 `reLaunch` 首页;✔ 7. 底部居中 Home 条;✔ 8. 页面无横向滚动 / 无内容溢出裁切。✔ 9. 服务商账号 + 正确密码 → 登录成功,`reLaunch` 首页;✔ 10. 非服务商账号 → 提示「该账号不是服务商账号」;✔ 11. 账号不存在或密码错误 → 统一提示「账号或密码错误」;✔ 12. 停用账号 → 提示「账号已停用,请联系管理员」。✔