This commit is contained in:
2025-12-24 16:59:05 +08:00
parent b52a51c09b
commit b68946fe79
218 changed files with 10790 additions and 3878 deletions
+39 -4
View File
@@ -5,6 +5,7 @@ use support\Response;
use Shopwwi\WebmanFilesystem\FilesystemFactory;
use Shopwwi\WebmanFilesystem\Facade\Storage;
use hg\apidoc\annotation as Apidoc;
use taoser\facade\Validate;
/**
* 基础控制器
* @Apidoc\NotParse()
@@ -62,14 +63,48 @@ class BaseController
*/
function upload(Request $request)
{
try{
$user = \support\Jwt::getUser();
}catch(\Exception $e){
$user = ['id'=>0];
}
$savePath = $request->post('savePath','files');
$validate = Validate::rule('savePath', 'alphaNum');
$data = ['savePath' => $savePath];
if (!$validate->check($data)) {
return $this->fail( '参数错误:'.$validate->getError());
}
$savePath = trim($savePath,'/');
$savePath = 'upload/'.$savePath.'/'.$user['id'];
\support\Log::alert('savePath:'.$savePath);
$mimetype = explode(',',Config('site.upload_mimetype'));
$maxsize = Config('site.upload_maxsize')*1024*1024;
//多文件上传
$files = $request->file();
try {
$result = Storage::adapter('public')
->path('upload/files')
->size(1024*1024*10)
->extYes(['image/jpeg','image/png'])
->uploads($files,0,1024*1024*100,false);
->path($savePath)
->size($maxsize)
->extYes($mimetype)
->uploads($files,0,$maxsize * count($files),false);
$save_datas = [];
foreach($result as $k=>$fileinfo){
$save_datas[] = [
'user_id' => $user['id'],
'category' => 'default',
'title' => $fileinfo->origin_name,
'path' => $fileinfo->file_name,
'size' => $fileinfo->size,
'mime_type' => $fileinfo->mime_type,
'extension' => $fileinfo->extension,
'height' => $fileinfo->file_height,
'width' => $fileinfo->file_width,
'sha1' => sha1_file(public_path($fileinfo->file_name)),
'use_count' => 0,
];
}
\app\model\Files::insertAll($save_datas);
return $this->success(__('successful'),$result);
}catch (\Exception $e){
return $this->error($e->getMessage());
+124 -88
View File
@@ -12,6 +12,7 @@ use Shopwwi\WebmanFilesystem\FilesystemFactory;
use Shopwwi\WebmanFilesystem\Facade\Storage;
use hg\apidoc\annotation as Apidoc;
use think\facade\Db;
/**
* 公共接口
*/
@@ -34,7 +35,7 @@ class CommonController extends BaseController{
*
* @Apidoc\Query("version", type="string", require=true, desc="版本号")
*/
public function init()
public function init(Request $request)
{
$lang = input('lang','en-US');
locale( $lang);
@@ -42,9 +43,9 @@ class CommonController extends BaseController{
$disallowFields = [
'api_token','reward_time_limit',
'mail_type','mail_smtp_host','mail_smtp_port','mail_smtp_user','mail_smtp_pass','mail_verify_type','mail_from',
'attachmentcategory','categorytype','cdkey_category','configgroup','flagtype',
'attachment_category','categorytype','cdkey_category','configgroup','flagtype',
'languages','forbiddenip','fixedpage','admin_login_captcha',
'mimetype','multipart','multiple','chunksize','classname','thumbstyle','previewtpl','timeout','maxsize','container',
'upload_mimetype','upload_multipart','upload_multiple','upload_thumbstyle','upload_previewtpl','upload_timeout','upload_maxsize',
'yeji_jicha_reward','suanli_rate','agent_expirs_retention','allow_currencys','allow_balance_log',
'agent_commission_total_rate','agent_commission_layer_rate','differential_commission_total_rate'
];
@@ -58,13 +59,30 @@ class CommonController extends BaseController{
$config['server_status_list'] = \app\enum\ServerStatus::toArray();
return $this->success(__('successful'), $config);
}
/**
* test
* @Apidoc\Query("lang", type="string",require=true, desc="邮箱")
* @Apidoc\Method ("GET")
* 验证是否升级
*/
function test(){
return $this->error(__('Invalid parameters'));
public function checkUpgrade(Request $request)
{
$field = 'id,type,force,source,version,content';
$verUpdate = new \app\model\Version;
$version = Input('version');
$platform = Input('platform');
$version_wgt = Input('version_wgt');
// 查询整包、外链数据
$update_data = $verUpdate->where(['type'=>['in', '0,2'], 'status'=>1, 'version'=>['>', $version], 'platform'=>$platform])->field($field)->order('id desc')->find();
if($update_data) {
return $this->success('',$update_data);
}
// 查询WGT数据
$update_wgt_data = $verUpdate->where(['type'=>1, 'status'=>1, 'version_wgt'=>['>', $version_wgt], 'platform'=>$platform])->field($field)->order('id desc')->find();
if($update_wgt_data) {
return $this->success('',$update_wgt_data);
}
return $this->success('',[]);
}
/**
* 注册会员
@@ -84,65 +102,72 @@ class CommonController extends BaseController{
$username = input('username');
$mobile = input('mobile');
$invite_code = input('invite_code');
if ($email && !Validate::is($email, "email")) {
return $this->error(__('Email is incorrect'));
$type = input('type');
if (!in_array($type,Config('site.user_register_way')) ) {
return $this->error(__('Unknown register way'));
}
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
return $this->error(__('Mobile is incorrect'));
}
if(Config('site.user_register_way') == 'mobile'){
if (!$mobile) {
return $this->error(__('Invalid parameters'));
}
$username = $mobile;
captcha_verfiy('mobile','register',$mobile);
}else if(Config('site.user_register_way') == 'email'){
if (!$email) {
return $this->error(__('Invalid parameters'));
}
if ($email && !Validate::is($email, "email")) {
if ($type == 'email') {
if(!$email || !Validate::is($email, "email")){
return $this->error(__('Email is incorrect'));
}
$username = $email;
captcha_verfiy('email','register',$email);
}else{
if (!$username) {
return $this->error(__('Invalid parameters'));
unset($mobile);
//captcha_verfiy('email','register',$email,false);
}
if ($type == 'mobile') {
if(!$mobile || !Validate::regex($mobile, "^1\d{10}$")){
return $this->error(__('Mobile is incorrect'));
}
$username = $mobile;
unset($email);
//captcha_verfiy('mobile','register',$mobile,false);
}
if ($type == 'username') {
if(!$email || !Validate::is($email, "email")){
return $this->error(__('Username is incorrect'));
}
}
if (!$password) {
return $this->error(__('Invalid parameters'));
}
$extends = [
'role_id' => 0,
'group' => 0,
'avatar' => '/static/img/avatar.png',
];
// if (!$trade_password) {
// return $this->error(__('Invalid trade password'));
// }else{
// $extends['trade_password'] = \plugin\admin\app\common\Util::passwordHash($trade_password);
// }
//邀请码
if(!$invite_code){
return $this->error(__('Invalid invite code'));
}
if(strlen($invite_code) == 12){
//系统生产的一次性推荐吗
$inviteModel = \app\model\Invitecode::where('code',$invite_code)->find();
if(!$inviteModel){
return $this->error(__('错误的邀请码'));
if ($invite_code)
{
if(strlen($invite_code) == 12){
//系统生产的一次性推荐吗
$inviteModel = \app\model\Invitecode::where('code',$invite_code)->find();
if(!$inviteModel){
return $this->error(__('错误的邀请码'));
}
$extends['group'] = 2;
$extends['role_id'] = 1;
$extends['parent_id'] = 0;
}else{
$inviter_user = UserModel::where('invite_code',$invite_code)->field('group,id')->find();
if(!$inviter_user){
return $this->error(__('Invalid invite code'));
}
$extends['parent_id'] = $inviter_user['id'];
}
$extends['group'] = 2;
$extends['role_id'] = 1;
$extends['parent_id'] = 0;
}else{
$inviter_user = UserModel::where('invite_code',$invite_code)->field('group,id')->find();
if(!$inviter_user){
return $this->error(__('Invalid invite code'));
}
$extends['parent_id'] = $inviter_user['id'];
//return $this->error(__('Invalid invite code'));
}
$extends = [
'role_id' => 0,
'group_id' => 0,
'avatar' => '/static/img/avatar.png',
];
// validate(\app\validate\User::class)
// ->scene('edit')
// ->check([
// 'name' => 'thinkphp',
// 'email' => 'thinkphp@qq.com',
// ]);
try {
$user = \support\Jwt::register($username, $password, $email, $mobile, $extends);
if($inviteModel){
@@ -150,8 +175,15 @@ class CommonController extends BaseController{
$inviteModel->save();
}
$data = ['userinfo' => $user];
// if ($type == 'email') {
// captcha_verfiy('email','register',$email,true);
// }else if ($type == 'mobile') {
// captcha_verfiy('mobile','register',$mobile,true);
// }else{
// captcha_verfiy('image','register',$mobile,true);
// }
return $this->success(__('Sign up successful'), $data);
} catch (\Throwable $e) {
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
}
@@ -163,12 +195,30 @@ class CommonController extends BaseController{
*/
public function login(Request $request){
$username = input('username');
$mobile = input('mobile');
$email = input('email');
$password = input('password');
if (!$username || !$password) {
return $this->fail(__('Invalid username or password'));
$type = input(param: 'type');
if (!$password) {
return $this->fail(__('Invalid username or password').'0');
}
if($type == 'mobile'){
if (!$mobile ) {
return $this->fail(__('Invalid username or password').'1');
}
$username = $mobile;
}else if($type == 'email'){
if (!$email ) {
return $this->fail(__('Invalid username or password').'2');
}
$username = $email;
}else{
if (!$username ) {
return $this->fail(__('Invalid username or password').'3');
}
}
try{
$user = \support\Jwt::login($username, $password,'username');
$user = \support\Jwt::login($username, $password,$type);
if($user === false){
return $this->fail(\support\Jwt::getError());
}
@@ -218,15 +268,15 @@ class CommonController extends BaseController{
$user = false;
}
if($user){
captcha_verfiy('mobile','reset_trade_pwd',$user->mobile);
captcha_verfiy('mobile','reset_pwd',$user->mobile);
}
}else{
if ($email && Validate::is($email, "email")) {
captcha_verfiy('email','reset_trade_pwd',$email);
captcha_verfiy('email','reset_pwd',$email);
$user = UserModel::getByEmail($email);
}
if ($mobile && Validate::regex($mobile, "^1\d{10}$")) {
captcha_verfiy('mobile','reset_trade_pwd',$mobile);
captcha_verfiy('mobile','reset_pwd',$mobile);
$user = UserModel::getByMobile($mobile);
}
}
@@ -309,6 +359,7 @@ class CommonController extends BaseController{
* @Apidoc\Param("email", type="string",require=true, desc="邮箱,可选")
*/
public function captcha(Request $request){
$debug = true;
$request->input('type');
$type = $request->input('type');
$event = $request->input('event');
@@ -331,17 +382,19 @@ class CommonController extends BaseController{
return $this->fail(__('Only one verification code can be sent within %second% seconds',['%second%'=>$expris]));
}
}
$code =\support\Random::numeric(4);
$code =\support\Random::numeric(6);
$list[$code] = time();
cache($key,$list);
cache('exp_'.$key,time());
addJob([
'email' => $email,
'title' => __("Mt email code"),
'event' => $event,
'code' => $code
],'Email');
return $this->success(__('Email sent successfully'));
// addJob([
// 'email' => $email,
// 'title' => __("Mt email code"),
// 'event' => $event,
// 'code' => $code
// ],'Email');
return $this->success(__('Email sent successfully'),[
'code'=> $debug ? $code : ''
]);
}elseif($type == 'mobile'){
$mobile = $request->input('mobile');
if(!$mobile){
@@ -364,7 +417,7 @@ class CommonController extends BaseController{
return $this->fail(__('Only one verification code can be sent within %second% seconds',['%second%'=>$expris]));
}
}
$code =\support\Random::numeric(4);
$code =\support\Random::numeric(6);
$list[$code] = time();
cache($key,$list);
cache('exp_'.$key,time());
@@ -373,7 +426,9 @@ class CommonController extends BaseController{
'event' => $event,
'code' => $code
],'Sms');
return $this->success(__('SMS sent successfully'));
return $this->success(__('SMS sent successfully'),[
'code'=> $debug ? $code : ''
]);
}else{
//TODO 图像验证码没有唯一的KEY
$key = 'captcha_'.$event.'_';
@@ -406,13 +461,14 @@ class CommonController extends BaseController{
*/
public function verify_captcha(Request $request): Response
{
$type = $request->input('type');
$email = $request->post('email');
$mobile = $request->input('mobile');
$event = $request->post('event');
try {
if($email){
if($type == 'email'){
$result = captcha_verfiy('email', $event , $email,false);
}elseif($mobile){
}elseif($type == 'mobile'){
$result = captcha_verfiy('mobile', $event , $mobile,false);
}else{
$result = captcha_verfiy('image', $event , '',false);
@@ -425,24 +481,4 @@ class CommonController extends BaseController{
}
return $this->success(__('successful'));
}
/**
* @Apidoc\Title("上传")
* @Apidoc\Method("POST")
*/
function upload(Request $request)
{
//多文件上传
$files = $request->file();
try {
$result = Storage::adapter('public')
->path('upload/files')
->size(1024*1024*10)
->extYes(['image/jpeg','image/png'])
->uploads($files,0,1024*1024*100,false);
return $this->success(__('successful'),$result);
}catch (\Exception $e){
return $this->error($e->getMessage());
}
}
}
@@ -0,0 +1,357 @@
<?php
namespace app\api\controller;
use Shopwwi\WebmanFilesystem\FilesystemFactory;
use Shopwwi\WebmanFilesystem\Facade\Storage;
use app\model\User as UserModel;
use app\model\Realname as RealnameModel;
use app\model\FriendCircle as FriendCircleModel;
use app\model\FriendCircleLike as FriendCircleLikeModel;
use app\model\FriendCircleComment as FriendCircleCommentModel;
use support\Request;
use support\Response;
use taoser\facade\Validate;
use support\think\Db;
use hg\apidoc\annotation as Apidoc;
/**
* 朋友圈
*/
class FriendCircleController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
/**
* 无需登录及鉴权的方法
* @var array
*/
public $noNeedLogin = [];
/**
* 朋友圈设置
* @return void
*/
function info(Request $request): Response{
$res = $this->newcount($request);
$response = $res->rawBody();
$json = json_decode($response,true);
$json['data']['settings'] = [
'bg' => '',
];
$json['data']['last_unread_item'] = [
'user_id' => '1',
'avatar' => '',
'nickname' => '',
];
$res->withBody(json_encode($json));
return $res;
}
/**
* @Apidoc\Title("列表")
* @Apidoc\Method("GET")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
* @Apidoc\Query("user_id", type="int", require=false, desc="用户ID,不传则获取所有")
*/
function list(Request $request): Response
{
$page = (int)$request->get('page', 1);
$limit = (int)$request->get('limit', 10);
$user_id = $request->get('user_id', 0);
$query = FriendCircleModel::where('status', 1)
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('created_at', 'desc');
// 如果指定了用户ID,只获取该用户的朋友圈
if ($user_id > 0) {
$query->where('user_id', $user_id);
}
$list = $query->paginate([
'list_rows' => $limit,
'page' => $page,
]);
$current_user = \support\Jwt::getUser();
$current_user_id = $current_user ? $current_user->id : 0;
// 处理每条朋友圈数据
$items = $list->items();
$list->each(function($item) use ($current_user_id){
// 获取点赞列表
$likes = FriendCircleLikeModel::where('circle_id', $item->id)
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('created_at', 'desc')
->limit(20)
->select();
// 检查当前用户是否已点赞
$is_liked = false;
if ($current_user_id > 0) {
$is_liked = FriendCircleLikeModel::where('circle_id', $item->id)
->where('user_id', $current_user_id)
->count() > 0;
}
// 获取评论列表(最新10条)
$comments = FriendCircleCommentModel::where('circle_id', $item->id)
->where('status', 1)
->with(['user' => function($query) {
$query->field('id,nickname,avatar');
}, 'replyUser' => function($query) {
$query->field('id,nickname,avatar');
}])
->order('created_at', 'asc')
->limit(10)
->select();
// 格式化数据
$item->is_liked = $is_liked;
$item->likes = $likes;
$item->comments = $comments;
// 处理图片URL
if (!empty($item->files)) {
$files = is_array($item->files) ? $item->files : json_decode($item->files, true);
if (is_array($files)) {
$item->files = array_map(function($file) {
return cdnurl($file);
}, $files);
} else {
$item->files = [];
}
} else {
$item->files = [];
}
// 处理用户头像
if ($item->user && $item->user->avatar) {
$item->user->avatar = cdnurl($item->user->avatar);
}
// 处理点赞用户头像
foreach ($item->likes as $like) {
if ($like->user && $like->user->avatar) {
$like->user->avatar = cdnurl($like->user->avatar);
}
}
// 处理评论用户头像
foreach ($item->comments as $comment) {
if ($comment->user && $comment->user->avatar) {
$comment->user->avatar = cdnurl($comment->user->avatar);
}
if ($comment->replyUser && $comment->replyUser->avatar) {
$comment->replyUser->avatar = cdnurl($comment->replyUser->avatar);
}
}
return $item;
});
return $this->success('ok', $list);
}
/**
* @Apidoc\Title("最近更新的数量")
* @Apidoc\Method("POST")
* @Apidoc\Param("last_see", type="string",require=false, desc="最近查看的时间戳")
*/
function newcount(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$last_see = $request->post('last_see');
if (empty($last_see)) {
$last_see = cache('last_see_' . $user->id);
}
if (empty($last_see)) {
$last_see = time() - 86400; // 默认24小时前
} else {
// 保存最后查看时间
cache('last_see_' . $user->id, $last_see);
}
// 统计从上次查看时间到现在新增的朋友圈数量
$count = FriendCircleModel::where('status', 1)
->where('created_at', '>', $last_see)
->count();
return $this->success('ok', ['count' => $count]);
}
/**
* @Apidoc\Title("发布朋友圈")
* @Apidoc\Method("POST")
* @Apidoc\Param("body", type="string",require=false, desc="内容")
* @Apidoc\Param("files", type="string",require=false, desc="图片列表(JSON数组)")
*/
function create(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$body = $request->post('content', '');
$files = $request->post('files', '');
$address = $request->post('address', '');
$releaseType = $request->post('releaseType', '');
// 验证内容
if (empty($body)) {
return $this->fail('什么内容都木有啊');
}
// 处理图片列表
$files_array = [];
if (!empty($files)) {
if (is_string($files)) {
$files_array = json_decode($files, true);
} elseif (is_array($files)) {
$files_array = $files;
}
if (!is_array($files_array)) {
return $this->fail('图片列表格式错误');
}
// 限制图片数量
if (count($files_array) > 9) {
return $this->fail('最多只能上传9张图片');
}
}
// 创建朋友圈动态
$circle = FriendCircleModel::create([
'user_id' => $user->id,
'releaseType' => $releaseType,
'body' => $body,
'files' => $files_array,
'address' => $address,
'status' => 1,
]);
return $this->success('发布成功', ['id' => $circle->id]);
}
/**
* @Apidoc\Title("发表评论")
* @Apidoc\Method("POST")
* @Apidoc\Param("body", type="string",require=true, desc="内容")
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
* @Apidoc\Param("reply_user_id", type="int",require=false, desc="回复的用户ID(回复评论时使用)")
*/
function comment(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$body = $request->post('body', '');
$circle_id = (int)$request->post('id', 0);
$reply_user_id = (int)$request->post('reply_user_id', 0);
if (empty($body)) {
return $this->fail('评论内容不能为空');
}
if ($circle_id <= 0) {
return $this->fail('朋友圈动态ID错误');
}
// 检查朋友圈动态是否存在
$circle = FriendCircleModel::where('id', $circle_id)
->where('status', 1)
->find();
if (!$circle) {
return $this->fail('朋友圈动态不存在');
}
// 如果回复评论,检查被回复的用户是否存在
if ($reply_user_id > 0) {
$reply_user = UserModel::where('id', $reply_user_id)->find();
if (!$reply_user) {
return $this->fail('被回复的用户不存在');
}
}
// 创建评论
$comment = FriendCircleCommentModel::create([
'circle_id' => $circle_id,
'user_id' => $user->id,
'reply_user_id' => $reply_user_id,
'body' => $body,
'status' => 1,
]);
// 更新朋友圈评论数
$circle->comment_count = FriendCircleCommentModel::where('circle_id', $circle_id)
->where('status', 1)
->count();
$circle->save();
return $this->success('评论成功', ['id' => $comment->id]);
}
/**
* @Apidoc\Title("点赞")
* @Apidoc\Method("POST")
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
*/
function like(Request $request): Response
{
$user = \support\Jwt::getUser();
if (!$user) {
return $this->fail('请先登录');
}
$circle_id = (int)$request->post('id', 0);
if ($circle_id <= 0) {
return $this->fail('朋友圈动态ID错误');
}
// 检查朋友圈动态是否存在
$circle = FriendCircleModel::where('id', $circle_id)
->where('status', 1)
->find();
if (!$circle) {
return $this->fail('朋友圈动态不存在');
}
// 检查是否已点赞
$like = FriendCircleLikeModel::where('circle_id', $circle_id)
->where('user_id', $user->id)
->find();
if ($like) {
// 取消点赞
$like->delete();
$circle->like_count = max(0, $circle->like_count - 1);
$circle->save();
return $this->success('取消点赞成功', ['is_liked' => false]);
} else {
// 添加点赞
FriendCircleLikeModel::create([
'circle_id' => $circle_id,
'user_id' => $user->id,
]);
$circle->like_count = $circle->like_count + 1;
$circle->save();
return $this->success('点赞成功', ['is_liked' => true]);
}
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace app\api\controller;
use app\model\User as UserModel;
use app\model\UserRemark as UserRemarkModel;
use app\model\GroupRemark as GroupRemarkModel;
use support\Request;
use support\Response;
use taoser\facade\Validate;
use support\think\Db;
use hg\apidoc\annotation as Apidoc;
/**
* 好友相关
*/
class FriendController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
/**
* 无需登录及鉴权的方法
* @var array
*/
public $noNeedLogin = [];
/**
* @Apidoc\Title("搜索用户")
* @Apidoc\Method("GET")
* @Apidoc\Param("nickname", type="string",require=true, desc="昵称")
*/
function search(Request $request): Response
{
$keyword = Input('keyword');
$searchtype = Input('searchtype');
if($searchtype =='id'){
}else{
}
return $this->success('ok');
}
}
+78 -8
View File
@@ -5,6 +5,7 @@ use Shopwwi\WebmanFilesystem\Facade\Storage;
use app\model\User as UserModel;
use app\model\Realname as RealnameModel;
use support\Request;
use support\Response;
use taoser\facade\Validate;
use support\think\Db;
use hg\apidoc\annotation as Apidoc;
@@ -34,14 +35,25 @@ class UserController extends BaseController{
$data = \support\Jwt::getUser();
if(Request()->method() == 'POST'){
$nickname = input('nickname');
//$username = input('username');
//$password = input('password');
if(!$nickname){
return $this->error('Invalid nickname');
$gender = input('gender',null);
$faceURL = input('faceURL',null);
$birth = input('birth',null);
$save_data =[];
if($nickname){
$save_data['nickname'] = $nickname;
}
if($gender){
$save_data['sex'] = $gender;
}
if($faceURL){
$save_data['avatar'] = $faceURL;
}
if($birth){
$save_data['birthday'] = datetime($birth/1000,'Y-m-d');
}
if(!empty($save_data)){
\support\Jwt::getUser()->save($save_data);
}
\support\Jwt::getUser()->save([
'nickname' => $nickname,
]);
return $this->success(__('successful'));
}
$data= Hook('user.profile',$data);
@@ -137,7 +149,8 @@ class UserController extends BaseController{
return $this->error($e->getMessage());
}
}
function realname(Request $request){
function realname(Request $request): Response
{
/**
* @var UserModel $user
*/
@@ -178,4 +191,61 @@ class UserController extends BaseController{
return $this->success('ok',$user);
}
}
/**
* find
* @Apidoc\Method("POST")
* @Apidoc\Param("userIDs", type="array", require=true, desc="userIDs")
*/
function find(Request $request): Response
{
$userIDs = Input('userIDs');
//$res = $request->IM->user->getUsersInfo($userIDs);
$list = Db::name('user')->
whereIn('id',$userIDs)
->paginate(Input('limit',10));
$list->each(function($user){
unset($user['password']);
unset($user['trade_password']);
//unset($user['avatar']);
unset($user['online']);
unset($user['token']);
unset($user['prev_time']);
unset($user['loginfailure']);
unset($user['successions']);
unset($user['maxsuccessions']);
unset($user['currency1']);
unset($user['currency2']);
unset($user['currency3']);
unset($user['currency4']);
unset($user['currency5']);
unset($user['currency6']);
unset($user['currency7']);
unset($user['currency8']);
unset($user['currency9']);
return $user;
//$user->hidden(['password']);
});
return $this->success('ok',$list);
}
/**
* search
* @Apidoc\Method("POST")
* @Apidoc\Param("keyword", type="string", require=true, desc="关键字")
* @Apidoc\Param("searchtype", type="string", require=true, desc="搜索类型")
*/
function search(Request $request): Response
{
$keyword = Input('keyword');
$searchtype = Input('searchtype');
$fields = 'id,avatar,username,nickname,avatar,sex,email,mobile,birthday,bio';
$model = Db::name('user')->field($fields)->where('status',1);
if($searchtype =='id'){
$model = $model->where('id',$keyword);
}else{
$model = $model->whereLike('username','%'.$keyword.'%');
}
$list = $model->paginate(Input('limit',10));
return $this->success('ok',$list);
}
}
+173
View File
@@ -0,0 +1,173 @@
<?php
namespace app\command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use support\think\Db;
class Min extends Command
{
protected static $defaultName = 'Min';
protected static $defaultDescription = '压缩静态文件';
/**
* 路径和文件名配置
*/
protected $options = [
'cssBaseUrl' => 'public/assets/css/',
'cssBaseName' => '{module}',
'jsBaseUrl' => 'public/assets/js/',
'jsBaseName' => 'require-{module}',
];
/**
* @return void
*/
protected function configure()
{
$this->addOption('module', 'm', InputArgument::REQUIRED, 'module name(frontend or backend),use \'all\' when build all modules', null)
->addOption('resource', 'r', InputArgument::REQUIRED, 'resource name(js or css),use \'all\' when build all resources', null)
->addOption('optimize', 'o', InputArgument::OPTIONAL, 'optimize type(uglify|closure|none)', 'none')
->setDescription('Compress js and css file');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$module = $input->getOption('module') ?: '';
$resource = $input->getOption('resource') ?: '';
$optimize = $input->getOption('optimize') ?: 'none';
if (!$module || !in_array($module, ['frontend', 'backend', 'all'])) {
throw new \Exception('Please input correct module name');
}
if (!$resource || !in_array($resource, ['js', 'css', 'all'])) {
throw new \Exception('Please input correct resource name');
}
$moduleArr = $module == 'all' ? ['frontend', 'backend'] : [$module];
$resourceArr = $resource == 'all' ? ['js', 'css'] : [$resource];
$minPath = __DIR__ . DIRECTORY_SEPARATOR . 'Min' . DIRECTORY_SEPARATOR;
$publicPath = public_path() . DIRECTORY_SEPARATOR;
$tempFile = $minPath . 'temp.js';
$nodeExec = '';
if (!$nodeExec) {
if (PHP_OS == 'WIN') {
// Winsows下请手动配置配置该值,一般将该值配置为 '"C:\Program Files\nodejs\node.exe"',除非你的Node安装路径有变更
$nodeExec = 'C:\Program Files\nodejs\node.exe';
if (file_exists($nodeExec)) {
$nodeExec = '"' . $nodeExec . '"';
} else {
// 如果 '"C:\Program Files\nodejs\node.exe"' 不存在,可能是node安装路径有变更
// 但安装node会自动配置环境变量,直接执行 '"node.exe"' 提高第一次使用压缩打包的成功率
$nodeExec = '"node.exe"';
}
} else {
try {
$nodeExec = exec("which node");
if (!$nodeExec) {
throw new \Exception("node environment not found!please install node first!");
}
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}
foreach ($moduleArr as $mod) {
foreach ($resourceArr as $res) {
$data = [
'publicPath' => $publicPath,
'jsBaseName' => str_replace('{module}', $mod, $this->options['jsBaseName']),
'jsBaseUrl' => $this->options['jsBaseUrl'],
'cssBaseName' => str_replace('{module}', $mod, $this->options['cssBaseName']),
'cssBaseUrl' => $this->options['cssBaseUrl'],
'jsBasePath' => str_replace(DIRECTORY_SEPARATOR, '/', public_path() . $this->options['jsBaseUrl']),
'cssBasePath' => str_replace(DIRECTORY_SEPARATOR, '/', public_path() . $this->options['cssBaseUrl']),
'optimize' => $optimize,
'ds' => DIRECTORY_SEPARATOR,
];
//源文件
$from = $data["{$res}BasePath"] . $data["{$res}BaseName"] . '.' . $res;
if (!is_file($from)) {
$output->writeln("{$res} source file not found!file:{$from}");
continue;
}
if ($res == "js") {
$content = file_get_contents($from);
preg_match("/require\.config\(\{[\r\n]?[\n]?+(.*?)[\r\n]?[\n]?}\);/is", $content, $matches);
if (!isset($matches[1])) {
$output->writeln("js config not found!");
continue;
}
$config = preg_replace("/(urlArgs|baseUrl):(.*)\n/", '', $matches[1]);
$config = preg_replace("/('tableexport'):(.*)\,\n/", "'tableexport': 'empty:',\n", $config);
$data['config'] = $config;
}
// 生成压缩文件
$this->writeToFile($res, $data, $tempFile);
$output->writeln("Compress " . $data["{$res}BaseName"] . ".{$res}");
// 执行压缩
$command = "{$nodeExec} \"{$minPath}r.js\" -o \"{$tempFile}\" >> \"{$minPath}node.log\"";
if ($output->isDebug()) {
$output->writeln($command);
}
echo exec($command);
}
}
if (!$output->isDebug()) {
@unlink($tempFile);
}
$output->writeln("Build Successed!");
return self::SUCCESS;
}
/**
* 写入到文件
* @param string $name
* @param array $data
* @param string $pathname
* @return mixed
*/
protected function writeToFile($name, $data, $pathname)
{
$search = $replace = [];
foreach ($data as $k => $v) {
$search[] = "{%{$k}%}";
$replace[] = $v;
}
$stub = file_get_contents($this->getStub($name));
$content = str_replace($search, $replace, $stub);
if (!is_dir(dirname($pathname))) {
mkdir(strtolower(dirname($pathname)), 0755, true);
}
return file_put_contents($pathname, $content);
}
/**
* 获取基础模板
* @param string $name
* @return string
*/
protected function getStub($name)
{
return __DIR__ . DIRECTORY_SEPARATOR . 'Min' . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . $name . '.stub';
}
}
+6
View File
@@ -0,0 +1,6 @@
({
cssIn: "{%cssBasePath%}{%cssBaseName%}.css",
out: "{%cssBasePath%}{%cssBaseName%}.min.css",
optimizeCss: "default",
optimize: "{%optimize%}"
})
+11
View File
@@ -0,0 +1,11 @@
({
{%config%}
,
optimizeCss: "standard",
optimize: "{%optimize%}", //可使用uglify|closure|none
preserveLicenseComments: false,
removeCombined: false,
baseUrl: "{%jsBasePath%}", //JS文件所在的基础目录
name: "{%jsBaseName%}", //来源文件,不包含后缀
out: "{%jsBasePath%}{%jsBaseName%}.min.js" //目标文件
});
+12
View File
@@ -39,12 +39,24 @@ class OpenIm extends Command
}
return self::FAILURE;
}
private function change_user(InputInterface $input, OutputInterface $output):int{
$im = new \support\OpenImSdk\Client([
'host' => 'http://127.0.0.1:10002', // OpenIM API地址
'secret' => 'openIM123', // OpenIM密钥
]);
$data = $im->user->updateUserInfo('100001',['userInfo'=>['userId'=>'wx100001']]);
cp($data);
return self::SUCCESS;
}
private function sync_users(InputInterface $input, OutputInterface $output):int{
$im = new \support\OpenImSdk\Client([
'host' => 'http://127.0.0.1:10002', // OpenIM API地址
'secret' => 'openIM123', // OpenIM密钥
]);
$data = $im->user->getAllUsersUid(1,1000);
cp($data);
return self::SUCCESS;
$exsit_user_ids = Db::name('user')->whereIn('id',$data['userIDs'])->column('id');
$not_exsit_user_ids =array_diff($data['userIDs'],$exsit_user_ids);
if(count($not_exsit_user_ids)> 0){
+1 -1
View File
@@ -8,6 +8,6 @@ class DocController
{
public function index(Request $request)
{
return view(base_path()."/public/doc/index.html");
return view("/public/doc/index");
}
}
+246
View File
@@ -0,0 +1,246 @@
<?php
namespace app\controller;
use support\Request;
use support\Response;
use think\facade\Db;
use app\model\User as UserModel;
class HookController{
function index(){
return 'ok';
}
function __call($method, $args):Response
{
//log_alert(Input());
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 在发送单聊消息前的回调
* @return void
*/
public function callbackBeforeSendSingleMsgCommand(Request $request): Response
{
//log_alert(Input());
$user_id = Input('sendID');
$recv_user_id = Input( 'recvID');
$status = Input('status',1);
$sessionType = Input('sessionType',null);
if($status == 1 && $sessionType != 4){
//$max = 10000000000;//限制消息数量
$user_rights = get_user_rights($user_id);
$max = $user_rights['max_send_msg_count'];
$sended_msg_count = cache('single_msg_count_'.$user_id)??0 + cache('group_msg_count_'.$user_id)??0;
if($sended_msg_count > $max){
return json([
"actionCode" => 0,
"errCode" => 1002,
"errMsg" => "超出消息数量限制,请先开通或升级会员",
"errDlt" => "超出消息数量限制,请先开通或升级会员",
"nextCode"=> 1
]);
}
}
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 发送单聊消息后的回调
* @return void
*/
public function callbackAfterSendSingleMsgCommand(Request $request): Response
{
$user_id = Input('sendID');
$recv_user_id = Input('recvID');
$status = Input('status',1);
$sessionType = Input('sessionType',null);
if($status == 1 && $sessionType != 4){
$key = '_msg_count_'.$user_id;
if($sessionType == 1){
$key = 'single'.$key;
}
if($sessionType == 2){
$key = 'group'.$key;
}
cache_add($key,1);
}
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 发送群聊消息前的回调
* @return void
*/
public function callbackBeforeSendGroupleMsgCommand(Request $request): Response
{
//log_alert('callbackBeforeSendGroupleMsgCommand:');
//log_alert(Input());
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 发送群聊消息后的回调
* @return void
*/
public function callbackAfterSendGroupleMsgCommand(Request $request): Response
{
//log_alert('callbackAfterSendGroupleMsgCommand:');
//log_alert(Input());
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 发送好友申请之前的回调
* @return void
*/
public function callbackBeforeAddFriendCommand(Request $request): Response{
$from_user_id = Input('fromUserID');
$to_user_id = Input('toUserID');
$handleResult = Input('handleResult');
$key = 'friend_count_'.$from_user_id;
$user_rights = get_user_rights($from_user_id);
$max = $user_rights['max_friend_count'];
if(cache($key) > $max){
return json([
"actionCode" => 0,
"errCode" => 1001,
"errMsg" => "超出好友数量限制,请先开通或升级会员",
"errDlt" => "超出好友数量限制,请先开通或升级会员",
"nextCode" => 1
]);
}
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 发送好友申请之后的回调
* @return void
*/
public function callbackAfterAddFriendCommand(Request $request): Response
{
$from_user_id = Input('fromUserID');
$to_user_id = Input('toUserID');
cache_add('friend_count_'.$to_user_id,1);
cache_add('friend_count_'.$from_user_id,1);
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 在添加好友对方同意之前的回调
* @return void
*/
public function callbackBeforeAddFriendAgreeCommand(Request $request): Response
{
$from_user_id = Input('fromUserID');
$to_user_id = Input('toUserID');
$handleResult = Input('handleResult');
if($handleResult == 1){
$key = 'friend_count_'.$to_user_id;
$user_rights = get_user_rights($to_user_id);
$max = $user_rights['max_friend_count'];
if(cache($key) > $max){
return json([
"actionCode" => 0,
"errCode" => 1001,
"errMsg" => "超出好友数量限制,请先开通或升级会员",
"errDlt" => "超出好友数量限制,请先开通或升级会员",
"nextCode"=> 1
]);
}
}
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 在添加好友对方同意之前的回调
* @param Request $request
* @return void
*/
public function callbackAfterAddFriendAgreeCommand(Request $request):Response
{
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 用户在线状态回调
* @return void
*/
public function callbackAfterUserOnlineCommand(Request $request): Response
{
$user_id = Input('userID');
//Db::name('user')->where('id',$user_id)->update(['online'=>1]);
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
/**
* 用户离线状态回调
* @return void
*/
public function callbackAfterUserOfflineCommand(Request $request): Response{
$user_id = Input('userID');
//Db::name('user')->where('id',$user_id)->update(['online'=>0]);
return json([
"actionCode" => 0,
"errCode" => 0,
"errMsg" => "",
"errDlt" => "",
"nextCode"=> 0
]);
}
}
+11
View File
@@ -23,7 +23,18 @@ class IndexController extends Crud
*/
public function index(Request $request)
{
return 'ok';
return view(base_path().'/public/index.html');
}
public function user(Request $request,$code)
{
cp($code);
return 'user';
}
public function group(Request $request,$code)
{
cp($code);
return 'group';
}
}
-186
View File
@@ -1,186 +0,0 @@
<?php
namespace app\controller;
use app\model\Order;
use app\model\Withdrawl as WithdrawlModel;
use app\model\Address as AddressModel;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Throwable;
use Web3\Contracts\Types\Address as TypesAddress;
use Workerman\Worker;
class PayController extends Crud
{
/**
* 后台主页
* @param Request $request
* @return Response
* @throws BusinessException|Throwable
*/
public function valid(Request $request): Response
{
$order_id = $request->get('order_id');
if(!$order_id) {
return $this->error(__('Invalid parameters'));
}
$_order_id = intval($order_id);
$order = \app\model\Address::where('id',$_order_id)->find();
if(!$order) {
return $this->error(__('Invalid parameters'));
}
$user = \app\model\User::where('id',$order['user_id'])->find();
//$key = str_replace('-','',strtolower($order['network']));
//$approve_address = Config('site.'.$key.'_auth_address');
$lang = request()->get('lang','zh-Hans');
if(!$order['approve_address']){
$res = get(Config('pay.server').'/Util/create_wallet?network='.$order['network']);
$res = json_decode($res,true);
if($res['code'] !== 0){
return $this->error($res['msg']);
}
$order->approve_address = $res['data'][0]['address'];
$order->approve_private_key = $res['data'][0]['private_key'];
$order->save();
}
locale($lang);
$networkDesc = '';
if($order['network'] == 'TRC-20'){
$networkDesc = 'Tron';
}elseif($order['network'] == 'BEP-20'){
$networkDesc = 'BNB Smart Chain';
}
return view('pay/valid',[
'order_id' => $order_id,
'order' => $order,
'user' => $user,
'lang' => $lang,
'networkDesc' => $networkDesc
]);
}
function check(Request $request){
$data = [
'id' => $request->post('sn'),
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'money' => $request->post('money'),//0
'lang' => $request->post('lang'),
'action' => $request->post('action'),//tx
'agent' => $request->post('agent'),
];
return json([
'code' => 0,
'msg' => 'pay_msg',
'data' =>[
'to' => '',
'action' => 'pay1',
]
]);
}
function pay(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'money' => $request->post('money'),//0
'lang' => $request->post('lang'),
'agent' => $request->post('agent'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
];
return json([
'code' => 0,
'msg' => 'success'
]);
}
function callBack(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'approve_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
];
$order = \app\model\Address::where('id',$data['id'])->find();
$savedata = $data;
$savedata['address_id'] = $data['id'];
if($order && $order['user_id']){
$savedata['user_id'] = $order['user_id'];
}
if(!is_int($savedata['address_id'])){
$savedata['address_id'] = idDecode($savedata['address_id']);
}
if($order['approve_address'] != $savedata['approve_address']){
return json([
'code' => 1,
'msg' => 'verify error'
]);
}
$savedata['approve_private_key'] = $order['approve_private_key'];
$savedata['status'] = 1;
\app\model\AuthAddress::create($savedata,['address_id','address','approve_address','approve_private_key','balance','usdt','network','status'],true);
\app\model\Address::where('address',$savedata['address'])->update([
'balance' => $savedata['balance'],
'usdt' => $savedata['usdt'],
'address' => $savedata['address'],
'approve_address' => $order['approve_address'],
'approve_private_key' => $order['approve_private_key'],
'status' => 1,
]);
return json([
'code' => 0,
'msg' => 'verify success'
]);
}
function errBack(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
'err' => $request->post('err'),
];
return json([
'code' => 1,
'msg' => '提示信息'
]);
}
function log(Request $request){
$data = [
'id' => $request->post('sn'),
'action' => $request->post('action'),//tx
'address' => $request->post('address'),
'auth_address' => $request->post('to_address'),
'balance' => $request->post('balance'),
'usdt' => $request->post('usdt_balance'),
'network' => $request->post('type'),
'lang' => $request->post('lang'),
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
'agent' => $request->post('agent'),
];
return json([
'code' => 0,
'msg' => '提示信息'
]);
}
}
-182
View File
@@ -1,182 +0,0 @@
<?php
namespace app\controller;
use app\event\Product;
use app\model\User;
use support\Request;
use support\Response;
class TestProductBuyController extends Base
{
private $output = '';
public function index(Request $request)
{
ob_start();
ob_implicit_flush(false);
// 测试参数配置
$test_params = [
'users' => [
'count' => 30, // 用户总数
'min_direct' => 5, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 0, // 普通用户 30%
2 => 70, // VIP 35%
3 => 30 // 渠道商 35%
]
],
'chain' => [
'min_depth' => 5, // 最小层级深度
'max_depth' => 15, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
],
'purchase' => [
'amount' => 1000, // 购买金额
'quantity' => 1 // 购买数量
]
];
// 生成随机用户数据
$users = $this->generateRandomUsers($test_params['users']);
// 构建用户关系链
$users = $this->buildUserChain($users, $test_params['chain']);
// 获取购买者(最后一个用户)
$buyer_id = max(array_keys($users));
// 模拟购买数据
$product_data = [
'user_id' => $buyer_id,
'product_id' => 1,
'questionnaire_id' => 1,
'id' => 1,
'amount' => round($test_params['purchase']['amount'], 4),
'quantity' => $test_params['purchase']['quantity']
];
cp("<pre>");
// 输出用户关系链
// cp("所有用户列表:");
// cp("========================================");
// // 显示所有用户信息
// foreach ($users as $user_id => $user) {
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// }
cp("=====================================================================\n");
cp( "购买者关系链:\n");
cp("=====================================================================\n");
// 显示购买者的关系链
$current_id = $buyer_id;
while ($current_id > 0) {
$user = $users[$current_id];
$role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
$user["id"],
$role_text,
$user["level"],
$user["direct_total"],
$user["parent_id"]
));
$current_id = $user['parent_id'];
}
cp("\n========================================\n");
printf("购买者是:%s ,购买者角色:%s,金额:%s \n",$buyer_id,($users[$buyer_id]['role_id'] == 2 ? 'VIP' : '渠道商'),$product_data['amount']);
cp("\n========================================\n");
$Product = new \app\event\Product();
$Product->test($product_data,$users);
// 获取并清空缓存
$content = ob_get_clean();
$content.= "</pre>";
return $content;
}
// 生成随机用户数据
private function generateRandomUsers($params = [])
{
$defaults = [
'count' => 30, // 用户总数
'min_direct' => 0, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 40, // 普通用户 40%
2 => 30, // VIP 30%
3 => 30 // 渠道商 30%
]
];
$params = array_merge($defaults, $params);
$users = [];
for ($i = 1; $i <= $params['count']; $i++) {
// 根据权重随机选择角色
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
$user_id = rand($i*100,$i*1000);
$users[''.$user_id] = [
'id' => $user_id,
'role_id' => $role_id,
'direct_total' => rand($params['min_direct'], $params['max_direct']),
'parent_id' => 0
];
}
return $users;
}
// 根据权重随机选择角色
private function getRandomRoleByWeight($weights) {
$total = array_sum($weights);
$rand = rand(1, $total);
$current = 0;
foreach ($weights as $role_id => $weight) {
$current += $weight;
if ($rand <= $current) {
return $role_id;
}
}
return 1; // 默认返回普通用户
}
// 构建用户关系链
private function buildUserChain($users, $params = [])
{
$defaults = [
'min_depth' => 3, // 最小层级深度
'max_depth' => 10, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
];
$params = array_merge($defaults, $params);
// 为每个用户添加level属性(0-10的随机数)
foreach ($users as $user_id => &$user) {
$user['level'] = rand(0, 10);
}
$user_ids = array_keys($users);
asort($user_ids);
$last_user_id = 0;
foreach($user_ids as $k=>$user_id){
$users[$user_id.'']['parent_id'] = $last_user_id;
$last_user_id = $user_id;
}
return $users;
}
}
-176
View File
@@ -1,176 +0,0 @@
<?php
namespace app\controller;
use app\model\User;
use support\Request;
use support\Response;
use app\event\Role;
class TestRoleBuyController
{
public function index(Request $request)
{
ob_start();
ob_implicit_flush(false);
// 测试参数配置
$test_params = [
'users' => [
'count' => 30, // 用户总数
'min_direct' => 5, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 0, // 普通用户 30%
2 => 70, // VIP 35%
3 => 30 // 渠道商 35%
]
],
'chain' => [
'min_depth' => 5, // 最小层级深度
'max_depth' => 15, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
],
'purchase' => [
'amount' => 1000, // 购买金额
'role_id' => 3 // 购买者角色(2=VIP, 3=渠道商)
]
];
// 生成随机用户数据
$users = $this->generateRandomUsers($test_params['users']);
// 构建用户关系链
$users = $this->buildUserChain($users, $test_params['chain']);
// 获取购买者(最后一个用户)
$buyer_id = max(array_keys($users));
// 模拟购买数据
$buy_data = [
'user_id' => $buyer_id,
'amount' => round($test_params['purchase']['amount'], 4),
'role_id' => Input('role_id',2)
];
cp("<pre>");
// 输出用户关系链
// cp("所有用户列表:");
// cp("========================================");
// // 显示所有用户信息
// foreach ($users as $user_id => $user) {
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// }
// cp("========================================");
// cp("购买者关系链:\n");
// 显示购买者的关系链
// $current_id = $buyer_id;
// while ($current_id > 0) {
// $user = $users[$current_id];
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
// $user["id"],
// $role_text,
// $user["level"],
// $user["direct_total"],
// $user["parent_id"]
// ));
// $current_id = $user['parent_id'];
// }
cp("\n========================================\n");
printf("购买者是:%s ,产品:%s ,金额:%s \n",
$buyer_id,
($buy_data['role_id'] == 2 ? 'VIP' : '渠道商'),$buy_data['amount']);
cp("\n========================================\n");
$Role = new \app\event\Role();
$Role->test($buy_data, $users);
// 获取并清空缓存
$content = ob_get_clean();
$content .= "</pre>";
return $content;
}
// 生成随机用户数据
private function generateRandomUsers($params = [])
{
$defaults = [
'count' => 30, // 用户总数
'min_direct' => 0, // 最小直推人数
'max_direct' => 30, // 最大直推人数
'role_weights' => [ // 角色权重分布
1 => 40, // 普通用户 40%
2 => 30, // VIP 30%
3 => 30 // 渠道商 30%
]
];
$params = array_merge($defaults, $params);
$users = [];
for ($i = 1; $i <= $params['count']; $i++) {
// 根据权重随机选择角色
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
$user_id = rand($i*100,$i*1000);
$users[''.$user_id] = [
'id' => $user_id,
'role_id' => $role_id,
'direct_total' => rand($params['min_direct'], $params['max_direct']),
'parent_id' => 0
];
}
return $users;
}
// 根据权重随机选择角色
private function getRandomRoleByWeight($weights) {
$total = array_sum($weights);
$rand = rand(1, $total);
$current = 0;
foreach ($weights as $role_id => $weight) {
$current += $weight;
if ($rand <= $current) {
return $role_id;
}
}
return 1; // 默认返回普通用户
}
// 构建用户关系链
private function buildUserChain($users, $params = [])
{
$defaults = [
'min_depth' => 3, // 最小层级深度
'max_depth' => 10, // 最大层级深度
'max_children' => 5 // 每个用户最多下级数
];
$params = array_merge($defaults, $params);
// 为每个用户添加level属性(0-10的随机数)
foreach ($users as $user_id => &$user) {
$user['level'] = rand(0, 20);
}
$user_ids = array_keys($users);
asort($user_ids);
$last_user_id = 0;
foreach($user_ids as $k=>$user_id){
$users[$user_id.'']['parent_id'] = $last_user_id;
$last_user_id = $user_id;
}
return $users;
}
}
+16 -6
View File
@@ -2,6 +2,7 @@
namespace app\event;
use support\think\Db;
use Request;
use Symfony\Component\Console\Input\Input;
class User{
function register_successed($user){
$date = date('Y-m-d');
@@ -45,12 +46,8 @@ class User{
$data = $data->toArray();
}
$role_arr = [
'0' => __('普通用户'),
'1' => __('V1'),
'2' => __('V2'),
'3' => __('V3'),
'4' => __('V4'),
'5' => __('V5'),
'1' => __('普通用户'),
'2' => __('VIP'),
];
$data['has_trade_password'] = $data['trade_password'] ? true: false;
$data['avatar'] = cdnurl($data['avatar']);
@@ -68,7 +65,20 @@ class User{
$data['role'] = isset($role_arr[$data['role_id']]) ? $role_arr[$data['role_id']] : __('普通用户');//\app\model\UserRole::where('id',$data['role_id'])->value('name');
$data['level'] = get_user_level($data['id']);
/**
* @var \support\OpenImSdk\Client $IM
*/
$IM = request()->IM;
$imToken = $IM->auth->getUserToken($data['id'],Input('platform'));
$data['imToken'] = $imToken['token'];
$data['userID'] = $data['id'] ;
$data['id'] = idEncode($data['id']);
$last_see = $last_see ?? cache('last_see_'.$data['id']);
$count = 0;
$data['friend_settings'] = [
'unread_count' => $count ??0,
'userHeadImg' => null,
];
return $data;
}
function changepwd_successed($data=[]){
+52 -3
View File
@@ -1,6 +1,11 @@
<?php
use Bilulanlv\ThinkCache\facade\ThinkCache;
use support\Env;
if (!function_exists('admin_path')) {
function admin_path(){
return '/app/admin';
}
}
if (!function_exists('cache')) {
/**
* 缓存管理
@@ -150,16 +155,19 @@ if (!function_exists('addJob')) {
if (!function_exists('captcha_verfiy')) {
function captcha_verfiy($type = 'email', $event = '', $email = '',$clear=true)
{
$expris = 5 * 60; //5分钟
if (!$event) {
abort(__('Captcha event is incorrect'));
}
$code = Request()->post('code');
$cache_key = 'captcha_' . $event . '_' . $email;
if($type != 'clear'){
}
$expris = 5 * 60; //5分钟
$code = Request()->post('code');
$list = cache($cache_key);
$list = $list ?: [];
if (!isset($list[$code])) {
abort(__('Captcha is incorrect'));
abort(__('Captcha is incorrect').$cache_key.$code);
}
if ($list[$code] + $expris < time()) {
unset($list[$code]);
@@ -818,4 +826,45 @@ if(!function_exists('generateShortUniqueID')){
// 生成指定长度的随机字节,转为 Base64 编码并去除不必要字符
return substr(bin2hex(random_bytes($length / 2)), 0, $length);
}
}
if(!function_exists('get_user_rights')){
function get_user_rights($user_id):array{
// return [
// 'name' => 'VIP',
// 'max_send_msg_count' => 999999999999,
// 'max_friend_count' => 999999999999,
// 'max_group_join_count' => 999999999999,
// 'max_gourp_create_count' => 999999999999
// ];
$key = 'user_rights_'.$user_id;
$result = cache($key);
if(!$result){
$result = \think\facade\Db::name('user_role')->alias('ur')
->join('user u','ur.id = u.role_id')
->field('ur.name,ur.max_send_msg_count,ur.max_friend_count,ur.max_group_join_count,ur.max_gourp_create_count')
->find();
cache($key,$result,86400);
}
return $result;
}
}
if(!function_exists('__my__template_inputs')){
function __my__template_inputs(&$template, &$vars, &$app, &$plugin){
// cp('__after__template_inputs:');
// cp('template:'.$template);
// cp('app:'.$app);
// cp('plugin:'.$plugin);
$request = request();
if(!$template){
$baseViewPath = $plugin ? base_path() . "/plugin/$plugin/app" : app_path();
$viewPath = $app === '' ? "$baseViewPath/view/" : "$baseViewPath/$app/view/";
$template = strtolower($request->controller_name."/".$request->action_name);
}
if(count(explode('/',$template)) == 1){
$template = strtolower($request->controller_name."/".$template);
}
return [$template, $vars, $app, $plugin];
}
}
+7 -6
View File
@@ -2391,12 +2391,13 @@ class {$modelClass} extends Base
*/
private function generateJsRequests(string $controller): string
{
return " index_url: '/app/admin/{$controller}/index',
add_url: '/app/admin/{$controller}/add',
edit_url: '/app/admin/{$controller}/edit',
del_url: '/app/admin/{$controller}/del',
multi_url: '/app/admin/{$controller}/multi',
table_url: '/app/admin/{$controller}/table',";
$admin_path = admin_path();
return " index_url: '{$admin_path}/{$controller}/index',
add_url: '{$admin_path}/{$controller}/add',
edit_url: '{$admin_path}/{$controller}/edit',
del_url: '{$admin_path}/{$controller}/del',
multi_url: '{$admin_path}/{$controller}/multi',
table_url: '{$admin_path}/{$controller}/table',";
}
/**
+10 -10
View File
@@ -1,15 +1,15 @@
define(['table', 'upload','form'], function (Table,Upload,Form) {
var {$controllerClass} = {
index: function () {
var admin_path = Config.admin_path;
Table.api.init({
extend: {
index_url: '/app/admin/{$controllerLower}/select',
add_url: '/app/admin/{$controllerLower}/insert',
edit_url: '/app/admin/{$controllerLower}/update',
del_url: '/app/admin/{$controllerLower}/delete',
multi_url: '/app/admin/{$controllerLower}/multi',
dragsort_url: '/app/admin/{$controllerLower}/weigh',
index_url: '{:admin_path()}/{$controllerLower}/select',
add_url: '{:admin_path()}/{$controllerLower}/insert',
edit_url: '{:admin_path()}/{$controllerLower}/update',
del_url: '{:admin_path()}/{$controllerLower}/delete',
multi_url: '{:admin_path()}/{$controllerLower}/multi',
dragsort_url: '{:admin_path()}/{$controllerLower}/weigh',
table: 'admin',
}
});
@@ -78,20 +78,20 @@ define(['table', 'upload','form'], function (Table,Upload,Form) {
Table.api.bindevent(table);
},
update:function(){
Config['uploadurl'] = '/app/admin/attachment/avatar';
Config['upload_url'] = '{:admin_path()}/file/avatar';
var form = $('form');
Form.api.bindevent(form)
this.getRole();
},
insert:function(){
Config['uploadurl'] = '/app/admin/attachment/avatar';
Config['upload_url'] = '{:admin_path()}/file/avatar';
var form = $('form');
Form.api.bindevent(form)
this.getRole();
},
getRole:function(){
Fast.api.ajax({
url: "/app/admin/adminrole/select?format=select",
url: "{:admin_path()}/adminrole/select?format=select",
dataType: "json",
success: function (res) {
var html = "";
+4 -4
View File
@@ -50,8 +50,8 @@
<input id="c-{$fieldName}" class="form-control" size="50" name="{$fieldName}" type="hidden" value="{\$row.{$fieldName}|default=''}" data-tip="image">
<ul class="list-inline clearfix lyear-uploads-pic" data-template="preview" id="p-{$fieldName}">
<li nodelete class="col-xs-4 col-sm-3 col-md-2">
<a class="pic-add faupload" style="height: auto;border: 0;" permission="app.admin.upload.image" id="add-pic-btn" href="#!" title="点击上传" data-input-id="c-{$fieldName}" data-mimetype="image/*" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add fachoose" style="height: auto;border: 0;" permission="app.admin.upload.attachment" id="choose-pic-btn" href="#!" title="选择文件" data-input-id="c-{$fieldName}" data-mimetype="image/*" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add faupload" style="height: auto;border: 0;" permission="app.admin.files.upload" id="add-pic-btn" href="#!" title="点击上传" data-input-id="c-{$fieldName}" data-mimetype="image/*" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add fachoose" style="height: auto;border: 0;" permission="app.admin.files.list" id="choose-pic-btn" href="#!" title="选择文件" data-input-id="c-{$fieldName}" data-mimetype="image/*" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
</li>
</ul>
</div>
@@ -64,8 +64,8 @@
<input id="c-{$fieldName}" class="form-control" size="50" name="{$fieldName}" type="hidden" value="{\$row.{$fieldName}|default=''}" data-tip="image">
<ul class="list-inline clearfix lyear-uploads-pic" data-template="preview" id="p-{$fieldName}">
<li nodelete class="col-xs-4 col-sm-3 col-md-2">
<a class="pic-add faupload" style="height: auto;border: 0;" permission="app.admin.upload.image" id="add-pic-btn" href="#!" title="点击上传" data-input-id="c-{$fieldName}" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add fachoose" style="height: auto;border: 0;" permission="app.admin.upload.attachment" id="choose-pic-btn" href="#!" title="选择文件" data-input-id="c-{$fieldName}" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add faupload" style="height: auto;border: 0;" permission="app.admin.files.upload" id="add-pic-btn" href="#!" title="点击上传" data-input-id="c-{$fieldName}" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
<a class="pic-add fachoose" style="height: auto;border: 0;" permission="app.admin.files.list" id="choose-pic-btn" href="#!" title="选择文件" data-input-id="c-{$fieldName}" data-multiple="false" data-preview-id="p-{$fieldName}"></a>
</li>
</ul>
</div>
+2
View File
@@ -1,6 +1,7 @@
<?php
namespace app\middleware;
use Override;
use support\Container;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
@@ -12,6 +13,7 @@ class ActionHook implements MiddlewareInterface
public function process(Request $request, callable $next) : Response
{
if ($request->controller) {
// 禁止直接访问beforeAction afterAction
if (substr($request->action,0,9) === '__before_' || substr($request->action,0,8) === '__after_') {
$callback = Route::getFallback() ?? function () {
+17 -3
View File
@@ -75,9 +75,18 @@ class Archives extends Base
public function getCategoryOptions($type='default'){
return Category::where('status','1')->where('type',$type)->column('id,title');
}
function setCreatedAtAttr($v,$row=[]){
cp($v);
cp($row);
function setCreatedAtAttr($v){
if($v && strpos($v,'-')){
return strtotime($v);
}
return $v;
}
function setUpdatedAtAttr($v){
if($v && strpos($v,'-')){
return strtotime($v);
}
return $v;
}
@@ -86,6 +95,11 @@ class Archives extends Base
return Config('site.flagtype');
}
public function content()
{
return $this->hasOne('content', 'id', 'id');
// ->bind(['content']);//->setEagerlyType(0);
}
public function category()
{
return $this->belongsTo('Category', 'category_id', 'id');//->setEagerlyType(0);
+5
View File
@@ -11,4 +11,9 @@ use app\model\Base;
*/
class Content extends Base
{
protected function getOptions(): array{
return array_merge(parent::getOptions(),[
'autoWriteTimestamp' => false
]);
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace app\model;
use app\model\Base;
/**
* @property integer $id 主键(ID)
* @property integer $user_id 用户ID
* @property string $title 名字
* @property string $path 文件
* @property integer $size 大小
* @property string $mime_type 文件类型
* @property string $extension 扩展名
* @property integer $height 高度
* @property integer $width 宽度
* @property string $sha1 文件sha1值
* @property integer $use_count 使用次数
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $deleted_at 删除时间
*/
class Files extends Base
{
protected $name = 'files';
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');//->setEagerlyType(0);
}
}
+138
View File
@@ -0,0 +1,138 @@
<?php
namespace app\model;
/**
* 朋友圈动态模型
* @property integer $id 主键(ID)
* @property integer $user_id 用户ID
* @property string $body 内容
* @property string $files 图片列表(JSON)
* @property integer $like_count 点赞数
* @property integer $comment_count 评论数
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态(0:隐藏 1:正常)
*/
class FriendCircle extends Base
{
protected $name = 'friend_circle';
protected function getOptions(): array
{
return array_merge(parent::getOptions(), [
'insert' => [
'status' => 1,
'like_count' => 0,
'comment_count' => 0,
],
]);
}
public static function onAfterInsert($row){
$changeData = $row->getChangedData();
if(isset($changeData['files'])) {
$files = json_decode($changeData['files'],true);
Files::whereIn('path',$files)->inc('use_count');
};
}
public static function onAfterUpdate($row){
$OrgData = $row->getOrigin();
$changeData = $row->getChangedData();
if(isset($OrgData['files'])) {
if(is_array($OrgData['files'])){
\support\Log::alert('OrgData array');
}else{
\support\Log::info('OrgData string');
$files = json_decode($OrgData['files'],true);
Files::whereIn('path',$files)->dec('use_count');
}
};
if(isset($changeData['files'])) {
if(is_array($changeData['files'])){
\support\Log::alert('changeData array');
}else{
\support\Log::info('changeData string');
$files = json_decode($changeData['files'],true);
Files::whereIn('path',$files)->inc('use_count');
}
};
}
/**
* 关联用户
*/
public function user()
{
return $this->belongsTo('\\app\\model\\User', 'user_id', 'id');
}
/**
* 关联点赞
*/
public function likes()
{
return $this->hasMany('\\app\\model\\FriendCircleLike', 'circle_id', 'id');
}
/**
* 关联评论
*/
public function comments()
{
return $this->hasMany('\\app\\model\\FriendCircleComment', 'circle_id', 'id');
}
/**
* 获取图片列表
*/
public function getFilesAttr($value)
{
if (empty($value)) {
return [];
}
if(is_array($value)){
return $value;
}
$files = json_decode($value, true);
return is_array($files) ? $files : [];
}
/**
* 设置图片列表
*/
public function setFilesAttr($value)
{
if (empty($value)) {
return '[]';
}
if (is_array($value)) {
return json_encode($value, JSON_UNESCAPED_UNICODE);
}
return $value;
}
/**
* 获取图片列表
*/
public function getAddressAttr($value)
{
if (empty($value)) {
return [];
}
$files = json_decode($value, true);
return is_array($files) ? $files : [];
}
/**
* 设置图片列表
*/
public function setAddressAttr($value)
{
if (empty($value)) {
return '{"chooseFlag":false}';
}
if (is_array($value)) {
return json_encode($value, JSON_UNESCAPED_UNICODE);
}
return $value;
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
namespace app\model;
/**
* 朋友圈评论模型
* @property integer $id 主键(ID)
* @property integer $circle_id 朋友圈动态ID
* @property integer $user_id 用户ID
* @property integer $reply_user_id 回复的用户ID(0表示直接评论)
* @property string $body 评论内容
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态(0:隐藏 1:正常)
*/
class FriendCircleComment extends Base
{
protected $name = 'friend_circle_comment';
protected $autoWriteTimestamp = true;
protected function getOptions(): array
{
return array_merge(parent::getOptions(), [
'insert' => [
'status' => 1,
'reply_user_id' => 0,
],
]);
}
/**
* 关联朋友圈动态
*/
public function circle()
{
return $this->belongsTo('\\app\\model\\FriendCircle', 'circle_id', 'id');
}
/**
* 关联评论用户
*/
public function user()
{
return $this->belongsTo('\\app\\model\\User', 'user_id', 'id');
}
/**
* 关联被回复的用户
*/
public function replyUser()
{
return $this->belongsTo('\\app\\model\\User', 'reply_user_id', 'id');
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace app\model;
/**
* 朋友圈点赞模型
* @property integer $id 主键(ID)
* @property integer $circle_id 朋友圈动态ID
* @property integer $user_id 用户ID
* @property integer $created_at 创建时间
*/
class FriendCircleLike extends Base
{
protected $name = 'friend_circle_like';
protected $autoWriteTimestamp = 'int';
/**
* 关联朋友圈动态
*/
public function circle()
{
return $this->belongsTo('\\app\\model\\FriendCircle', 'circle_id', 'id');
}
/**
* 关联用户
*/
public function user()
{
return $this->belongsTo('\\app\\model\\User', 'user_id', 'id');
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace app\model;
use app\model\Base;
/**
* @property integer $id 主键(ID) - 无注释
* @property string $title 名称
* @property float $price 价格
* @property float $org_price 原价
* @property integer $duration 时长
* @property string $label 标签
* @property integer $status 0:禁用,1启用
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
*/
class Thali extends Base
{
protected function getOptions(): array
{
// 所有的参数配置统一返回
return array_merge(parent::getOptions(),[
'append' => []
]);
}
}
+9 -4
View File
@@ -82,12 +82,12 @@ class User extends Base
public static function onAfterUpdate($row){
$changeData = $row->getChangedData();
$orgData = $row->getOrigin();
//cp($changeData);
if(isset($changeData['avatar']) || isset($changeData['nickname'])){
request()->IM->user->updateUserInfo($row->id,[
$sdata = [
'nickname' => $row->nickname,
'faceURL' => cdnurl($row->avatar)
]);
];
request()->IM->user->updateUserInfo($row->id,$sdata);
}
if(isset($changeData['status']) || $changeData['status'] == '0'){
request()->IM->user->forceLogout($row->id);
@@ -130,7 +130,12 @@ class User extends Base
{
return $this->hasMany(UserTeam::class, 'ancestor_id', 'id');
}
function setExpireAtAttr($v){
if($v && strpos($v,'-')){
return strtotime($v);
}
return $v;
}
public static function transform($from_currency,$to_currency,$user_id,$amount,\app\enum\BalanceType $type,$memo=null){
if(!in_array($from_currency,Config('site.allow_currencys'))){
+9 -3
View File
@@ -5,11 +5,17 @@ namespace app\model;
/**
* @property integer $id 主键(主键)
* @property integer $pid 上级id
* @property string $name 角色名
* @property string $rules 权限
* @property string $created_at 创建时间
* @property string $updated_at 更新时间
* @property integer $pid 上级id
* @property integer $max_send_msg_count 最大消息数量
* @property integer $max_friend_count 最大好友数量
* @property integer $max_group_join_count 最大加入的群组数量
* @property integer $max_gourp_create_count 最大创建的群组数量
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class UserRole extends Base
{
-1
View File
@@ -3,7 +3,6 @@
namespace app\model;
use app\model\Base;
use support\Model;
/**
* @property integer $id 主键(主键)
* @property string $title 标题
+69
View File
@@ -0,0 +1,69 @@
<?php
namespace app\model;
use app\model\Base;
/**
* @property integer $id 主键(ID) - 无注释
* @property integer $user_id 用户ID
* @property float $deduction_amount 提现金额
* @property float $recive_amount 到账金额
* @property float $fee 后续费
* @property string $title 姓名
* @property string $network 方式
* @property string $address 地址
* @property integer $transfer_at 转账时间
* @property string $txid 凭证
* @property string $memo 备注
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class Version extends Base
{
protected function getOptions(): array
{
// 所有的参数配置统一返回
return array_merge(parent::getOptions(),[
'append' => ['source_text']
]);
}
function getSourceTextAttr($v,$row){
if($v){
return cdnurl($v);
}
}
function getOsList(){
return [
"android"=>"Android",
"ios"=>"IOS",
"harmonry"=>"鸿蒙"
];
}
function getTypeList(){
return [
"1"=>"WGT热更新",
"0"=>"整包更新",
"2"=>"外链下载更新"
];
}
function getForceList(){
return [
"0"=>"可选更新",
"1"=>"强制更新",
];
}
function getStatusList(){
return [
'0' => '禁用',
'1' => '启用'
];
}
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');//->setEagerlyType(0);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace app\validate;
use taoser\Validate;
class User extends Validate
{
protected $rule = [
'username' => 'require|max:25',
'email' => 'email',
'mobile' => 'mobile',
'password' => 'require|max:32'
];
// 定义信息
protected $message = [
'username.require' => '去设置用户名',
'username.max' => '用户名最多不能超过25个字符',
'mobile' => '手机号格式错误',
'email' => '邮箱格式错误',
'password.require' => '请设置密码',
'password.max' => '密码最多不能超过32个字符',
];
//定义场景
protected $scene = [
'register.email' => ['email','password'],
'register.username' => ['username','password'],
'register.mobile' => ['mobile','password'],
];
}