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

18 KiB
Raw Permalink Blame History

用户信息管理API使用说明

接口概述

本文档提供用户信息获取和编辑的接口说明,包括会员个人信息的查询和更新功能。

基础信息

  • Base URL: http://localhost:8123/api
  • Content-Type: application/json
  • 认证方式: Session需要先登录

1. 获取当前登录用户信息

接口地址

GET /user/get/login

接口说明

获取当前登录用户的详细信息包括会员ID、等级、昵称、手机号码、注册日期、套餐类别、费用到期时间、性别、所在省市、彩票偏好、获客渠道等。

请求参数

无需参数通过Session获取当前登录用户

请求示例(使用 curl

curl -X GET "http://localhost:8123/api/user/get/login" \
  -H "Content-Type: application/json" \
  -b "JSESSIONID=your_session_id"

请求示例(使用 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);
});

响应示例(成功)

{
  "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)

错误响应示例

{
  "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

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

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

<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>

响应示例(成功)

{
  "code": 0,
  "data": true,
  "message": "ok"
}

响应字段说明

字段名 类型 说明
code Integer 状态码0表示成功
data Boolean 是否更新成功
message String 响应消息

错误响应示例

1. 未登录

{
  "code": 40100,
  "data": null,
  "message": "未登录"
}

2. 参数错误

{
  "code": 40000,
  "data": null,
  "message": "手机号格式不正确"
}

3. 无权限

{
  "code": 40101,
  "data": null,
  "message": "无权限修改其他用户信息"
}

3. 根据ID获取用户信息管理员

接口地址

GET /user/get?id={userId}

接口说明

管理员根据用户ID获取指定用户的详细信息。

请求参数

参数名 类型 必填 说明
id Long 用户ID

请求示例

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

<!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. 数据更新

    • 只需要传递需要更新的字段
    • 未传递的字段不会被更新
    • 建议每次都传递完整的可编辑字段数据