Files
happy-life-star/docs/superpowers/specs/2026-06-27-sms-login-config-design.md
T

208 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
author: system
created_at: 2026-06-27
purpose: 短信登录开关与通用系统配置功能设计
---
# 短信登录开关与通用系统配置设计
## 背景
当前系统未接入真实短信服务商,短信验证码使用硬编码 `123456`。小程序登录页同时展示「微信一键登录」和「手机号+验证码登录」两种方式,SMS 相关元素始终可见。
需要在管理后台增加系统配置管理功能,通过「短信登录开关」控制小程序端是否展示手机号短信登录入口。短信未启用时,小程序登录页只显示微信授权登录。
## 方案选择
采用 **方案 AKey-Value 通用配置表**
- 新建 `t_system_config` 表,key-value 结构
- 通用性强,后续加新配置只需 INSERT 一行数据,不用改表结构
- 复杂度可控,管理后台根据 `value_type` 动态渲染对应控件
## 详细设计
### 一、数据库设计
#### 新建表 `t_system_config`
```sql
CREATE TABLE t_system_config (
id VARCHAR(64) PRIMARY KEY,
config_key VARCHAR(100) NOT NULL UNIQUE COMMENT '配置唯一标识',
config_value VARCHAR(500) NOT NULL DEFAULT '' COMMENT '配置值',
value_type VARCHAR(20) NOT NULL DEFAULT 'string' COMMENT '值类型: boolean/string/number/json',
config_group VARCHAR(50) NOT NULL DEFAULT 'system' COMMENT '配置分组: system/login/notification',
config_name VARCHAR(100) NOT NULL DEFAULT '' COMMENT '显示名称',
description VARCHAR(300) DEFAULT '' COMMENT '配置说明',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序号',
is_visible TINYINT NOT NULL DEFAULT 1 COMMENT '是否在管理后台可见: 0-隐藏, 1-显示',
create_by VARCHAR(64) DEFAULT NULL,
create_time DATETIME DEFAULT NULL,
update_by VARCHAR(64) DEFAULT NULL,
update_time DATETIME DEFAULT NULL,
is_deleted TINYINT NOT NULL DEFAULT 0
) COMMENT = '系统配置表';
```
#### 初始数据
```sql
INSERT INTO t_system_config (id, config_key, config_value, value_type, config_group, config_name, description, sort_order, is_visible, create_time, update_time, is_deleted)
VALUES (
REPLACE(UUID(), '-', ''),
'sms_login_enabled',
'false',
'boolean',
'login',
'短信登录',
'是否启用手机号+短信验证码登录方式',
1,
1,
NOW(),
NOW(),
0
);
```
### 二、后端设计
#### 新增文件
| 层 | 文件 | 说明 |
|---|---|---|
| Entity | `SystemConfig.java` | 继承 `BaseEntity`,映射 `t_system_config` |
| Mapper | `SystemConfigMapper.java` | MyBatis-Plus 基础 CRUD |
| Service | `SystemConfigService.java` | 接口定义 |
| Service | `SystemConfigServiceImpl.java` | 业务逻辑实现 |
| Controller | `SystemConfigController.java` | 管理端接口,需 admin 登录 |
| DTO | `SystemConfigUpdateRequest.java` | 更新请求体(key + value |
| DTO | `LoginConfigResponse.java` | 返回给小程序的登录方式配置 |
#### 接口设计
**管理端接口(需要 admin token):**
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/admin/systemConfig/list` | 获取所有可见配置列表(`is_visible=1` |
| PUT | `/admin/systemConfig/update` | 批量更新配置值,传入 `List<SystemConfigUpdateRequest>` |
**公开接口(不需要登录,小程序登录页调用):**
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/auth/loginConfig` | 返回当前启用的登录方式 |
`/auth/loginConfig` 返回格式:
```json
{
"code": 200,
"data": {
"wechatLoginEnabled": true,
"smsLoginEnabled": false
}
}
```
#### 核心逻辑
1. `SystemConfigService` 提供 `getConfigValue(String key)` 方法
2. 内部做 Redis 缓存,缓存 key 为 `system_config:{config_key}`
3. 更新配置时同步清除对应缓存
4. `/auth/loginConfig` 读取 `sms_login_enabled` 配置值,组装 `LoginConfigResponse` 返回
5. 管理端更新接口接收 `List<SystemConfigUpdateRequest>`,支持一次提交多个配置变更
6. `/auth/loginConfig``WebMvcConfig` 白名单中放行(与 `/auth/login``/auth/wechat/login` 同级)
### 三、管理后台设计
#### 路由配置
`web-admin/src/router/index.ts` 中新增:
```ts
{
path: '/system',
component: Layout,
redirect: '/system/settings',
meta: { title: '系统设置', icon: 'Setting' },
children: [
{
path: 'settings',
name: 'SystemSettings',
component: () => import('@/views/system/SystemSettings.vue'),
meta: { title: '基础设置' }
}
]
}
```
#### 页面设计
**文件**`web-admin/src/views/system/SystemSettings.vue`
**页面结构**
- 顶部:页面标题「基础设置」+ 保存按钮
- 内容区:按 `config_group` 分组展示配置项
- 每个配置项根据 `value_type` 渲染不同控件:
- `boolean``el-switch` 开关
- `string``el-input` 输入框
- `number``el-input-number` 数字输入框
- 当前只有一个配置项:「短信登录」开关,下方显示描述文字
- 点击「保存」调用批量更新接口
#### API 封装
新增 `web-admin/src/api/systemConfig.ts`
- `getSystemConfigList()` → GET `/admin/systemConfig/list`
- `updateSystemConfig(list)` → PUT `/admin/systemConfig/update`
### 四、小程序登录页设计
#### 数据获取
在登录页 `onMounted` 时调用 `/auth/loginConfig` 接口:
```js
const loginConfig = ref({ wechatLoginEnabled: true, smsLoginEnabled: false })
onMounted(async () => {
try {
const res = await getLoginConfig()
loginConfig.value = res.data
} catch (e) {
// 接口失败时默认只显示微信登录
loginConfig.value = { wechatLoginEnabled: true, smsLoginEnabled: false }
}
})
```
#### 条件渲染
`v-if="loginConfig.smsLoginEnabled"` 控制以下元素的显示:
- 分隔线(「或使用手机号登录」)
- 手机号输入框
- 验证码输入框 + 获取验证码按钮
- 「开启旅程」手机号登录按钮
始终显示的元素:
- 品牌标题区域
- 「微信一键登录」按钮
- 底部协议文字
#### 代码处理
- 新增 `services/auth.js` 中的 `getLoginConfig()` 方法
- 短信相关的 `ref``phone``code``countdown` 等)和方法保留不动,只是 `v-if` 不渲染
- 不删除任何现有短信登录代码,后续启用短信时只需将配置改为 `true` 即可
## 验收标准
1. 管理后台出现「系统设置」菜单,可看到「短信登录」开关
2. 开关默认关闭(`false`
3. 小程序登录页在短信关闭时只显示微信登录按钮,无手机号表单
4. 管理后台将开关打开后,小程序刷新登录页可看到手机号+验证码表单
5. 后端编译通过,部署到服务器后验收正常
6. 浏览器 Console 无报错