20
This commit is contained in:
@@ -9,3 +9,4 @@ app/command/Test.php
|
||||
runtime
|
||||
vendor
|
||||
public/shunliao.apk
|
||||
.user.ini
|
||||
|
||||
@@ -1 +1 @@
|
||||
open_basedir=/www/wwwroot/admin/:/tmp/
|
||||
open_basedir=/www/wwwroot/im/admin/:/tmp/
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use app\model\User;
|
||||
use app\model\Album as AlbumModel;
|
||||
|
||||
/**
|
||||
* 群相册
|
||||
*/
|
||||
class AlbumController extends BaseController
|
||||
{
|
||||
public $noNeedAuth = ['*'];
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* @Apidoc\Title("群相册列表")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("group_id", type="string", require=true, desc="群ID")
|
||||
* @Apidoc\Param("offset", type="int", require=false, desc="偏移量,和页码二选一",default=0)
|
||||
* @Apidoc\Param("page", type="int", require=false, desc="页码",default=1)
|
||||
* @Apidoc\Param("limit", type="int", require=true, desc="分页大小",default=10)
|
||||
*/
|
||||
function list(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$limit = $request->post('limit',10);
|
||||
$offset = $request->post('offset',0);
|
||||
$group_id = $request->post('groupID') ?:$request->post('group_id');
|
||||
//$ls = $this->get_user_in_group($group_id);
|
||||
$query = AlbumModel::where('group_id',$group_id)
|
||||
->order('id','desc');
|
||||
if($offset){
|
||||
$list = $query->where('id','<',$offset)->limit($offset,$limit);
|
||||
}else{
|
||||
$list = $query->paginate($limit);
|
||||
}
|
||||
return $this->success('ok',$list);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("创建相册")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("groupID", type="string", require=true, desc="群ID")
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("image", type="int", require=false, desc="封面ID")
|
||||
*/
|
||||
function create(Request $request): Response
|
||||
{
|
||||
$user_id = \support\Jwt\JwtToken::getCurrentId();
|
||||
$data = [
|
||||
'user_id' => $user_id,
|
||||
'group_id' => $request->post('groupID'),
|
||||
'title' => input('title'),
|
||||
'image' => input('image'),
|
||||
];
|
||||
$result = AlbumModel::create($data);
|
||||
return $this->success('ok',$result);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("更新")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("image", type="int", require=false, desc="封面ID")
|
||||
*/
|
||||
function update(Request $request): Response
|
||||
{
|
||||
$id = $request->input('id');
|
||||
$image = $request->input('image');
|
||||
$title = $request->input('title');
|
||||
$album = AlbumModel::find($id);
|
||||
if($title){
|
||||
$album->title = $title;
|
||||
}
|
||||
if($image){
|
||||
$album->image = $image;
|
||||
}
|
||||
$album->save();
|
||||
return $this->success('ok',$album);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("删除")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
*/
|
||||
function delete(Request $request): Response
|
||||
{
|
||||
$id = Input('id');
|
||||
$album = AlbumModel::whereIn('id',condition: $id)->find();
|
||||
$album->delete();
|
||||
|
||||
return $this->success('ok');
|
||||
}
|
||||
}
|
||||
@@ -90,4 +90,17 @@ class CollectionController extends BaseController{
|
||||
|
||||
return $this->success('发布成功', ['collection' => $collection]);
|
||||
}
|
||||
/**
|
||||
* 删除收藏
|
||||
* @Apidoc\Param("id", type="int",require=true, desc="收藏id")
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
function delete(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$id = $request->post('id');
|
||||
CollectionModel::where('id',$id)->where('user_id',$user->id)->delete();
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,33 @@ class CommonController extends BaseController{
|
||||
$config['recharge_status_list'] = \app\enum\RechargeStatus::toArray();
|
||||
$config['withdrawl_status_list'] = \app\enum\WithdrawlStatus::toArray();
|
||||
$config['server_status_list'] = \app\enum\ServerStatus::toArray();
|
||||
$config['see_point_awards'] = [
|
||||
[
|
||||
'name'=>'S1',
|
||||
'award'=>0.05,
|
||||
'total'=>50,
|
||||
],
|
||||
[
|
||||
'name'=>'S2',
|
||||
'award'=>0.1,
|
||||
'total'=>100,
|
||||
],
|
||||
[
|
||||
'name'=>'S3',
|
||||
'award'=>0.15,
|
||||
'total'=>1000,
|
||||
],
|
||||
[
|
||||
'name'=>'S4',
|
||||
'award'=>0.2,
|
||||
'total'=>5000,
|
||||
],
|
||||
[
|
||||
'name'=>'S5',
|
||||
'award'=>0.25,
|
||||
'total'=>20000,
|
||||
]
|
||||
];
|
||||
//$config['getFriendList'] = $request->IM->friend->getFriendList('100006');
|
||||
return $this->success(__('successful'), $config);
|
||||
}
|
||||
@@ -97,7 +124,9 @@ class CommonController extends BaseController{
|
||||
* 注册会员
|
||||
*
|
||||
* @Apidoc\Method ("POST")
|
||||
* @Apidoc\Param("type", type="string",require=true, desc="注册方式:email,mobile")
|
||||
* @Apidoc\Param("email", type="string",require=true, desc="邮箱")
|
||||
* @Apidoc\Param("mobile", type="string",require=true, desc="手机号码")
|
||||
* @Apidoc\Param("password", type="string",require=true, desc="密码")
|
||||
* @Apidoc\Param("trade_password", type="string",require=true, desc="交易密码")
|
||||
* @Apidoc\Param("invite_code", type="string",require=true, desc="推荐码")
|
||||
@@ -121,7 +150,7 @@ class CommonController extends BaseController{
|
||||
}
|
||||
$username = $email;
|
||||
unset($mobile);
|
||||
//captcha_verfiy('email','register',$email,false);
|
||||
captcha_verfiy('email','register',$email,false);
|
||||
}
|
||||
if ($type == 'mobile') {
|
||||
if(!$mobile || !Validate::regex($mobile, "^1\d{10}$")){
|
||||
@@ -129,10 +158,10 @@ class CommonController extends BaseController{
|
||||
}
|
||||
$username = $mobile;
|
||||
unset($email);
|
||||
//captcha_verfiy('mobile','register',$mobile,false);
|
||||
captcha_verfiy('mobile','register',$mobile,false);
|
||||
}
|
||||
if ($type == 'username') {
|
||||
if(!$email || !Validate::is($email, "email")){
|
||||
if(!$username){
|
||||
return $this->error(__('Username is incorrect'));
|
||||
}
|
||||
}
|
||||
@@ -151,9 +180,18 @@ class CommonController extends BaseController{
|
||||
'role_id' => 1,
|
||||
'group_id' => 0,
|
||||
'region' => '86',
|
||||
'nickname' => input('nickname','用户_'.substr($username,7)),
|
||||
'nickname' => input('nickname'),
|
||||
'avatar' => '/static/avatar/'.rand(0,17).'.png',
|
||||
];
|
||||
if(empty($extends['nickname'])){
|
||||
if($type == 'mobile'){
|
||||
$extends['nickname'] = '用户_'.substr($username,7);
|
||||
}else if($type == 'email'){
|
||||
$extends['nickname'] = '用户_'.substr(explode('@',$username)[0],7);
|
||||
}else{
|
||||
$extends['nickname'] = $username;
|
||||
}
|
||||
}
|
||||
if ($invite_code) {
|
||||
if(strlen($invite_code) == 12){
|
||||
//系统生产的一次性推荐吗
|
||||
@@ -203,10 +241,12 @@ class CommonController extends BaseController{
|
||||
* 登录
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("username", type="string",require=false, desc="用户名登录必填")
|
||||
* @Apidoc\Param("email", type="string",require=false, desc="邮箱登录必填")
|
||||
* @Apidoc\Param("mobile", type="string",require=false, desc="手机号登录必填")
|
||||
* @Apidoc\Param("type", type="string",require=true,default="mobile",desc="登录方式,username,mobile,email")
|
||||
* @Apidoc\Param("password", type="string",require=false, desc="密码的登录必填")
|
||||
* @Apidoc\Param("code", type="string",require=false, desc="验证码登录必填")
|
||||
* @Apidoc\Param("platform", type="string",require=false, desc="平台",default="web")
|
||||
* @Apidoc\Param("region", type="string",require=false,default="86", desc="区域,手机号登录必填")
|
||||
*/
|
||||
public function login(Request $request){
|
||||
@@ -321,11 +361,13 @@ class CommonController extends BaseController{
|
||||
* @Apidoc\Param("email", type="string",require=true, desc="邮箱")
|
||||
* @Apidoc\Param("newpassword", type="string",require=true, desc="新密码")
|
||||
* @Apidoc\Param("code", type="string",require=true, desc="邮箱验证码,event=reset_trade_pwd")
|
||||
* @Apidoc\Param("verify_type", type="string",require=true, desc="验证方式,email,mobile")
|
||||
*/
|
||||
public function reset_trade_pwd()
|
||||
{
|
||||
$email = input("email");
|
||||
$mobile = input("mobile");
|
||||
$verify_type = input("verify_type");
|
||||
$newpassword = input("newpassword");
|
||||
if (!$newpassword) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
@@ -334,7 +376,6 @@ class CommonController extends BaseController{
|
||||
if (!Validate::check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,32}'])) {
|
||||
return $this->error(__('Trade password must be 6-32 characters'));
|
||||
}
|
||||
|
||||
if (!$mobile && !$email){
|
||||
try{
|
||||
$user = \support\Jwt::getUser();
|
||||
@@ -342,7 +383,14 @@ class CommonController extends BaseController{
|
||||
$user = false;
|
||||
}
|
||||
if($user){
|
||||
|
||||
if($verify_type == 'email'){
|
||||
captcha_verfiy('email','reset_trade_pwd',$user->email);
|
||||
}else if($verify_type == 'mobile'){
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$user->mobile);
|
||||
}else{
|
||||
return $this->error(__('Unknown verify type'));
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if ($mobile && Validate::regex($mobile, "^1\d{10}$")) {
|
||||
@@ -402,12 +450,13 @@ class CommonController extends BaseController{
|
||||
$list[$code] = time();
|
||||
cache($key,$list);
|
||||
cache('exp_'.$key,time());
|
||||
// addJob([
|
||||
// 'email' => $email,
|
||||
// 'title' => __("Mt email code"),
|
||||
// 'event' => $event,
|
||||
// 'code' => $code
|
||||
// ],'Email');
|
||||
addJob([
|
||||
'email' => $email,
|
||||
'title' => __(Config('site.name').' 验证码'),
|
||||
'event' => $event,
|
||||
'code' => $code
|
||||
],'Email');
|
||||
\support\Log::channel('mail')->alert("邮件验证码:".$code.',邮箱:'.$email);
|
||||
return $this->success(__('Email sent successfully'),[
|
||||
'code'=> $debug ? $code : ''
|
||||
]);
|
||||
@@ -443,6 +492,7 @@ class CommonController extends BaseController{
|
||||
'event' => $event,
|
||||
'code' => $code
|
||||
],'Sms');
|
||||
\support\Log::channel('mail')->alert("短信验证码:".$code.',手机号:'.$mobile);
|
||||
return $this->success(__('SMS sent successfully'),[
|
||||
'code'=> $debug ? $code : ''
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use app\model\User;
|
||||
use app\model\Gallery as GalleryModel;
|
||||
use app\model\Album as AlbumModel;
|
||||
|
||||
/**
|
||||
* 相册的相片
|
||||
*/
|
||||
class GalleryController extends BaseController
|
||||
{
|
||||
public $noNeedAuth = ['*'];
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* @Apidoc\Title("列表")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("album_id", type="string", require=true, desc="相册ID")
|
||||
* @Apidoc\Param("offset", type="int", require=false, desc="偏移量,和页码二选一",default=0)
|
||||
* @Apidoc\Param("page", type="int", require=false, desc="页码",default=1)
|
||||
* @Apidoc\Param("limit", type="int", require=true, desc="分页大小",default=10)
|
||||
*/
|
||||
function list(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$limit = $request->post('limit',10);
|
||||
$offset = $request->post('offset',0);
|
||||
$album_id = $request->post('album_id') ?: 0;
|
||||
//$ls = $this->get_user_in_group($group_id);
|
||||
$query = GalleryModel::where('album_id',$album_id)->order('id','desc');
|
||||
if($offset){
|
||||
$list = $query->where('id','<',$offset)->limit(0,$limit);
|
||||
}else{
|
||||
$list = $query->paginate($limit);
|
||||
}
|
||||
return $this->success('ok',$list);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("上传")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("album_id", type="string", require=true, desc="相册ID",default=0)
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("url", type="string", require=true, desc="图片")
|
||||
* @Apidoc\Param("file", type="file", require=true, desc="图片,没有url得时候必传")
|
||||
*/
|
||||
function create(Request $request): Response
|
||||
{
|
||||
$user_id = \support\Jwt\JwtToken::getCurrentId();
|
||||
$res = $this->_upload($request);
|
||||
if(is_string($res)){
|
||||
return $this->fail( $res);
|
||||
}
|
||||
$album_id = $request->post('album_id') ?: 0;
|
||||
$album = AlbumModel::find($album_id);
|
||||
if(!$album){
|
||||
return $this->fail('相册不存在');
|
||||
}
|
||||
$insert_data = [];
|
||||
foreach($res as $item){
|
||||
$insert_data[] = [
|
||||
'user_id' => $user_id,
|
||||
'group_id' => $album->group_id,
|
||||
'album_id' => $album_id,
|
||||
'title' => $item['origin_name'],
|
||||
'url' => $item['file_name'],
|
||||
];
|
||||
}
|
||||
$result = GalleryModel::saveAll($insert_data);
|
||||
return $this->success('ok',$result[0]);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("更新")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("url", type="string", require=true, desc="图片")
|
||||
*/
|
||||
function update(Request $request): Response
|
||||
{
|
||||
$id = $request->input('id');
|
||||
$title = $request->input('title');
|
||||
$url = $request->input('url');
|
||||
$album = GalleryModel::find($id);
|
||||
if($album){
|
||||
if($title){
|
||||
$album->title = $title;
|
||||
}
|
||||
if($url){
|
||||
$album->url = $url;
|
||||
}
|
||||
$album->save();
|
||||
}
|
||||
return $this->success('ok',$album);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("删除")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
*/
|
||||
function delete(Request $request): Response
|
||||
{
|
||||
$ids = Input('ids');
|
||||
GalleryModel::whereIn('id',condition: $ids)->delete();
|
||||
return $this->success('ok');
|
||||
}
|
||||
/**
|
||||
* 获取在群里的角色
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
private function get_user_in_group($group_id='',$user_id='')
|
||||
{
|
||||
$list = request()->IM->group->getGroupMemberList($group_id,$user_id);
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ use support\Request;
|
||||
use support\Response;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use app\model\User;
|
||||
use app\model\Album as AlbumModel;
|
||||
use app\model\Gallery as AlbumModel;
|
||||
|
||||
/**
|
||||
* 群组管理
|
||||
@@ -19,7 +19,7 @@ class GroupController extends BaseController
|
||||
* @Apidoc\Title("群相片列表")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("group_id", type="string", require=true, desc="群ID")
|
||||
* @Apidoc\Param("page", type="int", require=true, desc="页码",default=1)
|
||||
* @Apidoc\Param("offset", type="int", require=true, desc="偏移量",default=99999999999999)
|
||||
* @Apidoc\Param("limit", type="int", require=true, desc="分页大小",default=10)
|
||||
*/
|
||||
function album_list(Request $request): Response
|
||||
|
||||
@@ -401,6 +401,12 @@ class MomentsController extends BaseController{
|
||||
$result[] = \support\Encrypt::userIDDecode($userID);
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* 删除朋友圈
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
|
||||
* @return Response
|
||||
*/
|
||||
function delete(Request $request): Response{
|
||||
$id = $request->post('id');
|
||||
$user = \support\Jwt::getUser();
|
||||
@@ -422,7 +428,8 @@ class MomentsController extends BaseController{
|
||||
}
|
||||
/**
|
||||
* 设置朋友圈背景
|
||||
* @param Request $request
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("file", type="File",require=true, desc="文件")
|
||||
* @return Response
|
||||
*/
|
||||
function setBanner(Request $request){
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\model\User as UserModel;
|
||||
use app\model\Card;
|
||||
use app\model\Cdkey;
|
||||
use support\think\Db;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use Tinywan\Validate\Facade\Validate;
|
||||
|
||||
/**
|
||||
* 通行证
|
||||
*/
|
||||
class PassportController extends BaseController{
|
||||
/**
|
||||
* 不需要鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = ['*'];
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* 安全验证
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("verify_type", type="string", require=true, desc="验证类型,email或mobile")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=verify")
|
||||
*/
|
||||
public function security_verify()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$verify_type = input('verify_type');
|
||||
if($verify_type=='mobile'){
|
||||
captcha_verfiy('mobile', 'verify', $user->mobile);
|
||||
}else if($verify_type == 'email'){
|
||||
captcha_verfiy('email', 'verify', $user->email);
|
||||
}else{
|
||||
return $this->error(__('Invalid verify type'));
|
||||
}
|
||||
return $this->success(__('Security verify successfully'));
|
||||
}
|
||||
/**
|
||||
* 绑定手机号
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("region", type="string", require=true, desc="区域代码")
|
||||
* @Apidoc\Param("mobile", type="string", require=true, desc="手机号")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=bind_mobile")
|
||||
*/
|
||||
public function bind_mobile()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$mobile = input('mobile');
|
||||
$region = input('region');
|
||||
|
||||
// 验证手机号格式
|
||||
if (!$mobile || !Validate::regex($mobile, "^1\d{10}$")) {
|
||||
return $this->error(__('Incorrect mobile number format'));
|
||||
}
|
||||
|
||||
// 验证手机号唯一性
|
||||
if (UserModel::where('mobile', $mobile)->where('region',$region)->where('id', '<>', $user->id)->find()) {
|
||||
return $this->error(__('Mobile number already exists'));
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
captcha_verfiy('mobile', 'bind_mobile', $mobile);
|
||||
|
||||
// 更新用户信息
|
||||
$user->mobile = $mobile;
|
||||
$user->region = $region;
|
||||
//$user->mobile_verify = 1;
|
||||
$user->save();
|
||||
|
||||
return $this->success(__('Mobile number bound successfully'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定邮箱
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("email", type="string", require=true, desc="邮箱")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=bind_email")
|
||||
*/
|
||||
public function bind_email()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$email = input('email');
|
||||
// 验证邮箱格式
|
||||
if (!$email || !Validate::email($email)) {
|
||||
return $this->error(__('Incorrect email format'));
|
||||
}
|
||||
|
||||
// 验证邮箱唯一性
|
||||
if (UserModel::where('email', $email)->where('id', '<>', $user->id)->find()) {
|
||||
return $this->error(__('Email already exists'));
|
||||
}
|
||||
captcha_verfiy('email', 'bind_email', $email);
|
||||
|
||||
|
||||
// 更新用户信息
|
||||
$user->email = $email;
|
||||
//$user->email_verify = 1;
|
||||
$user->save();
|
||||
|
||||
return $this->success(__('Email bound successfully'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定用户名
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("username", type="string", require=true, desc="用户名")
|
||||
* @Apidoc\Param("verify_type", type="string", require=true, desc="验证类型,email或mobile")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=bind_username")
|
||||
*/
|
||||
public function bind_username()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$username = input('username');
|
||||
$verify_type = input('verify_type');
|
||||
|
||||
// 验证用户名格式
|
||||
if (!$username || strlen($username) < 3 || strlen($username) > 20) {
|
||||
return $this->error(__('Username length must be between 3 and 20 characters'));
|
||||
}
|
||||
|
||||
// 验证用户名唯一性
|
||||
if (UserModel::where('username', $username)->where('id', '<>', $user->id)->find()) {
|
||||
return $this->error(__('Username already exists'));
|
||||
}
|
||||
|
||||
if($verify_type == 'mobile'){
|
||||
captcha_verfiy('mobile', 'bind_username', $user->mobile);
|
||||
}else if($verify_type == 'email'){
|
||||
captcha_verfiy('email', 'bind_username', $user->email);
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
$user->username = $username;
|
||||
$user->save();
|
||||
|
||||
return $this->success(__('Username bound successfully'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑手机号
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=unbind_mobile")
|
||||
*/
|
||||
public function unbind_mobile()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
|
||||
if (!$user->mobile) {
|
||||
return $this->error(__('Mobile number not bound'));
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
captcha_verfiy('mobile', 'unbind_mobile', $user->mobile);
|
||||
|
||||
// 更新用户信息
|
||||
$user->mobile = '';
|
||||
$user->mobile_verify = 0;
|
||||
$user->save();
|
||||
|
||||
return $this->success(__('Mobile number unbound successfully'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解绑邮箱
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("code", type="string", require=true, desc="验证码,event=unbind_email")
|
||||
*/
|
||||
public function unbind_email()
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
|
||||
if (!$user->email) {
|
||||
return $this->error(__('Email not bound'));
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
captcha_verfiy('email', 'unbind_email', $user->email);
|
||||
|
||||
// 更新用户信息
|
||||
$user->email = '';
|
||||
$user->email_verify = 0;
|
||||
$user->save();
|
||||
|
||||
return $this->success(__('Email unbound successfully'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,8 +47,7 @@ class TeamController extends BaseController{
|
||||
// 'user_sales_reward' => cache('user_sales_reward_'.$user_id)??0,//销售奖
|
||||
// 'user_output_reward' => cache('user_output_reward_'.$user_id)??0,//产值奖
|
||||
// 'user_withdrawl_reward' => cache('user_withdrawl_reward'.$user_id)??0,//提现奖
|
||||
'user' => $user[0],
|
||||
|
||||
'user' => $user[0]
|
||||
];
|
||||
return $this->success(__('successful'),$result);
|
||||
|
||||
|
||||
@@ -95,14 +95,38 @@ class UserController extends BaseController{
|
||||
* @Apidoc\Param("password", type="string",require=true, desc="旧密码(新设时可用为空)")
|
||||
* @Apidoc\Param("newpassword", type="string",require=true, desc="新密码")
|
||||
* @Apidoc\Param("renewpassword", type="string",require=true, desc="新密码")
|
||||
* @Apidoc\Param("code", type="string",require=true, desc="验证码")
|
||||
* @Apidoc\Param("verify_type", type="string",require=true, desc="验证方式,email,mobile,password")
|
||||
*/
|
||||
public function change_trade_password(){
|
||||
$user = \support\Jwt::getUser();
|
||||
$password = input('password');
|
||||
$newpassword = input('newpassword');
|
||||
$renewpassword = input('renewpassword');
|
||||
$verify_type = input('verify_type');
|
||||
if (!$newpassword || !$renewpassword || $newpassword !== $renewpassword) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
if($verify_type == 'email'){
|
||||
captcha_verfiy('email','reset_trade_pwd',$user->email);
|
||||
try{
|
||||
\support\Jwt::change_trade_pwd($newpassword,'',true);
|
||||
return $this->success(__('Reset trade password successful'));
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}else if($verify_type == 'mobile'){
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$user->mobile);
|
||||
try{
|
||||
\support\Jwt::change_trade_pwd($newpassword,'',true);
|
||||
return $this->success(__('Reset trade password successful'));
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}else if($verify_type == 'password'){
|
||||
if (!$password) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
try{
|
||||
\support\Jwt::change_trade_pwd($newpassword,$password);
|
||||
return $this->success(__('Reset trade password successful'));
|
||||
@@ -110,6 +134,8 @@ class UserController extends BaseController{
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 根据关键字查询用户列表
|
||||
* @Apidoc\Method("POST")
|
||||
|
||||
+30
-7
@@ -21,8 +21,8 @@ class User extends Command
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this->addOption('user_id','u', InputArgument::OPTIONAL, 'user_id');
|
||||
$this->addOption('action','a', InputArgument::OPTIONAL, '操作类型');
|
||||
$this->addOption('user_id','u', InputOption::VALUE_OPTIONAL, 'user_id');
|
||||
$this->addOption('action','a', InputOption::VALUE_OPTIONAL, '操作类型','test');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,7 +38,28 @@ class User extends Command
|
||||
}
|
||||
cp('操作不存在:'.$action);
|
||||
return 0;
|
||||
}
|
||||
function test(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$user_id = 104864;
|
||||
$_user = Db::name('user')->where('id',$user_id)->find();
|
||||
Db::query('delete FROM `wa_user_team` WHERE descendant_id='.$user_id.' or ancestor_id='.$user_id.';');
|
||||
Hook('user.register_successed',$_user);
|
||||
//管理团队人数
|
||||
// $team_user_ids = Db::name('user_team')->where('descendant_id',$_user['id'])
|
||||
// ->where('depth','>',0)
|
||||
// ->order('depth','ASC')
|
||||
// ->column('ancestor_id');
|
||||
|
||||
// Db::name('user_extend')->whereIn('user_id',$team_user_ids)->data([
|
||||
// 'team_total'=> Db::raw('team_total+1')
|
||||
// ])->save();
|
||||
// $list = Db::name('user_extend')->whereIn('user_id',$team_user_ids)->field('user_id,team_total')->select();
|
||||
// foreach($list as $v){
|
||||
// cache('team_user_count_'.$v['user_id'],$v['team_total']);
|
||||
// }
|
||||
// cp($team_user_ids);
|
||||
return 0;
|
||||
}
|
||||
function login(InputInterface $input, OutputInterface $output){
|
||||
// $IM = new \support\OpenImSdk\Client([
|
||||
@@ -59,19 +80,20 @@ class User extends Command
|
||||
}
|
||||
function build_team(InputInterface $input, OutputInterface $output){
|
||||
$list = Db::name('user')->field('id')->order('id','asc')->select();
|
||||
//$list = [['id'=>100006]];
|
||||
foreach($list as $k=>$user){
|
||||
//team_total
|
||||
$team_user_ids = Db::name('user_team')->where('descendant_id',$user['id'])
|
||||
$team_user_ids = Db::name('user_team')->where('ancestor_id',$user['id'])
|
||||
->where('depth','>',0)
|
||||
->order('depth','ASC')
|
||||
->column('ancestor_id');
|
||||
->column('descendant_id');
|
||||
Db::name('user_extend')->where('user_id',$user['id'])->data([
|
||||
'team_total'=> count($team_user_ids)
|
||||
])->save();
|
||||
cache('team_user_count_'.$user['id'],count($team_user_ids));
|
||||
|
||||
$direct_use_count = Db::name('user')->where('parent_id',$user['id'])->count('id');
|
||||
$vip_user_count = Db::name('user')->whereIn('id',$team_user_ids)->where('role_id','>',0)->count('id');
|
||||
$vip_user_count = Db::name('user')->whereIn('id',$team_user_ids)->where('role_id','>',1)->count('id');
|
||||
|
||||
Db::name('user_extend')->where('user_id',$user['id'])->data([
|
||||
'direct_total'=> $direct_use_count,
|
||||
@@ -80,6 +102,7 @@ class User extends Command
|
||||
cache('team_direct_total_'.$user['id'],$direct_use_count);
|
||||
cache('team_vip_total_'.$user['id'],$vip_user_count);
|
||||
$this->level_up($user['id'],$vip_user_count);
|
||||
cp($user['id'].'完成');
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -87,10 +110,10 @@ class User extends Command
|
||||
protected function level_up($user_id,$count=0){
|
||||
$levels = [
|
||||
0,
|
||||
500,
|
||||
50,
|
||||
100,
|
||||
1000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
];
|
||||
$level = 0;
|
||||
|
||||
+23
-25
@@ -17,12 +17,23 @@ class User{
|
||||
'invite_code' => \support\Encrypt::userIDencode($_user['id']),
|
||||
'userID' => \support\Encrypt::userIDencode($_user['id'])
|
||||
];
|
||||
|
||||
\app\model\User::where('id',$_user['id'])->update($saveData);
|
||||
//创建扩展数据
|
||||
Db::name('user_extend')->replace()->insert([
|
||||
'user_id' => $_user['id'],
|
||||
'consume' => 0,
|
||||
// 'profile_banner' => '',
|
||||
// 'moments_banner' => '',
|
||||
// 'moments_allow_view_days'=>0,
|
||||
]);
|
||||
//管理直推人数和团队人数
|
||||
if($_user['parent_id']){
|
||||
parent_info( $_user['id'],[
|
||||
'id' => $_user['parent_id'],
|
||||
'username' => Db::name('user')->where('id',$_user['parent_id'])->value('username')
|
||||
]);
|
||||
$this->buildTeam($_user);
|
||||
//直属团队人数
|
||||
Db::name('user_extend')->where('user_id',$_user['parent_id'])
|
||||
->data([
|
||||
@@ -31,7 +42,7 @@ class User{
|
||||
cache_add('team_direct_total_'.$_user['parent_id'],1);
|
||||
|
||||
//管理团队人数
|
||||
$team_user_ids = Db::name('user_team')->where('descendant_id',$user['id'])
|
||||
$team_user_ids = Db::name('user_team')->where('descendant_id',$_user['id'])
|
||||
->where('depth','>',0)
|
||||
->order('depth','ASC')
|
||||
->column('ancestor_id');
|
||||
@@ -44,19 +55,6 @@ class User{
|
||||
cache('team_user_count_'.$v['user_id'],$v['team_total']);
|
||||
}
|
||||
}
|
||||
|
||||
\app\model\User::where('id',$_user['id'])->update($saveData);
|
||||
//创建扩展数据
|
||||
Db::name('user_extend')->replace()->insert([
|
||||
'user_id' => $_user['id'],
|
||||
'consume' => 0,
|
||||
// 'profile_banner' => '',
|
||||
// 'moments_banner' => '',
|
||||
// 'moments_allow_view_days'=>0,
|
||||
]);
|
||||
|
||||
|
||||
$this->buildTeam($user);
|
||||
}
|
||||
function login_successed($data=[]){
|
||||
$data = $this->profile($data);
|
||||
@@ -71,10 +69,10 @@ class User{
|
||||
protected function level_up($user_id,$count=0){
|
||||
$levels = [
|
||||
0,
|
||||
500,
|
||||
50,
|
||||
100,
|
||||
1000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
];
|
||||
$level = 0;
|
||||
@@ -100,7 +98,7 @@ class User{
|
||||
'userHeadImg' => null,
|
||||
];
|
||||
try {
|
||||
$ff = Db::name('user_extend')->where('user_id',$user->id)->field('moments_allow_view_days,profile_banner,moments_banner')->find();
|
||||
$ff = Db::name('user_extend')->where('user_id',$user['id'])->field('moments_allow_view_days,profile_banner,moments_banner')->find();
|
||||
$data['moments_allow_view_days'] = $ff['moments_allow_view_days'];
|
||||
$data['moments_banner'] = $ff['moments_banner'];
|
||||
$data['profile_banner'] = $ff['profile_banner'];
|
||||
@@ -170,29 +168,29 @@ class User{
|
||||
// 插入自己的团队关系 (自己是自己的后代)
|
||||
$teamData = [
|
||||
[
|
||||
'ancestor_id' => $user->id,
|
||||
'descendant_id' => $user->id,
|
||||
'ancestor_id' => $user['id'],
|
||||
'descendant_id' => $user['id'],
|
||||
'depth' => 0,
|
||||
'status' => 0,
|
||||
]
|
||||
];
|
||||
// 2. 处理团队关系(如果有推荐人)
|
||||
if ($user->parent_id) {
|
||||
if ($user['parent_id']) {
|
||||
|
||||
parent_info( $user->id,[
|
||||
'id' => $user->parent_id,
|
||||
'username' => Db::name('user')->where('id',$user->parent_id)->value('username')
|
||||
parent_info( $user['id'],[
|
||||
'id' => $user['parent_id'],
|
||||
'username' => Db::name('user')->where('id',$user['parent_id'])->value('username')
|
||||
]);
|
||||
// 获取推荐人所有的上级关系,生成新用户的团队关系
|
||||
$ancestors = Db::name('user_team')
|
||||
->where('descendant_id', $user->parent_id)
|
||||
->where('descendant_id', $user['parent_id'])
|
||||
->select();
|
||||
/** @var \app\model\UserTeam $ancestor */
|
||||
// 插入新用户与祖先的关系
|
||||
foreach ($ancestors as $ancestor) {
|
||||
$teamData[] = [
|
||||
'ancestor_id' => $ancestor['ancestor_id'],
|
||||
'descendant_id' => $user->id,
|
||||
'descendant_id' => $user['id'],
|
||||
'depth' => $ancestor['depth'] + 1,
|
||||
'status' => 1, // 默认状态为 0,表示无效
|
||||
];
|
||||
|
||||
+3
-3
@@ -499,13 +499,13 @@ if(!function_exists('cache_get')){
|
||||
if(!$ret || $force){
|
||||
if (str_starts_with($key, 'team_user_total_')) {
|
||||
$user_id = substr($key,strlen('team_user_total_'));
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->column('team_total');
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('team_total');
|
||||
}else if (str_starts_with($key, 'team_direct_total_')) {
|
||||
$user_id = substr($key,strlen('team_direct_total_'));
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->column('direct_total');
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('direct_total');
|
||||
}else if (str_starts_with($key, 'team_vip_total_')) {
|
||||
$user_id = substr($key,strlen('team_vip_total_'));
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->column('vip_total');
|
||||
$ret = \support\think\Db::name('user_extend')->where('user_id',$user_id)->value('vip_total');
|
||||
}
|
||||
cache($key,$ret);
|
||||
}
|
||||
|
||||
+27
-9
@@ -5,9 +5,12 @@ namespace app\model;
|
||||
* 相册模型
|
||||
* @property integer $id 主键(ID)
|
||||
* @property integer $user_id 用户ID
|
||||
* @property integer $group_id 内容
|
||||
* @property string $url 图片
|
||||
* @property integer $group_id 群组ID
|
||||
* @property integer $userID 用户ID
|
||||
* @property integer $groupID 群组ID
|
||||
* @property string $title 标题
|
||||
* @property int $image 封面图片ID
|
||||
* @property int $weigh 排序权重,越小越靠前
|
||||
* @property integer $created_at 创建时间
|
||||
* @property integer $updated_at 更新时间
|
||||
* @property integer $status 状态(0:隐藏 1:正常)
|
||||
@@ -22,30 +25,45 @@ class Album extends Base
|
||||
'insert' => [
|
||||
'status' => 1,
|
||||
],
|
||||
'append'=>[
|
||||
'userID',
|
||||
'groupID'
|
||||
]
|
||||
]);
|
||||
}
|
||||
public static function onAfterInsert($row){
|
||||
$changeData = $row->getChangedData();
|
||||
if(isset($changeData['url'])) {
|
||||
Files::where('path',$changeData['url'])->inc('use_count');
|
||||
if(isset($changeData['image'])) {
|
||||
Files::where('path',$changeData['image'])->inc('use_count');
|
||||
};
|
||||
}
|
||||
|
||||
public static function onAfterUpdate($row){
|
||||
$OrgData = $row->getOrigin();
|
||||
$changeData = $row->getChangedData();
|
||||
if(isset($OrgData['url']) && $OrgData['url']) {
|
||||
if(isset($OrgData['image']) && $OrgData['image']) {
|
||||
\support\Log::info('OrgData string');
|
||||
Files::where('path',$OrgData['url'])->dec('use_count');
|
||||
Files::where('path',$OrgData['image'])->dec('use_count');
|
||||
};
|
||||
if(isset($changeData['url']) && $changeData['url']) {
|
||||
if(isset($changeData['image']) && $changeData['image']) {
|
||||
\support\Log::info('changeData string');
|
||||
Files::where('path',$changeData['url'])->inc('use_count');
|
||||
Files::where('path',$changeData['image'])->inc('use_count');
|
||||
};
|
||||
}
|
||||
|
||||
public static function onBeforeDelete($row){
|
||||
if($row->total>0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static function onAfterDelete($row){
|
||||
Files::where('path',$row->url)->dec('use_count');
|
||||
Files::where('path',$row->image)->dec('use_count');
|
||||
}
|
||||
function getGroupIDAttr($v,$row){
|
||||
return $v?:$row['group_id'];
|
||||
}
|
||||
function getUserIDAttr($v,$row){
|
||||
return $v?:$row['user_id'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class BalanceLog extends Base
|
||||
// ],
|
||||
]);
|
||||
}
|
||||
public static function create(array|object $data, array $allowField = [], bool $replace = false):\think\model\contract\Modelable
|
||||
public static function create(array|object $data, array $allowField = [], bool $replace = false, string $suffix = ''):\think\model\contract\Modelable
|
||||
{
|
||||
$model = new static();
|
||||
if(isset($data['currency'])){
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace app\model;
|
||||
|
||||
/**
|
||||
* 相册模型
|
||||
* @property integer $id 主键(ID)
|
||||
* @property integer $album_id 用户ID
|
||||
* @property integer $user_id 用户ID
|
||||
* @property integer $group_id 内容
|
||||
* @property string $url 图片
|
||||
* @property string $title 标题
|
||||
* @property integer $created_at 创建时间
|
||||
* @property integer $updated_at 更新时间
|
||||
* @property integer $status 状态(0:隐藏 1:正常)
|
||||
*/
|
||||
class Gallery extends Base
|
||||
{
|
||||
protected $name = 'gallery';
|
||||
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return array_merge(parent::getOptions(), [
|
||||
'insert' => [
|
||||
'status' => 1,
|
||||
],
|
||||
'append'=>[
|
||||
'userID',
|
||||
'groupID'
|
||||
]
|
||||
]);
|
||||
}
|
||||
function getGroupIDAttr($v,$row){
|
||||
return $v?:$row['group_id'];
|
||||
}
|
||||
function getUserIDAttr($v,$row){
|
||||
return $v?:$row['user_id'];
|
||||
}
|
||||
public static function onAfterInsert($row){
|
||||
$changeData = $row->getChangedData();
|
||||
if(isset($changeData['url'])) {
|
||||
Files::where('path',$changeData['url'])->inc('use_count');
|
||||
};
|
||||
}
|
||||
|
||||
public static function onAfterUpdate($row){
|
||||
$OrgData = $row->getOrigin();
|
||||
$changeData = $row->getChangedData();
|
||||
if(isset($OrgData['url']) && $OrgData['url']) {
|
||||
\support\Log::info('OrgData string');
|
||||
Files::where('path',$OrgData['url'])->dec('use_count');
|
||||
};
|
||||
if(isset($changeData['url']) && $changeData['url']) {
|
||||
\support\Log::info('changeData string');
|
||||
Files::where('path',$changeData['url'])->inc('use_count');
|
||||
};
|
||||
}
|
||||
|
||||
public static function onAfterDelete($row){
|
||||
Files::where('path',$row->url)->dec('use_count');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+554
-40
@@ -39,7 +39,7 @@
|
||||
min-height: 100vh;
|
||||
line-height: 1.6;
|
||||
padding: 20px;
|
||||
_background-image: radial-gradient(at 0 0,rgba(var(--primary-rgb),0.05) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(var(--secondary-rgb),0.05) 0,transparent 50%)
|
||||
background-image: radial-gradient(at 0 0,rgba(39, 186, 87, 0.05) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(39, 186, 87, 0.05) 0,transparent 50%)
|
||||
}
|
||||
|
||||
.container {
|
||||
@@ -50,13 +50,17 @@
|
||||
box-shadow: var(--shadow);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 1
|
||||
z-index: 1;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.container:hover {
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
@@ -68,7 +72,9 @@
|
||||
|
||||
.header {
|
||||
padding: 40px 40px 30px;
|
||||
text-align: center
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.logo {
|
||||
@@ -80,7 +86,13 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: var(--shadow);
|
||||
margin-bottom: 20px
|
||||
margin-bottom: 20px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 6px 20px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.logo svg {
|
||||
@@ -99,7 +111,8 @@
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 14pt
|
||||
font-size: 14pt;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.card {
|
||||
@@ -161,10 +174,29 @@
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(67,97,238,0.15);
|
||||
box-shadow: 0 0 0 3px rgba(39, 186, 87, 0.15);
|
||||
outline: 0
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
border-color: #f56c6c;
|
||||
}
|
||||
|
||||
.form-control.success {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #f56c6c;
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.captcha-group {
|
||||
display: flex;
|
||||
gap: 12px
|
||||
@@ -184,11 +216,15 @@
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
padding: 0 16px
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.captcha-btn:hover {
|
||||
background-color: rgba(67,97,238,0.1)
|
||||
.captcha-btn:hover:not(:disabled) {
|
||||
background-color: rgba(39, 186, 87, 0.1);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.captcha-btn:disabled {
|
||||
@@ -209,18 +245,26 @@
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
margin-top: 10px;
|
||||
box-shadow: 0 4px 12px rgba(67,97,238,0.2)
|
||||
box-shadow: 0 4px 12px rgba(39, 186, 87, 0.2);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(67,97,238,0.3)
|
||||
box-shadow: 0 6px 16px rgba(39, 186, 87, 0.3)
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0)
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
@@ -239,7 +283,6 @@
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
|
||||
.other-options {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
@@ -282,6 +325,14 @@
|
||||
height: 60px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 12pt;
|
||||
}
|
||||
}
|
||||
/*成功卡片*/
|
||||
.success-card {
|
||||
@@ -447,6 +498,184 @@
|
||||
}
|
||||
}
|
||||
|
||||
.region .layui-select-title .layui-input{
|
||||
height: 51px;
|
||||
border-top-left-radius: 12px;
|
||||
border-bottom-left-radius: 12px;
|
||||
}
|
||||
|
||||
/* 密码强度指示器 */
|
||||
.password-strength {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.strength-bar {
|
||||
flex: 1;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
background-color: var(--border);
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.strength-bar.weak {
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
.strength-bar.medium {
|
||||
background-color: #e6a23c;
|
||||
}
|
||||
|
||||
.strength-bar.strong {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
.strength-text {
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.strength-text.weak {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.strength-text.medium {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.strength-text.strong {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.loading {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid rgba(255,255,255,0.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: #fff;
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 输入框图标 */
|
||||
.input-icon {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.form-control.has-icon {
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
/* 验证码按钮加载状态 */
|
||||
.captcha-btn.loading {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.captcha-btn.loading::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid rgba(39, 186, 87, 0.3);
|
||||
border-radius: 50%;
|
||||
border-top-color: var(--primary);
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 响应式优化 */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 16px;
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 0 24px 32px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 48px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.captcha-btn {
|
||||
min-width: 100px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.form-container {
|
||||
animation: fadeInUp 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 错误消息优化 */
|
||||
.error-message {
|
||||
font-size: 12px;
|
||||
color: #f56c6c;
|
||||
margin-top: 4px;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
min-height: 16px;
|
||||
}
|
||||
|
||||
/* 星星装饰优化 */
|
||||
.star {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: twinkle 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes twinkle {
|
||||
0%, 100% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 庆祝效果 */
|
||||
.confetti {
|
||||
position: absolute;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
</style>
|
||||
{/literal}
|
||||
</head>
|
||||
@@ -819,52 +1048,77 @@
|
||||
</svg>
|
||||
</div>
|
||||
<h1>欢迎回来</h1>
|
||||
<p>使用手机号码注册您的账户</p>
|
||||
<p>使用手机号或邮箱注册您的账户</p>
|
||||
</div>
|
||||
<div class="card" data-type="register">
|
||||
<!-- 注册表单 -->
|
||||
<div class="form-container active" id="register-form">
|
||||
<form id="registerForm" class="layui-form" method="post" action="/api/common/register">
|
||||
<input type="hidden" name="type" id="register_type" value="mobile" />
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="form-group">
|
||||
<label for="register-phone">手机号码</label>
|
||||
<label for="register-phone">手机号/邮箱</label>
|
||||
<div class="input-wrapper">
|
||||
<input type="tel" name="mobile" lay-reqtext="请输入您的手机号码" id="register-phone" class="form-control" placeholder="请输入您的手机号码" required lay-verify="required|phone">
|
||||
<i class="layui-icon layui-icon-cellphone input-icon"></i>
|
||||
<input type="text" name="mobile"
|
||||
lay-reqtext="请输入您的手机号或邮箱"
|
||||
id="register-phone"
|
||||
class="form-control has-icon"
|
||||
placeholder="请输入您的手机号或邮箱"
|
||||
required
|
||||
lay-verify="require|username" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="error-message" id="phone-error"></div>
|
||||
<div class="form-group" style="display: none;">
|
||||
<label for="register-password">我的昵称</label>
|
||||
<div class="input-wrapper">
|
||||
<input type="text" name="nickname" lay-reqtext="请设置您的昵称" id="register-nickname" class="form-control" placeholder="给自己取一个好听的昵称吧" required lay-verify="required">
|
||||
<i class="layui-icon layui-icon-username input-icon"></i>
|
||||
<input type="text" name="nickname" lay-reqtext="请设置您的昵称" id="register-nickname" class="form-control has-icon" placeholder="给自己取一个好听的昵称吧" lay-verify="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="register-captcha">验证码</label>
|
||||
<div class="captcha-group">
|
||||
<div class="input-wrapper" style="flex: 1;">
|
||||
<input type="text" lay-reqtext="请输入验证码" name="code" id="register-captcha" class="form-control captcha-input"
|
||||
<i class="layui-icon layui-icon-vercode input-icon"></i>
|
||||
<input type="text" lay-reqtext="请输入验证码" name="code" id="register-captcha" class="form-control captcha-input has-icon"
|
||||
placeholder="请输入验证码" required lay-verify="required|number">
|
||||
</div>
|
||||
<button type="button" class="captcha-btn" id="register-get-captcha">获取验证码</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="error-message" id="captcha-error"></div>
|
||||
<div class="form-group">
|
||||
<label for="register-password">设置密码</label>
|
||||
<div class="input-wrapper">
|
||||
<input type="password" lay-reqtext="请设置您的登录密码" name="password" id="register-password" class="form-control" placeholder="请输入6-20位密码"
|
||||
<i class="layui-icon layui-icon-password input-icon"></i>
|
||||
<input type="password" lay-reqtext="请设置您的登录密码" name="password" id="register-password" class="form-control has-icon" placeholder="请输入6-20位密码"
|
||||
required lay-verify="required|password">
|
||||
</div>
|
||||
<div class="password-strength">
|
||||
<div class="strength-bar" id="strength-bar-1"></div>
|
||||
<div class="strength-bar" id="strength-bar-2"></div>
|
||||
<div class="strength-bar" id="strength-bar-3"></div>
|
||||
</div>
|
||||
<div class="strength-text" id="strength-text">密码强度:弱</div>
|
||||
</div>
|
||||
<div class="error-message" id="password-error"></div>
|
||||
<div class="form-group">
|
||||
<label for="register-password">确认密码</label>
|
||||
<div class="input-wrapper">
|
||||
<input type="password" lay-reqtext="请再次输入密码" name="repassword" id="register-repassword" class="form-control" placeholder="请输入6-20位密码"
|
||||
<i class="layui-icon layui-icon-password input-icon"></i>
|
||||
<input type="password" lay-reqtext="请再次输入密码" name="repassword" id="register-repassword" class="form-control has-icon" placeholder="请输入6-20位密码"
|
||||
required lay-verify="required|repassword">
|
||||
</div>
|
||||
</div>
|
||||
<div class="error-message" id="repassword-error"></div>
|
||||
<div class="form-group">
|
||||
<label for="register-password">邀请码</label>
|
||||
<div class="input-wrapper">
|
||||
<input type="text" readonly class="form-control" lay-reqtext="参数错误" value="{$invite_code}" name="invite_code" required lay-verify="required">
|
||||
<i class="layui-icon layui-icon-code input-icon"></i>
|
||||
<input type="text" readonly class="form-control has-icon" lay-reqtext="参数错误" value="{$invite_code}" name="invite_code" required lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -904,15 +1158,162 @@
|
||||
{literal}
|
||||
<script type="text/javascript">
|
||||
layui.use(function(){
|
||||
var element = layui.element;
|
||||
var layer = layui.layer;
|
||||
var form = layui.form;
|
||||
var $ = layui.jquery;
|
||||
|
||||
// 初始化页面
|
||||
function initPage() {
|
||||
$('[data-type="register"]').show();
|
||||
$('[data-type="success"]').hide();
|
||||
generateStars();
|
||||
}
|
||||
|
||||
// 生成星星装饰
|
||||
function generateStars() {
|
||||
const stars = document.getElementById('stars');
|
||||
if (stars) {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const star = document.createElement('div');
|
||||
star.className = 'star';
|
||||
star.style.left = Math.random() * 100 + '%';
|
||||
star.style.top = Math.random() * 100 + '%';
|
||||
star.style.width = Math.random() * 3 + 1 + 'px';
|
||||
star.style.height = star.style.width;
|
||||
star.style.animationDelay = Math.random() * 3 + 's';
|
||||
stars.appendChild(star);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 密码强度检测
|
||||
function checkPasswordStrength(password) {
|
||||
let strength = 0;
|
||||
if (password.length >= 6) strength++;
|
||||
if (password.length >= 10) strength++;
|
||||
if (/[A-Z]/.test(password)) strength++;
|
||||
if (/[0-9]/.test(password)) strength++;
|
||||
if (/[^A-Za-z0-9]/.test(password)) strength++;
|
||||
|
||||
// 更新密码强度指示器
|
||||
const strengthBars = document.querySelectorAll('.strength-bar');
|
||||
const strengthText = document.getElementById('strength-text');
|
||||
|
||||
strengthBars.forEach((bar, index) => {
|
||||
bar.className = 'strength-bar';
|
||||
if (index < Math.floor(strength / 2)) {
|
||||
if (strength <= 2) {
|
||||
bar.classList.add('weak');
|
||||
} else if (strength <= 4) {
|
||||
bar.classList.add('medium');
|
||||
} else {
|
||||
bar.classList.add('strong');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (strength <= 2) {
|
||||
strengthText.textContent = '密码强度:弱';
|
||||
strengthText.className = 'strength-text weak';
|
||||
} else if (strength <= 4) {
|
||||
strengthText.textContent = '密码强度:中';
|
||||
strengthText.className = 'strength-text medium';
|
||||
} else {
|
||||
strengthText.textContent = '密码强度:强';
|
||||
strengthText.className = 'strength-text strong';
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框验证
|
||||
function validateInput(input, errorId, message) {
|
||||
const errorElement = document.getElementById(errorId);
|
||||
if (input.value.trim() === '') {
|
||||
input.classList.add('error');
|
||||
errorElement.textContent = message;
|
||||
errorElement.classList.add('show');
|
||||
return false;
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement.classList.remove('show');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 实时验证
|
||||
$('#register-phone').on('blur', function() {
|
||||
validateInput(this, 'phone-error', '请输入手机号或邮箱');
|
||||
});
|
||||
|
||||
$('#register-captcha').on('blur', function() {
|
||||
validateInput(this, 'captcha-error', '请输入验证码');
|
||||
});
|
||||
|
||||
$('#register-password').on('input', function() {
|
||||
checkPasswordStrength(this.value);
|
||||
validateInput(this, 'password-error', '请设置密码');
|
||||
});
|
||||
|
||||
$('#register-password').on('blur', function() {
|
||||
validateInput(this, 'password-error', '请设置密码');
|
||||
});
|
||||
|
||||
$('#register-repassword').on('blur', function() {
|
||||
if (this.value !== $('#register-password').val()) {
|
||||
this.classList.add('error');
|
||||
document.getElementById('repassword-error').textContent = '两次密码输入不一致';
|
||||
document.getElementById('repassword-error').classList.add('show');
|
||||
return false;
|
||||
} else {
|
||||
this.classList.remove('error');
|
||||
document.getElementById('repassword-error').classList.remove('show');
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// hash 地址定位
|
||||
var hashName = 'register_type'; // hash 名称
|
||||
var layid = location.hash.replace(new RegExp('^#'+ hashName + '='), ''); // 获取 lay-id 值
|
||||
layid = layid || 'mobile';
|
||||
// 初始切换
|
||||
element.tabChange('registe-type', layid);
|
||||
// 切换事件
|
||||
element.on('tab(registe-type)', function(obj){
|
||||
location.hash = hashName +'='+ this.getAttribute('lay-id');
|
||||
$('#register_type').val(this.getAttribute('lay-id'));
|
||||
});
|
||||
|
||||
form.verify({
|
||||
username:function(v,elem){
|
||||
if(v.indexOf('@') == -1){
|
||||
if(!v){return '手机号不能为空';}
|
||||
const reg = /^1[3-9]\d{9}$/;
|
||||
if(!reg.test(v)){
|
||||
return '手机号码格式错误';
|
||||
}
|
||||
$('#register_type').val('mobile');
|
||||
}else{
|
||||
if(!v){return '手机号或邮箱不能为空';}
|
||||
const reg = /^[a-zA-Z0-9._%+-]+@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/;
|
||||
if(!reg.test(v) || /[<>(){}[\]\\]/.test(v)){
|
||||
return '邮箱格式错误';
|
||||
}
|
||||
$('#register_type').val('email');
|
||||
}
|
||||
},
|
||||
phonerequire: function(value, elem) {
|
||||
if($('#register_type').val() == 'mobile'){
|
||||
if(!value){return '手机号不能为空';}
|
||||
}
|
||||
},
|
||||
emailrequire: function(value, elem) {
|
||||
if($('#register_type').val() == 'email'){
|
||||
if(!value){return '邮箱不能为空';}
|
||||
}
|
||||
},
|
||||
password: function(value, elem) {
|
||||
if (value.length < 6) {
|
||||
return '密码太过简单';
|
||||
return '密码长度不能少于6位';
|
||||
}
|
||||
},
|
||||
repassword: function(value, elem) {
|
||||
@@ -921,17 +1322,61 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#register-get-captcha').on('click',function(){
|
||||
var isValid = form.validate('#register-phone');
|
||||
// 验证通过
|
||||
if(!isValid){
|
||||
layer.msg('请输入正确的手机号',{icon:2});
|
||||
|
||||
function check_exist(callback){
|
||||
var elem = $('#register-phone');
|
||||
var v = elem.val();
|
||||
var msg='';
|
||||
var data={};
|
||||
var api_url='';
|
||||
if($('#register_type').val() == 'email'){
|
||||
api_url = '/api/Validate/check_email_exist';
|
||||
data={'email':v};
|
||||
msg='邮箱已经存在';
|
||||
}else{
|
||||
api_url = '/api/Validate/check_mobile_exist';
|
||||
data={'mobile':v};
|
||||
msg='手机号码已经存在';
|
||||
}
|
||||
$.post(api_url,data,function(res){
|
||||
if(res.code === 0){
|
||||
elem.removeClass('layui-form-danger').addClass('layui-form-danger');
|
||||
layer.msg(msg,{icon:2});
|
||||
return ;
|
||||
}
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
|
||||
$('#register-get-captcha').on('click',function(){
|
||||
var isValid = form.validate('#register-phone');
|
||||
var msg = '请输入正确的手机号或邮箱';
|
||||
var val = $('#register-phone').val();
|
||||
var senddata = {
|
||||
type:$('#register_type').val(),
|
||||
mobile:val,
|
||||
'event':'register'
|
||||
};
|
||||
if($('#register_type').val() == 'email'){
|
||||
delete senddata['mobile'];
|
||||
senddata['email'] = val;
|
||||
}
|
||||
// 验证通过
|
||||
if(!isValid){
|
||||
layer.msg(msg,{icon:2});
|
||||
return ;
|
||||
}
|
||||
|
||||
var btn = $('#register-get-captcha').get(0);
|
||||
var phone = $('#register-phone').val();
|
||||
// 禁用按钮并开始倒计时
|
||||
btn.disabled = true;
|
||||
btn.classList.add('loading');
|
||||
|
||||
check_exist(function(){
|
||||
$.post('/api/common/captcha',senddata,function(res){
|
||||
btn.classList.remove('loading');
|
||||
if(res.code === 0){
|
||||
layer.msg(`验证码已发送`,{icon:1});
|
||||
let countdown = 60;
|
||||
btn.innerHTML = `${countdown}秒后重新获取`;
|
||||
|
||||
@@ -945,44 +1390,113 @@
|
||||
btn.innerHTML = '获取验证码';
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// 这里应该是发送验证码的AJAX请求
|
||||
console.log(`发送验证码到手机: ${phone}`);
|
||||
$.post('/api/common/captcha',{type:'mobile',mobile:phone,'event':'register'},function(res){
|
||||
if(res.code === 0){
|
||||
console.log(res);
|
||||
layer.msg(`验证码已发送到手机 ${phone} (模拟)`,{icon:1});
|
||||
}else{
|
||||
clearInterval(timer);
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '获取验证码';
|
||||
layer.msg(res.msg,{icon:2});
|
||||
}
|
||||
}).fail(function() {
|
||||
btn.classList.remove('loading');
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '获取验证码';
|
||||
layer.msg('网络错误,请稍后重试',{icon:2});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// 提交事件
|
||||
form.on('submit(register-form)', function(data){
|
||||
var field = data.field; // 获取表单字段值
|
||||
// 显示填写结果,仅作演示用
|
||||
field['type'] = 'mobile';
|
||||
console.log(field);
|
||||
// 此处可执行 Ajax 等操作
|
||||
|
||||
// 验证所有输入框
|
||||
const phoneValid = validateInput($('#register-phone')[0], 'phone-error', '请输入手机号或邮箱');
|
||||
const captchaValid = validateInput($('#register-captcha')[0], 'captcha-error', '请输入验证码');
|
||||
const passwordValid = validateInput($('#register-password')[0], 'password-error', '请设置密码');
|
||||
const repasswordValid = validateInput($('#register-repassword')[0], 'repassword-error', '请确认密码');
|
||||
|
||||
if (!phoneValid || !captchaValid || !passwordValid || !repasswordValid) {
|
||||
layer.msg('请完善表单信息',{icon:2});
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($('#register-password').val() !== $('#register-repassword').val()) {
|
||||
$('#register-repassword')[0].classList.add('error');
|
||||
document.getElementById('repassword-error').textContent = '两次密码输入不一致';
|
||||
document.getElementById('repassword-error').classList.add('show');
|
||||
layer.msg('两次密码输入不一致',{icon:2});
|
||||
return false;
|
||||
}
|
||||
|
||||
const btn = this;
|
||||
const originalText = btn.innerHTML;
|
||||
btn.innerHTML = `<span class="layui-icon layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop"></span> 注册中...`;
|
||||
btn.disabled = true;
|
||||
if(field['type'] == 'email'){
|
||||
field['email'] = field['mobile'];
|
||||
delete field['mobile'];
|
||||
}
|
||||
$.post('/api/common/register', field, function(res){
|
||||
btn.innerHTML = originalText;
|
||||
btn.disabled = false;
|
||||
if(res.code === 0 ){
|
||||
// 更新成功页面的用户名
|
||||
if (res.data && res.data.username) {
|
||||
$('#username').text(res.data.username);
|
||||
}
|
||||
// 显示成功页面
|
||||
$('[data-type="register"]').hide();
|
||||
$('[data-type="success"]').show();
|
||||
// 生成庆祝效果
|
||||
createConfetti();
|
||||
}else{
|
||||
layer.msg(res.msg,{icon:2});
|
||||
}
|
||||
}).fail(function() {
|
||||
btn.innerHTML = originalText;
|
||||
btn.disabled = false;
|
||||
layer.msg('网络错误,请稍后重试',{icon:2});
|
||||
});
|
||||
|
||||
return false; // 阻止默认 form 跳转
|
||||
});
|
||||
|
||||
// 创建庆祝效果
|
||||
function createConfetti() {
|
||||
const successCard = document.querySelector('.success-card');
|
||||
if (!successCard) return;
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const confetti = document.createElement('div');
|
||||
confetti.className = 'confetti';
|
||||
confetti.style.left = Math.random() * 100 + '%';
|
||||
confetti.style.top = Math.random() * 100 + '%';
|
||||
confetti.style.backgroundColor = getRandomColor();
|
||||
confetti.style.width = Math.random() * 10 + 5 + 'px';
|
||||
confetti.style.height = Math.random() * 10 + 5 + 'px';
|
||||
confetti.style.opacity = 1;
|
||||
confetti.style.transform = 'translateY(0) rotate(0deg)';
|
||||
confetti.style.transition = 'all ' + (Math.random() * 3 + 2) + 's ease-out';
|
||||
|
||||
successCard.appendChild(confetti);
|
||||
|
||||
setTimeout(() => {
|
||||
confetti.style.opacity = 0;
|
||||
confetti.style.transform = 'translateY(100px) rotate(720deg)';
|
||||
setTimeout(() => {
|
||||
confetti.remove();
|
||||
}, 5000);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取随机颜色
|
||||
function getRandomColor() {
|
||||
const colors = ['#f00', '#0f0', '#00f', '#ff0', '#f0f', '#0ff', '#333', '#666', '#999'];
|
||||
return colors[Math.floor(Math.random() * colors.length)];
|
||||
}
|
||||
|
||||
// 初始化页面
|
||||
initPage();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -86,6 +86,7 @@ class AccountController extends Crud
|
||||
$username = $request->post('username', '');
|
||||
$this->removeLoginLimit($username);
|
||||
$password = $request->post('password', '');
|
||||
$code = $request->post('code', '');
|
||||
if (!$username) {
|
||||
return $this->fail('用户名不能为空');
|
||||
}
|
||||
@@ -94,9 +95,13 @@ class AccountController extends Crud
|
||||
* @var Admin $admin
|
||||
*/
|
||||
$admin = Admin::where('username', $username)->find();
|
||||
// if (!$admin || !Util::passwordVerify($password, $admin->password)) {
|
||||
// return $this->fail('账户不存在或密码错误');
|
||||
// }
|
||||
if ($admin->status != 1) {
|
||||
return $this->fail('当前账户暂时无法登录');
|
||||
}
|
||||
if(!$code && !$password){
|
||||
return $this->fail('请输入验证码或密码');
|
||||
}
|
||||
if($code){
|
||||
//$secret = $admin['totp_secret'] ?:'EJGYB7OZR2W46XRX7VB3PXHSOY4LUAWCA5GTDAVTWKHXNDAAAIIP7AQ3JSO3XZJNX5J5OTIDEQVKLYFYIYNAXSCYF4GNZ2EMA4ORA3Y';
|
||||
//\support\Log::alert($admin['totp_secret']);
|
||||
$totp = \OTPHP\TOTP::create($admin->totp_secret);
|
||||
@@ -108,11 +113,14 @@ class AccountController extends Crud
|
||||
//cp($qrCodeUri);
|
||||
//cp('https://api.qrtool.cn/?text='.urlencode($qrCodeUri));
|
||||
//cp($totp->at(time()));
|
||||
if (!$totp->verify($request->post('code', ''))) {
|
||||
return $this->fail('当前账户暂时无法登录1');
|
||||
if (!$totp->verify($code)) {
|
||||
return $this->fail('动态密码错误');
|
||||
}
|
||||
}
|
||||
if($password){
|
||||
if (!$admin || !Util::passwordVerify($password, $admin->password)) {
|
||||
return $this->fail('账户不存在或密码错误');
|
||||
}
|
||||
if ($admin->status != 1) {
|
||||
return $this->fail('当前账户暂时无法登录');
|
||||
}
|
||||
$admin->login_at = time();
|
||||
$admin->save();
|
||||
|
||||
@@ -374,7 +374,8 @@ class Crud extends Base
|
||||
}
|
||||
}
|
||||
}
|
||||
$password_filed = 'password';
|
||||
$password_fileds = ['password','trade_password','empty_password'];
|
||||
foreach($password_fileds as $password_filed){
|
||||
if (isset($data[$password_filed])) {
|
||||
// 密码为空,则不更新密码
|
||||
if ($data[$password_filed] === '') {
|
||||
@@ -383,14 +384,6 @@ class Crud extends Base
|
||||
$data[$password_filed] = Util::passwordHash(md5($data[$password_filed]));
|
||||
}
|
||||
}
|
||||
$password_filed = 'trade_password';
|
||||
if (isset($data[$password_filed])) {
|
||||
// 密码为空,则不更新密码
|
||||
if ($data[$password_filed] === '') {
|
||||
unset($data[$password_filed]);
|
||||
} else {
|
||||
$data[$password_filed] = Util::passwordHash($data[$password_filed]);
|
||||
}
|
||||
}
|
||||
unset($data[$primary_key]);
|
||||
return [$id, $data];
|
||||
|
||||
@@ -69,7 +69,6 @@ class IndexController extends Base
|
||||
}
|
||||
//$day7_user_recharge_sum = Recharge::where('status',2)->whereTime('created_at', '-7 days')->sum('amount');
|
||||
// 总用户数
|
||||
$user_count = \app\model\User::where('status',1)->count('id');
|
||||
$recharge_total = 0;//\app\model\Recharge::where('status',\app\enum\RechargeStatus::COMPLETE->value)->sum('amount');
|
||||
// mysql版本
|
||||
$withdrawl_total = \app\model\Withdrawl::where('status',\app\enum\WithdrawlStatus::COMPLETE->value)->sum('recive_amount');
|
||||
@@ -90,7 +89,6 @@ class IndexController extends Base
|
||||
return view('index/dashboard', [
|
||||
'today_user_recharge_sum' => formatAmount(cache('statistics_recharge_amount_'.date('Y-m-d')),0),
|
||||
'day7_user_recharge_sum' => formatAmount($day7_user_recharge_sum,0),
|
||||
'user_count' => $user_count,
|
||||
//'recharge' => $recharge,
|
||||
//'withdrawl' => $withdrawl,
|
||||
'recharge_total' => formatAmount($recharge_total,0),
|
||||
@@ -122,39 +120,28 @@ class IndexController extends Base
|
||||
}
|
||||
return $this->success('ok',$res);
|
||||
}
|
||||
function recharge_lines()
|
||||
{
|
||||
function lines_data(){
|
||||
$days = Input('days',7);
|
||||
$items = Input('items','');
|
||||
$items = explode(',',$items);
|
||||
$res = [];
|
||||
for ($i=7; $i >= 0; $i--) {
|
||||
for ($i=$days; $i >= 0; $i--) {
|
||||
$date = date('Y-m-d',strtotime('-'.$i.' days'));
|
||||
$res[$date] = [
|
||||
'amount' => cache('statistics_recharge_amount_'.$date)?:0,
|
||||
];
|
||||
$item= [];
|
||||
foreach($items as $k=>$v){
|
||||
if($v == 'withdrawl'){
|
||||
$item[$v] = cache('statistics_withdrawl_amount_'.$date)?:0;
|
||||
}
|
||||
return $this->success('ok',$res);
|
||||
if($v == 'recharge'){
|
||||
$item[$v] = cache('statistics_recharge_amount_'.$date)?:0;
|
||||
}
|
||||
function withdrawl_lines()
|
||||
{
|
||||
$res = [];
|
||||
for ($i=7; $i >= 0; $i--) {
|
||||
$date = date('Y-m-d',strtotime('-'.$i.' days'));
|
||||
$res[$date] = [
|
||||
'amount' => cache('statistics_withdrawl_amount_'.$date)?:0,
|
||||
];
|
||||
if($v == 'register'){
|
||||
$item[$v] = cache('statistics_register_'.$date)?:0;
|
||||
}
|
||||
return $this->success('ok',$res);
|
||||
}
|
||||
function money_lines()
|
||||
{
|
||||
$res = [];
|
||||
for ($i=7; $i >= 0; $i--) {
|
||||
$date = date('Y-m-d',strtotime('-'.$i.' days'));
|
||||
$res[$date] = [
|
||||
'withdrawl' => cache('statistics_withdrawl_amount_'.$date)?:0,
|
||||
'recharge' => cache('statistics_recharge_amount_'.$date)?:0,
|
||||
];
|
||||
$res[$date] = $item;
|
||||
}
|
||||
return $this->success('ok',$res);
|
||||
return $this->success('ok'.$items,$res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ class Config implements MiddlewareInterface
|
||||
$config['action'] = $request->action_name;
|
||||
$config['moduleurl'] = admin_path();
|
||||
$config['admin_path'] = admin_path();
|
||||
$config['development'] = config('site.name') == '瞬聊Test';
|
||||
$config['domain'] = env_get('server.domain','');
|
||||
$request->_view_vars = array_merge((array) $request->_view_vars,[
|
||||
'user' => session('admin'),
|
||||
|
||||
@@ -54,18 +54,28 @@
|
||||
<div class="login-header text-center">
|
||||
<a href="javascript:;" style="font-size: 22px;display: flex;align-items: center;justify-content: center;"> <img alt="{$title}" src="{$logo}" width="32" class="m-r-5" />{$title}</a>
|
||||
</div>
|
||||
<ul class="nav nav-tabs nav-justified">
|
||||
<li class="active"><a data-toggle="tab" href="#otop_login">OTOP登录</a></li>
|
||||
<li class="nav-item"><a data-toggle="tab" href="#passowrd_login">密码登录</a></li>
|
||||
</ul>
|
||||
<form action="{:url('account/login')}" method="post" id="loginform" valid>
|
||||
<div class="form-group has-feedback feedback-left">
|
||||
<span class="mdi mdi-account form-control-feedback" aria-hidden="true"></span>
|
||||
<input type="text" placeholder="请输入您的用户名" class="form-control" name="username" id="username" data-rule="required" data-msg="请输入您的用户名"/>
|
||||
</div>
|
||||
<!-- <div class="form-group has-feedback feedback-left">
|
||||
<span class="mdi mdi-lock form-control-feedback" aria-hidden="true"></span>
|
||||
<input type="password" placeholder="请输入密码" class="form-control" id="password" name="password" data-rule="required;password" />
|
||||
</div> -->
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade active in" id="otop_login">
|
||||
<div class="form-group has-feedback feedback-left">
|
||||
<span class="mdi mdi-lock form-control-feedback" aria-hidden="true"></span>
|
||||
<input type="code" placeholder="请输入OTOP验证码" class="form-control" id="code" name="code" data-rule="required;length(4)" data-msg="请输入OTOP验证码" />
|
||||
<input type="code" placeholder="请输入OTOP验证码" class="form-control" id="code" name="code" data-rule="required(#otop_login.active);length(4)" data-msg="请输入OTOP验证码" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="passowrd_login">
|
||||
<div class="form-group has-feedback feedback-left">
|
||||
<span class="mdi mdi-lock form-control-feedback" aria-hidden="true"></span>
|
||||
<input type="password" placeholder="请输入密码" class="form-control" id="password" name="password" data-rule="required(#passowrd_login.active);password" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{if Config('site.admin_login_captcha')}
|
||||
<div class="form-group has-feedback feedback-left row">
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
<p class="h6 text-white m-t-0">7日内充值</p>
|
||||
<p class="h3 text-white m-b-0 fa-1-5x"><?=$day7_user_recharge_sum?></p>
|
||||
</div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i
|
||||
class="mdi mdi-account fa-1-5x"></i></span> </div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-account fa-1-5x"></i></span> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,8 +31,7 @@
|
||||
<p class="h6 text-white m-t-0">总充值</p>
|
||||
<p class="h3 text-white m-b-0 fa-1-5x"><?=$recharge_total?></p>
|
||||
</div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i
|
||||
class="mdi mdi-arrow-down-bold fa-1-5x"></i></span> </div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-arrow-down-bold fa-1-5x"></i></span> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,8 +43,7 @@
|
||||
<p class="h6 text-white m-t-0">总提现</p>
|
||||
<p class="h3 text-white m-b-0 fa-1-5x"><?=$withdrawl_total?></p>
|
||||
</div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i
|
||||
class="mdi mdi-arrow-up-bold fa-1-5x"></i></span> </div>
|
||||
<div class="pull-left"> <span class="img-avatar img-avatar-48 bg-translucent"><i class="mdi mdi-arrow-up-bold fa-1-5x"></i></span> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,28 +87,24 @@
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>渠道商数</td>
|
||||
<td>
|
||||
<?php
|
||||
echo \app\model\User::where('group_id',1)->count('id');
|
||||
?>
|
||||
</td>
|
||||
<td>用户总数</td>
|
||||
<td><?php echo \app\model\User::count('id');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户余额总和</td>
|
||||
<td>{$user_money_total}</td>
|
||||
<td>VIP用户数</td>
|
||||
<td><?php echo \app\model\User::where('role_id',2)->count('id');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SVIP1用户数</td>
|
||||
<td><?php echo \app\model\User::where('role_id',3)->count('id');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>SVIP2用户数</td>
|
||||
<td><?php echo \app\model\User::where('role_id',4)->count('id');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户积分总和</td>
|
||||
<td>{$user_score_total}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>调研币总和</td>
|
||||
<td><?php echo \app\model\User::sum('currency1');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>待分配总和</td>
|
||||
<td><?php echo \app\model\User::sum('currency7');?></td>
|
||||
<td><?php echo \app\model\User::sum('score');?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -132,49 +125,24 @@
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>问卷成交个数</td>
|
||||
<td>
|
||||
<?php $system_question_total = cache('system_question_total');echo $system_question_total;?>
|
||||
</td>
|
||||
<td>操作系统</td>
|
||||
<td>{$os}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>预计支出泡沫</td>
|
||||
<td>
|
||||
<?php $system_question_cha_total = 0;echo $system_question_cha_total;?>
|
||||
</td>
|
||||
<td>workerman</td>
|
||||
<td>{$workerman_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>总沉淀金额</td>
|
||||
<td>
|
||||
<?php
|
||||
$system_role_buy_amount_total = cache('system_role_buy_amount_total');
|
||||
$system_role_buy_reward_total = cache('system_role_buy_reward_total');
|
||||
$system_role_buy_residual_total = $system_role_buy_amount_total - $system_role_buy_reward_total;
|
||||
echo $system_role_buy_residual_total;
|
||||
?>
|
||||
|
||||
</td>
|
||||
<td>webman</td>
|
||||
<td>{$webman_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>实际泡沫</td>
|
||||
<td>
|
||||
<?php
|
||||
$cha = $system_question_cha_total - $system_role_buy_residual_total;
|
||||
if($cha>0){
|
||||
echo '<span class="text-danger">'.$cha.'</span>';
|
||||
}else{
|
||||
echo '<span class="text-success">'.$cha.'</span>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>php</td>
|
||||
<td>{$php_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td></td>
|
||||
<td>MySQL</td>
|
||||
<td>{$mysql_version}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -83,7 +83,11 @@ define(['lightyear','multitabs', '../libs/Chart','form','bootstrap'], function (
|
||||
setTheme = function (input_name, data_name) {
|
||||
$("input[name='" + input_name + "']").click(function () {
|
||||
$('body').attr(data_name, $(this).val());
|
||||
localStorage.setItem(data_name,$(this).val());
|
||||
});
|
||||
if(Config.development){
|
||||
$('body').attr(data_name, localStorage.getItem(data_name) || 'color_8');
|
||||
}
|
||||
}
|
||||
setTheme('logo_bg', 'data-logobg');
|
||||
setTheme('header_bg', 'data-headerbg');
|
||||
@@ -167,47 +171,7 @@ define(['lightyear','multitabs', '../libs/Chart','form','bootstrap'], function (
|
||||
});
|
||||
},
|
||||
dashboard: function () {
|
||||
// new Chart(
|
||||
// document.getElementsByClassName('js-chartjs-bars'),
|
||||
// {
|
||||
// type: 'bar',
|
||||
// data: {
|
||||
// labels: recharge_labels,
|
||||
// datasets: [
|
||||
// {
|
||||
// label: '充值统计',
|
||||
// data: recharge_values,
|
||||
// borderColor: '#358ed7',
|
||||
// backgroundColor: 'rgba(53, 142, 215, 0.175)',
|
||||
// borderWidth: 1,
|
||||
// fill: false,
|
||||
// lineTension: 0.5
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// new Chart(
|
||||
// document.getElementsByClassName('js-chartjs-lines'),
|
||||
// {
|
||||
// type: 'bar',//line
|
||||
// data: {
|
||||
// labels: withdrawl_labels,
|
||||
// datasets: [
|
||||
// {
|
||||
// label: '提现统计',
|
||||
// data: withdrawl_values,
|
||||
// borderColor: '#358ed7',
|
||||
// backgroundColor: 'rgba(53, 142, 215, 0.175)',
|
||||
// borderWidth: 1,
|
||||
// fill: false,
|
||||
// lineTension: 0.5
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
$.getJSON('index/money_lines',function(res){
|
||||
$.getJSON('index/lines_data?items=withdrawl,recharge&days=7',function(res){
|
||||
res = res.data;
|
||||
var labels=[];
|
||||
var withdrawl_values=[];
|
||||
@@ -248,17 +212,13 @@ define(['lightyear','multitabs', '../libs/Chart','form','bootstrap'], function (
|
||||
}
|
||||
);
|
||||
});
|
||||
$.getJSON('index/role_buy_lines',function(res){
|
||||
$.getJSON('index/lines_data?items=register&days=7',function(res){
|
||||
res = res.data;
|
||||
var amount=[];
|
||||
var reward=[];
|
||||
var residual=[];
|
||||
var register=[];
|
||||
var labels=[];
|
||||
for (let date in res) {
|
||||
labels.push(date);
|
||||
amount.push(res[date].amount);
|
||||
reward.push(res[date].reward);
|
||||
residual.push(res[date].residual);
|
||||
register.push(res[date].register);
|
||||
}
|
||||
new Chart(document.getElementsByClassName('js-role_buy_lines'),{
|
||||
type: 'line',
|
||||
@@ -266,32 +226,32 @@ define(['lightyear','multitabs', '../libs/Chart','form','bootstrap'], function (
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
label: '总购买金额',
|
||||
data: amount,
|
||||
label: '注册统计',
|
||||
data: register,
|
||||
borderColor: 'rgba(43, 191, 232, 0.7)',
|
||||
backgroundColor: 'rgba(43, 191, 232, 0.7)',
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
lineTension: 0.5
|
||||
},
|
||||
{
|
||||
label: '奖励统计',
|
||||
data: reward,
|
||||
borderColor: 'rgba(166, 53, 215, 0.7)',
|
||||
backgroundColor: 'rgba(166, 53, 215, 0.7)',
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
lineTension: 0.5
|
||||
},
|
||||
{
|
||||
label: '沉淀统计',
|
||||
data: residual,
|
||||
borderColor: 'rgba(59, 199, 8, 0.7)',
|
||||
backgroundColor: 'rgba(59, 199, 8, 0.7)',
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
lineTension: 0.5
|
||||
}
|
||||
// {
|
||||
// label: '奖励统计',
|
||||
// data: reward,
|
||||
// borderColor: 'rgba(166, 53, 215, 0.7)',
|
||||
// backgroundColor: 'rgba(166, 53, 215, 0.7)',
|
||||
// borderWidth: 2,
|
||||
// fill: false,
|
||||
// lineTension: 0.5
|
||||
// },
|
||||
// {
|
||||
// label: '沉淀统计',
|
||||
// data: residual,
|
||||
// borderColor: 'rgba(59, 199, 8, 0.7)',
|
||||
// backgroundColor: 'rgba(59, 199, 8, 0.7)',
|
||||
// borderWidth: 2,
|
||||
// fill: false,
|
||||
// lineTension: 0.5
|
||||
// }
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
@@ -50,11 +50,13 @@ define(['table', 'upload','form','qrcode'], function (Table,Upload,Form) {
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
field: "username"
|
||||
field: "username",
|
||||
filter: "string"
|
||||
},
|
||||
{
|
||||
title: "昵称",
|
||||
field: "nickname"
|
||||
field: "nickname",
|
||||
filter: "string"
|
||||
},
|
||||
{
|
||||
title: "头像",
|
||||
|
||||
@@ -79,3 +79,11 @@ bash bootstrap.sh
|
||||
mage
|
||||
mage start
|
||||
docker exec -it mongo mongorestore --uri="mongodb://openIM:n1e5a6s6m7@172.18.0.1:37017/openim_v3" /data/backup/3/openim_v3
|
||||
docker exec -it mongo mongorestore --uri="mongodb://openIM:n1e5a6s6m7@localhost:27017/openim_v3" /data/backup/0/openim_v3
|
||||
|
||||
修复未读<0的问题
|
||||
cd /www/wwwroot/im/server
|
||||
go run tools/fix-conversation-maxseq/main.go --config config --dry-run
|
||||
清理15天以前的消息
|
||||
cd /www/wwwroot/im/server
|
||||
go run tools/clean-old-messages/main.go --config config --days 15
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ class Jwt
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'mobile' => $mobile,
|
||||
'level' => 1,
|
||||
'level' => 0,
|
||||
'score' => 0,
|
||||
'avatar' => '',
|
||||
];
|
||||
|
||||
@@ -33,9 +33,8 @@ class Auth
|
||||
public function getUserToken(string $userID, string $platformID = 'android'): array
|
||||
{
|
||||
// 获取管理员token
|
||||
$adminToken = Utils::getAdminToken();
|
||||
$platformID = Utils::getPlatformId( $platformID );
|
||||
return Utils::send(Url::$getUserToken, ['userID' => $userID, 'platformID' => $platformID], '获取用户token错误', $adminToken);
|
||||
return Utils::send(Url::$getUserToken, ['userID' => $userID, 'platformID' => $platformID], '获取用户token错误');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,7 +63,7 @@ class Friend
|
||||
* @param string $friendUserID 好友ID
|
||||
* @return array
|
||||
*/
|
||||
public function deleteFriend(string $ownerUserID, string $friendUserID): array
|
||||
public function deleteFriend(string $ownerUserID, string $friendUserID): array|bool
|
||||
{
|
||||
// 获取管理员token
|
||||
$adminToken = Utils::getAdminToken();
|
||||
|
||||
@@ -192,6 +192,9 @@ class Utils
|
||||
return self::getTokenManager()->clearToken($userID, $isAdmin);
|
||||
}
|
||||
public static function getPlatformId($name=''): int{
|
||||
if(ctype_digit($name)){
|
||||
return (int)$name;
|
||||
}
|
||||
$arr = [
|
||||
'ios' => 1,
|
||||
'android' => 2,
|
||||
|
||||
Reference in New Issue
Block a user