yunzer/app/api/controller/UserController.php

402 lines
13 KiB
PHP
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.

<?php
/**
* 商业使用授权协议
*
* Copyright (c) 2025 [云泽网]. 保留所有权利.
*
* 本软件仅供评估使用。任何商业用途必须获得书面授权许可。
* 未经授权商业使用本软件属于侵权行为,将承担法律责任。
*
* 授权购买请联系: 357099073@qq.com
* 官方网站: https://www.yunzer.cn
*
* 评估用户须知:
* 1. 禁止移除版权声明
* 2. 禁止用于生产环境
* 3. 禁止转售或分发
*/
namespace app\api\controller;
use app\api\controller\BaseController;
use app\index\model\User\Users as Users;
use app\index\model\User\UsersGroup as UsersGroup;
use think\facade\Log;
use think\facade\Cache;
use think\Response;
class UserController extends BaseController
{
/**
* 用户登录接口
*
* @return \think\Response
*/
public function login()
{
if (!$this->request->isPost()) {
return json(['code' => 1, 'msg' => '请求方法错误']);
}
$data = $this->request->post();
try {
// 验证数据
$validate = validate([
'account' => 'require|email',
'password' => 'require'
], [
'account.require' => '账户不能为空',
'account.email' => '邮箱格式不正确',
'password.require' => '密码不能为空'
]);
if (!$validate->check($data)) {
return json(['code' => 1, 'msg' => $validate->getError()]);
}
// 查询用户
$user = Users::where('account', $data['account'])->find();
if (!$user) {
return json(['code' => 1, 'msg' => '用户不存在']);
}
// 验证密码
if ($user->password !== md5($data['password'])) {
return json(['code' => 1, 'msg' => '密码错误']);
}
// 生成JWT token这里使用简单的token实际项目中建议使用JWT
$token = $this->generateToken($user->id);
// 将token存储到缓存中设置过期时间
Cache::set('user_token_' . $user->id, $token, 7 * 24 * 3600);
// 记录登录日志
Log::record('用户登录成功:' . $user->account, 'info');
// 返回用户信息和token
return json([
'code' => 0,
'msg' => '登录成功',
'data' => [
'token' => $token,
'user_info' => [
'id' => $user->id,
'account' => $user->account,
'name' => $user->name,
'avatar' => $user->avatar ?? '/static/images/avatar.png',
'phone' => $user->phone ?? '',
'sex' => $user->sex ?? 0,
'qq' => $user->qq ?? '',
'wechat' => $user->wechat ?? '',
'create_time' => $user->create_time
]
]
]);
} catch (\Exception $e) {
Log::record('登录失败:' . $e->getMessage(), 'error');
return json(['code' => 1, 'msg' => '登录失败:' . $e->getMessage()]);
}
}
/**
* 用户注册接口
*
* @return \think\Response
*/
public function register()
{
if (!$this->request->isPost()) {
return json(['code' => 1, 'msg' => '请求方法错误']);
}
$data = $this->request->post();
try {
// 验证数据
$validate = validate([
'account' => 'require|email|unique:users',
'code' => 'require|number|length:6',
'password' => 'require|min:6|max:20',
'repassword' => 'require|confirm:password'
], [
'account.require' => '账户不能为空',
'account.email' => '邮箱格式不正确',
'account.unique' => '该邮箱已注册',
'code.require' => '验证码不能为空',
'code.number' => '验证码必须为数字',
'code.length' => '验证码长度必须为6位',
'password.require' => '密码不能为空',
'password.min' => '密码长度不能小于6个字符',
'password.max' => '密码长度不能超过20个字符',
'repassword.require' => '确认密码不能为空',
'repassword.confirm' => '两次输入的密码不一致'
]);
if (!$validate->check($data)) {
return json(['code' => 1, 'msg' => $validate->getError()]);
}
// 验证邮箱验证码
$emailCode = Cache::get('email_code_' . $data['account']);
if (!$emailCode || $emailCode != $data['code']) {
return json(['code' => 1, 'msg' => '验证码错误或已过期']);
}
// 创建用户
$user = new Users;
$user->account = $data['account'];
$user->password = md5($data['password']);
$user->name = $this->generateRandomName();
$user->create_time = time();
$user->save();
// 清除验证码缓存
Cache::delete('email_code_' . $data['account']);
return json(['code' => 0, 'msg' => '注册成功']);
} catch (\Exception $e) {
return json(['code' => 1, 'msg' => '注册失败:' . $e->getMessage()]);
}
}
/**
* 退出登录接口
*
* @return \think\Response
*/
public function logout()
{
try {
$token = $this->request->header('Authorization');
if ($token) {
// 从token中获取用户ID
$userId = $this->getUserIdFromToken($token);
if ($userId) {
// 清除token缓存
Cache::delete('user_token_' . $userId);
}
}
Log::record('用户退出登录', 'info');
return json(['code' => 0, 'msg' => '退出成功']);
} catch (\Exception $e) {
Log::record('退出登录失败:' . $e->getMessage(), 'error');
return json(['code' => 1, 'msg' => '退出失败:' . $e->getMessage()]);
}
}
/**
* 获取用户信息接口
*
* @return \think\Response
*/
public function getUserInfo()
{
try {
$token = $this->request->header('Authorization');
if (!$token) {
return json(['code' => 1, 'msg' => '请先登录']);
}
$userId = $this->getUserIdFromToken($token);
if (!$userId) {
return json(['code' => 1, 'msg' => 'token无效']);
}
// 验证token是否在缓存中
$cachedToken = Cache::get('user_token_' . $userId);
if (!$cachedToken || $cachedToken !== $token) {
return json(['code' => 1, 'msg' => 'token已过期']);
}
// 获取用户信息
$user = Users::find($userId);
if (!$user) {
return json(['code' => 1, 'msg' => '用户不存在']);
}
return json([
'code' => 0,
'msg' => '获取成功',
'data' => [
'id' => $user->id,
'account' => $user->account,
'name' => $user->name,
'avatar' => $user->avatar ?? '/static/images/avatar.png',
'phone' => $user->phone ?? '',
'sex' => $user->sex ?? 0,
'qq' => $user->qq ?? '',
'wechat' => $user->wechat ?? '',
'create_time' => $user->create_time
]
]);
} catch (\Exception $e) {
return json(['code' => 1, 'msg' => '获取用户信息失败:' . $e->getMessage()]);
}
}
/**
* 发送邮箱验证码接口
*
* @return \think\Response
*/
public function sendEmailCode()
{
if (!$this->request->isPost()) {
return json(['code' => 1, 'msg' => '请求方法错误']);
}
$email = $this->request->post('account');
if (empty($email)) {
return json(['code' => 1, 'msg' => '邮箱不能为空']);
}
// 验证邮箱格式
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return json(['code' => 1, 'msg' => '邮箱格式不正确']);
}
// 检查邮箱是否已注册
$exists = Users::where('account', $email)->find();
if ($exists) {
return json(['code' => 1, 'msg' => '该邮箱已注册']);
}
// 生成6位随机验证码
$code = mt_rand(100000, 999999);
// 这里应该调用邮件发送服务
// 为了演示,我们直接返回成功
// 实际项目中需要实现邮件发送逻辑
// 将验证码存入缓存有效期5分钟
Cache::set('email_code_' . $email, $code, 300);
return json(['code' => 0, 'msg' => '验证码已发送']);
}
/**
* 修改密码接口
*
* @return \think\Response
*/
public function updatePassword()
{
if (!$this->request->isPost()) {
return json(['code' => 1, 'msg' => '请求方法错误']);
}
try {
$token = $this->request->header('Authorization');
if (!$token) {
return json(['code' => 1, 'msg' => '请先登录']);
}
$userId = $this->getUserIdFromToken($token);
if (!$userId) {
return json(['code' => 1, 'msg' => 'token无效']);
}
$data = $this->request->post();
// 验证数据
$validate = validate([
'old_password' => 'require',
'new_password' => 'require|min:6|max:20',
'confirm_password' => 'require|confirm:new_password'
], [
'old_password.require' => '旧密码不能为空',
'new_password.require' => '新密码不能为空',
'new_password.min' => '新密码长度不能小于6个字符',
'new_password.max' => '新密码长度不能超过20个字符',
'confirm_password.require' => '确认密码不能为空',
'confirm_password.confirm' => '两次输入的密码不一致'
]);
if (!$validate->check($data)) {
return json(['code' => 1, 'msg' => $validate->getError()]);
}
// 获取用户信息
$user = Users::find($userId);
if (!$user) {
return json(['code' => 1, 'msg' => '用户不存在']);
}
// 验证旧密码
if ($user->password !== md5($data['old_password'])) {
return json(['code' => 1, 'msg' => '旧密码错误']);
}
// 更新密码
$user->password = md5($data['new_password']);
$user->update_time = time();
if ($user->save()) {
// 清除token要求重新登录
Cache::delete('user_token_' . $userId);
return json(['code' => 0, 'msg' => '密码修改成功,请重新登录']);
} else {
return json(['code' => 1, 'msg' => '密码修改失败']);
}
} catch (\Exception $e) {
return json(['code' => 1, 'msg' => '密码修改失败:' . $e->getMessage()]);
}
}
/**
* 生成简单的token
*
* @param int $userId
* @return string
*/
private function generateToken($userId)
{
$data = [
'user_id' => $userId,
'timestamp' => time(),
'random' => mt_rand(100000, 999999)
];
return base64_encode(json_encode($data));
}
/**
* 从token中获取用户ID
*
* @param string $token
* @return int|null
*/
private function getUserIdFromToken($token)
{
try {
$data = json_decode(base64_decode($token), true);
if ($data && isset($data['user_id'])) {
return $data['user_id'];
}
} catch (\Exception $e) {
return null;
}
return null;
}
/**
* 生成随机用户名
*
* @return string
*/
private function generateRandomName()
{
return '云朵_' . mt_rand(100000, 999999);
}
}