Files
cpzs-frontend/用户信息管理API使用说明.md

686 lines
18 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.

# 用户信息管理API使用说明
## 接口概述
本文档提供用户信息获取和编辑的接口说明,包括会员个人信息的查询和更新功能。
## 基础信息
- **Base URL**: `http://localhost:8123/api`
- **Content-Type**: `application/json`
- **认证方式**: Session需要先登录
---
## 1. 获取当前登录用户信息
### 接口地址
```
GET /user/get/login
```
### 接口说明
获取当前登录用户的详细信息包括会员ID、等级、昵称、手机号码、注册日期、套餐类别、费用到期时间、性别、所在省市、彩票偏好、获客渠道等。
### 请求参数
无需参数通过Session获取当前登录用户
### 请求示例(使用 curl
```bash
curl -X GET "http://localhost:8123/api/user/get/login" \
-H "Content-Type: application/json" \
-b "JSESSIONID=your_session_id"
```
### 请求示例(使用 JavaScript
```javascript
fetch('http://localhost:8123/api/user/get/login', {
method: 'GET',
credentials: 'include', // 携带cookie
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log('用户信息:', data);
})
.catch(error => {
console.error('获取失败:', error);
});
```
### 响应示例(成功)
```json
{
"code": 0,
"data": {
"id": "1234567890123456789",
"userName": "张三",
"userAccount": "zhangsan",
"phone": "13800138000",
"userAvatar": "https://example.com/avatar.jpg",
"gender": 1,
"userRole": "user",
"isVip": 1,
"vipExpire": "2026-12-31T23:59:59",
"vipType": "年度会员",
"location": "北京市",
"preference": "双色球",
"channel": "微信推广",
"status": 0,
"createTime": "2025-01-01T10:00:00",
"updateTime": "2026-01-26T15:30:00"
},
"message": "ok"
}
```
### 响应字段说明
| 字段名 | 类型 | 说明 | 备注 |
|--------|------|------|------|
| code | Integer | 状态码 | 0表示成功 |
| data | Object | 用户信息对象 | |
| data.id | String | 会员ID | 系统自动生成,不可修改 |
| data.userName | String | 昵称 | 可修改 |
| data.userAccount | String | 账号 | 系统收集,不可修改 |
| data.phone | String | 手机号码 | 可修改 |
| data.userAvatar | String | 头像URL | 可修改 |
| data.gender | Integer | 性别 | 0-女1-男2-未知,可修改 |
| data.userRole | String | 用户角色 | user/admin系统收集 |
| data.isVip | Integer | 是否会员 | 0-非会员1-会员,系统收集 |
| data.vipExpire | String | 费用到期时间 | ISO 8601格式系统收集 |
| data.vipType | String | 套餐类别 | 体验会员/月度会员/年度会员,系统收集 |
| data.location | String | 所在省市 | 可由用户填写或客服填写 |
| data.preference | String | 彩票偏好 | 双色球/大乐透等,可由用户填写或客服填写 |
| data.channel | String | 获客渠道 | 可由用户填写或客服填写 |
| data.status | Integer | 状态 | 0-正常1-封禁,系统收集 |
| data.createTime | String | 注册日期 | ISO 8601格式系统收集 |
| data.updateTime | String | 更新时间 | ISO 8601格式 |
| message | String | 响应消息 | |
### 字段权限说明
**系统收集字段(黄色标记,会员可查看但不可修改):**
- 会员ID (id)
- 等级 (userRole)
- 注册日期 (createTime)
- 套餐类别 (vipType)
- 费用到期时间 (vipExpire)
**用户可填写或客服可填写字段(其它四项):**
- 性别 (gender)
- 所在省市 (location)
- 彩票偏好 (preference)
- 获客渠道 (channel)
### 错误响应示例
```json
{
"code": 40100,
"data": null,
"message": "未登录"
}
```
---
## 2. 编辑用户信息
### 接口地址
```
POST /user/update
```
### 接口说明
更新当前登录用户的个人信息。用户只能修改自己的信息,管理员可以修改任何用户的信息。
**注意:**
- 系统收集的字段会员ID、等级、注册日期、套餐类别、费用到期时间不可通过此接口修改
- 用户可以修改:昵称、手机号码、头像、性别、所在省市、彩票偏好、获客渠道
### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 用户ID当前登录用户的ID |
| userName | String | 否 | 昵称 |
| phone | String | 否 | 手机号码11位 |
| userAvatar | String | 否 | 头像URL |
| gender | Integer | 否 | 性别0-女1-男2-未知) |
| location | String | 否 | 所在省市 |
| preference | String | 否 | 彩票偏好(如:双色球、大乐透) |
| channel | String | 否 | 获客渠道 |
### 请求示例(使用 curl
```bash
curl -X POST "http://localhost:8123/api/user/update" \
-H "Content-Type: application/json" \
-b "JSESSIONID=your_session_id" \
-d '{
"id": 1234567890123456789,
"userName": "李四",
"phone": "13900139000",
"gender": 1,
"location": "上海市",
"preference": "大乐透",
"channel": "朋友推荐"
}'
```
### 请求示例(使用 JavaScript
```javascript
const updateUserInfo = async (userInfo) => {
const response = await fetch('http://localhost:8123/api/user/update', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userInfo)
});
const result = await response.json();
return result;
};
// 使用示例
updateUserInfo({
id: 1234567890123456789,
userName: "李四",
phone: "13900139000",
gender: 1,
location: "上海市",
preference: "大乐透",
channel: "朋友推荐"
}).then(data => {
console.log('更新成功:', data);
}).catch(error => {
console.error('更新失败:', error);
});
```
### 请求示例(使用 Vue 3
```vue
<template>
<div class="user-profile">
<form @submit.prevent="handleSubmit">
<div class="form-item">
<label>昵称</label>
<input v-model="userForm.userName" type="text" />
</div>
<div class="form-item">
<label>手机号码</label>
<input v-model="userForm.phone" type="tel" maxlength="11" />
</div>
<div class="form-item">
<label>性别</label>
<select v-model="userForm.gender">
<option :value="0"></option>
<option :value="1"></option>
<option :value="2">未知</option>
</select>
</div>
<div class="form-item">
<label>所在省市</label>
<input v-model="userForm.location" type="text" placeholder="如:北京市" />
</div>
<div class="form-item">
<label>彩票偏好</label>
<select v-model="userForm.preference">
<option value="">请选择</option>
<option value="双色球">双色球</option>
<option value="大乐透">大乐透</option>
<option value="双色球和大乐透">双色球和大乐透</option>
</select>
</div>
<div class="form-item">
<label>获客渠道</label>
<input v-model="userForm.channel" type="text" placeholder="如:微信推广" />
</div>
<button type="submit">保存</button>
</form>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';
const userForm = ref({
id: null,
userName: '',
phone: '',
gender: 2,
location: '',
preference: '',
channel: ''
});
// 获取用户信息
const getUserInfo = async () => {
try {
const response = await axios.get('/api/user/get/login');
if (response.data.code === 0) {
const user = response.data.data;
userForm.value = {
id: user.id,
userName: user.userName,
phone: user.phone,
gender: user.gender,
location: user.location || '',
preference: user.preference || '',
channel: user.channel || ''
};
}
} catch (error) {
console.error('获取用户信息失败:', error);
}
};
// 提交表单
const handleSubmit = async () => {
try {
const response = await axios.post('/api/user/update', userForm.value);
if (response.data.code === 0) {
alert('保存成功!');
} else {
alert('保存失败:' + response.data.message);
}
} catch (error) {
console.error('保存失败:', error);
alert('保存失败,请稍后重试');
}
};
onMounted(() => {
getUserInfo();
});
</script>
```
### 响应示例(成功)
```json
{
"code": 0,
"data": true,
"message": "ok"
}
```
### 响应字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码0表示成功 |
| data | Boolean | 是否更新成功 |
| message | String | 响应消息 |
### 错误响应示例
#### 1. 未登录
```json
{
"code": 40100,
"data": null,
"message": "未登录"
}
```
#### 2. 参数错误
```json
{
"code": 40000,
"data": null,
"message": "手机号格式不正确"
}
```
#### 3. 无权限
```json
{
"code": 40101,
"data": null,
"message": "无权限修改其他用户信息"
}
```
---
## 3. 根据ID获取用户信息管理员
### 接口地址
```
GET /user/get?id={userId}
```
### 接口说明
管理员根据用户ID获取指定用户的详细信息。
### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 用户ID |
### 请求示例
```bash
curl -X GET "http://localhost:8123/api/user/get?id=1234567890123456789" \
-H "Content-Type: application/json" \
-b "JSESSIONID=your_session_id"
```
### 响应示例
与"获取当前登录用户信息"接口响应格式相同。
---
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 40000 | 参数错误 |
| 40100 | 未登录 |
| 40101 | 无权限 |
| 40400 | 用户不存在 |
| 50000 | 系统错误 |
---
## 字段约束说明
### 1. 手机号码 (phone)
- 长度11位
- 格式:纯数字
- 示例13800138000
### 2. 性别 (gender)
- 0
- 1
- 2未知
### 3. 所在省市 (location)
- 最大长度100字符
- 格式:省份+城市,如"北京市"、"广东省广州市"
- 可为空
### 4. 彩票偏好 (preference)
- 最大长度100字符
- 常见值:双色球、大乐透、双色球和大乐透
- 可为空
### 5. 获客渠道 (channel)
- 最大长度100字符
- 常见值:微信推广、朋友推荐、搜索引擎、广告投放等
- 可为空
---
## 完整的前端表单示例HTML + JavaScript
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户信息编辑</title>
<style>
.user-profile {
max-width: 600px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.form-item {
margin-bottom: 15px;
}
.form-item label {
display: inline-block;
width: 120px;
font-weight: bold;
}
.form-item input,
.form-item select {
width: 300px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.form-item.readonly input {
background-color: #f5f5f5;
cursor: not-allowed;
}
.readonly-note {
color: #999;
font-size: 12px;
margin-left: 120px;
}
button {
margin-left: 120px;
padding: 10px 30px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="user-profile">
<h2>会员个人信息</h2>
<form id="userForm">
<!-- 系统收集字段(只读) -->
<div class="form-item readonly">
<label>会员ID</label>
<input type="text" id="userId" readonly />
</div>
<div class="form-item readonly">
<label>等级:</label>
<input type="text" id="userRole" readonly />
</div>
<div class="form-item readonly">
<label>注册日期:</label>
<input type="text" id="createTime" readonly />
</div>
<div class="form-item readonly">
<label>套餐类别:</label>
<input type="text" id="vipType" readonly />
</div>
<div class="form-item readonly">
<label>费用到期时间:</label>
<input type="text" id="vipExpire" readonly />
</div>
<p class="readonly-note">注:黄色标记为系统收集,会员可查看但不可修改</p>
<hr style="margin: 20px 0;">
<!-- 可编辑字段 -->
<div class="form-item">
<label>昵称:</label>
<input type="text" id="userName" />
</div>
<div class="form-item">
<label>手机号码:</label>
<input type="tel" id="phone" maxlength="11" />
</div>
<div class="form-item">
<label>性别:</label>
<select id="gender">
<option value="0"></option>
<option value="1"></option>
<option value="2">未知</option>
</select>
</div>
<div class="form-item">
<label>所在省市:</label>
<input type="text" id="location" placeholder="如:北京市" />
</div>
<div class="form-item">
<label>彩票偏好:</label>
<select id="preference">
<option value="">请选择</option>
<option value="双色球">双色球</option>
<option value="大乐透">大乐透</option>
<option value="双色球和大乐透">双色球和大乐透</option>
</select>
</div>
<div class="form-item">
<label>获客渠道:</label>
<input type="text" id="channel" placeholder="如:微信推广" />
</div>
<p class="readonly-note">注:其它四项可由用户填写或客服填写</p>
<button type="submit">保存</button>
</form>
</div>
<script>
// 获取用户信息
async function loadUserInfo() {
try {
const response = await fetch('/api/user/get/login', {
method: 'GET',
credentials: 'include'
});
const result = await response.json();
if (result.code === 0) {
const user = result.data;
// 填充只读字段
document.getElementById('userId').value = user.id;
document.getElementById('userRole').value = user.userRole === 'admin' ? '管理员' : '普通用户';
document.getElementById('createTime').value = formatDate(user.createTime);
document.getElementById('vipType').value = user.vipType || '体验会员';
document.getElementById('vipExpire').value = user.vipExpire ? formatDate(user.vipExpire) : '未开通';
// 填充可编辑字段
document.getElementById('userName').value = user.userName || '';
document.getElementById('phone').value = user.phone || '';
document.getElementById('gender').value = user.gender !== null ? user.gender : 2;
document.getElementById('location').value = user.location || '';
document.getElementById('preference').value = user.preference || '';
document.getElementById('channel').value = user.channel || '';
} else {
alert('获取用户信息失败:' + result.message);
}
} catch (error) {
console.error('获取用户信息失败:', error);
alert('获取用户信息失败,请稍后重试');
}
}
// 格式化日期
function formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return date.toLocaleString('zh-CN');
}
// 提交表单
document.getElementById('userForm').addEventListener('submit', async (e) => {
e.preventDefault();
const userId = document.getElementById('userId').value;
const phone = document.getElementById('phone').value;
// 验证手机号
if (phone && phone.length !== 11) {
alert('手机号格式不正确请输入11位手机号');
return;
}
const formData = {
id: userId,
userName: document.getElementById('userName').value,
phone: phone,
gender: parseInt(document.getElementById('gender').value),
location: document.getElementById('location').value,
preference: document.getElementById('preference').value,
channel: document.getElementById('channel').value
};
try {
const response = await fetch('/api/user/update', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (result.code === 0) {
alert('保存成功!');
loadUserInfo(); // 重新加载用户信息
} else {
alert('保存失败:' + result.message);
}
} catch (error) {
console.error('保存失败:', error);
alert('保存失败,请稍后重试');
}
});
// 页面加载时获取用户信息
loadUserInfo();
</script>
</body>
</html>
```
---
## 注意事项
1. **权限控制**
- 用户只能查看和修改自己的信息
- 管理员可以查看和修改任何用户的信息
- 系统收集的字段会员ID、等级、注册日期、套餐类别、费用到期时间任何人都不能通过此接口修改
2. **数据验证**
- 手机号必须是11位数字
- 性别只能是0、1、2
- 所有字符串字段都有长度限制
3. **Session管理**
- 所有接口都需要先登录
- 请求时需要携带Session Cookie
- 前端使用`credentials: 'include'`来携带Cookie
4. **错误处理**
- 前端应该处理所有可能的错误情况
- 显示友好的错误提示给用户
5. **数据更新**
- 只需要传递需要更新的字段
- 未传递的字段不会被更新
- 建议每次都传递完整的可编辑字段数据