diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b05cbd2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "php.version": "8.2" +} \ No newline at end of file diff --git a/app/api/controller/BaseController.php b/app/api/controller/BaseController.php index db220c7..6acce58 100644 --- a/app/api/controller/BaseController.php +++ b/app/api/controller/BaseController.php @@ -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()); diff --git a/app/api/controller/CommonController.php b/app/api/controller/CommonController.php index 338f582..b96cd86 100644 --- a/app/api/controller/CommonController.php +++ b/app/api/controller/CommonController.php @@ -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()); - } - } } \ No newline at end of file diff --git a/app/api/controller/FriendCircleController.php b/app/api/controller/FriendCircleController.php new file mode 100644 index 0000000..2cba832 --- /dev/null +++ b/app/api/controller/FriendCircleController.php @@ -0,0 +1,357 @@ +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]); + } + } +} \ No newline at end of file diff --git a/app/api/controller/FriendController.php b/app/api/controller/FriendController.php new file mode 100644 index 0000000..ea63ac0 --- /dev/null +++ b/app/api/controller/FriendController.php @@ -0,0 +1,42 @@ +success('ok'); + } + +} \ No newline at end of file diff --git a/app/api/controller/RoleController.php.bak b/app/api/controller/RoleController.php similarity index 100% rename from app/api/controller/RoleController.php.bak rename to app/api/controller/RoleController.php diff --git a/app/api/controller/UserController.php b/app/api/controller/UserController.php index 4069e26..28ee0a6 100644 --- a/app/api/controller/UserController.php +++ b/app/api/controller/UserController.php @@ -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); + } } \ No newline at end of file diff --git a/app/command/Min.php b/app/command/Min.php new file mode 100644 index 0000000..51d9f02 --- /dev/null +++ b/app/command/Min.php @@ -0,0 +1,173 @@ + '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'; + } +} diff --git a/app/command/Min/stubs/css.stub b/app/command/Min/stubs/css.stub new file mode 100644 index 0000000..17211a1 --- /dev/null +++ b/app/command/Min/stubs/css.stub @@ -0,0 +1,6 @@ +({ + cssIn: "{%cssBasePath%}{%cssBaseName%}.css", + out: "{%cssBasePath%}{%cssBaseName%}.min.css", + optimizeCss: "default", + optimize: "{%optimize%}" +}) \ No newline at end of file diff --git a/app/command/Min/stubs/js.stub b/app/command/Min/stubs/js.stub new file mode 100644 index 0000000..8e7a210 --- /dev/null +++ b/app/command/Min/stubs/js.stub @@ -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" //目标文件 +}); \ No newline at end of file diff --git a/app/command/OpenIm.php b/app/command/OpenIm.php index 89cc1c5..4bb1229 100644 --- a/app/command/OpenIm.php +++ b/app/command/OpenIm.php @@ -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){ diff --git a/app/controller/DocController.php b/app/controller/DocController.php index 00eb6ea..9f7b797 100644 --- a/app/controller/DocController.php +++ b/app/controller/DocController.php @@ -8,6 +8,6 @@ class DocController { public function index(Request $request) { - return view(base_path()."/public/doc/index.html"); + return view("/public/doc/index"); } } diff --git a/app/controller/HookController.php b/app/controller/HookController.php new file mode 100644 index 0000000..b64f11d --- /dev/null +++ b/app/controller/HookController.php @@ -0,0 +1,246 @@ + 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 + ]); + } +} \ No newline at end of file diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index f7e435b..765c724 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -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'; + } } diff --git a/app/controller/PayController.php b/app/controller/PayController.php deleted file mode 100644 index ce91372..0000000 --- a/app/controller/PayController.php +++ /dev/null @@ -1,186 +0,0 @@ -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' => '提示信息' - ]); - } -} \ No newline at end of file diff --git a/app/controller/TestProductBuyController.php b/app/controller/TestProductBuyController.php deleted file mode 100644 index 32a2b00..0000000 --- a/app/controller/TestProductBuyController.php +++ /dev/null @@ -1,182 +0,0 @@ - [ - '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("
");
-        // 输出用户关系链
-        // 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.=  "
"; - 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; - } -} \ No newline at end of file diff --git a/app/controller/TestRoleBuyController.php b/app/controller/TestRoleBuyController.php deleted file mode 100644 index 2519477..0000000 --- a/app/controller/TestRoleBuyController.php +++ /dev/null @@ -1,176 +0,0 @@ - [ - '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("
");
-        // 输出用户关系链
-        // 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 .= "
"; - 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; - } -} \ No newline at end of file diff --git a/app/event/User.php b/app/event/User.php index 8e8787b..ced47bf 100644 --- a/app/event/User.php +++ b/app/event/User.php @@ -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=[]){ diff --git a/app/functions.php b/app/functions.php index 23cab5f..e58517e 100644 --- a/app/functions.php +++ b/app/functions.php @@ -1,6 +1,11 @@ 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]; + + } } \ No newline at end of file diff --git a/app/mcp/McpService.php b/app/mcp/McpService.php index 5d2595a..8208dcc 100644 --- a/app/mcp/McpService.php +++ b/app/mcp/McpService.php @@ -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',"; } /** diff --git a/app/mcp/tpl/js/admin.tpl b/app/mcp/tpl/js/admin.tpl index 1260ad6..8248c67 100644 --- a/app/mcp/tpl/js/admin.tpl +++ b/app/mcp/tpl/js/admin.tpl @@ -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 = ""; diff --git a/app/mcp/tpl/view/update.html b/app/mcp/tpl/view/update.html index 92216ae..42976ae 100644 --- a/app/mcp/tpl/view/update.html +++ b/app/mcp/tpl/view/update.html @@ -50,8 +50,8 @@ @@ -64,8 +64,8 @@ diff --git a/app/middleware/ActionHook.php b/app/middleware/ActionHook.php index 1d6b3ab..8b67253 100644 --- a/app/middleware/ActionHook.php +++ b/app/middleware/ActionHook.php @@ -1,6 +1,7 @@ controller) { + // 禁止直接访问beforeAction afterAction if (substr($request->action,0,9) === '__before_' || substr($request->action,0,8) === '__after_') { $callback = Route::getFallback() ?? function () { diff --git a/app/model/Archives.php b/app/model/Archives.php index 9f55608..83f476d 100644 --- a/app/model/Archives.php +++ b/app/model/Archives.php @@ -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); diff --git a/app/model/Content.php b/app/model/Content.php index 4cba29b..169d232 100644 --- a/app/model/Content.php +++ b/app/model/Content.php @@ -11,4 +11,9 @@ use app\model\Base; */ class Content extends Base { + protected function getOptions(): array{ + return array_merge(parent::getOptions(),[ + 'autoWriteTimestamp' => false + ]); + } } diff --git a/app/model/Files.php b/app/model/Files.php new file mode 100644 index 0000000..51c865d --- /dev/null +++ b/app/model/Files.php @@ -0,0 +1,33 @@ +belongsTo('User', 'user_id', 'id');//->setEagerlyType(0); + } + + +} diff --git a/app/model/FriendCircle.php b/app/model/FriendCircle.php new file mode 100644 index 0000000..650c3a9 --- /dev/null +++ b/app/model/FriendCircle.php @@ -0,0 +1,138 @@ + [ + '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; + } +} + diff --git a/app/model/FriendCircleComment.php b/app/model/FriendCircleComment.php new file mode 100644 index 0000000..ef49440 --- /dev/null +++ b/app/model/FriendCircleComment.php @@ -0,0 +1,54 @@ + [ + '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'); + } +} + diff --git a/app/model/FriendCircleLike.php b/app/model/FriendCircleLike.php new file mode 100644 index 0000000..e7780e9 --- /dev/null +++ b/app/model/FriendCircleLike.php @@ -0,0 +1,32 @@ +belongsTo('\\app\\model\\FriendCircle', 'circle_id', 'id'); + } + + /** + * 关联用户 + */ + public function user() + { + return $this->belongsTo('\\app\\model\\User', 'user_id', 'id'); + } +} + diff --git a/app/model/Thali.php b/app/model/Thali.php new file mode 100644 index 0000000..fde80ac --- /dev/null +++ b/app/model/Thali.php @@ -0,0 +1,27 @@ + [] + ]); + } + +} diff --git a/app/model/User.php b/app/model/User.php index 3cddbf7..7fe6726 100644 --- a/app/model/User.php +++ b/app/model/User.php @@ -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'))){ diff --git a/app/model/UserRole.php b/app/model/UserRole.php index c4dae30..e808293 100644 --- a/app/model/UserRole.php +++ b/app/model/UserRole.php @@ -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 { diff --git a/app/model/UserRule.php b/app/model/UserRule.php index bdd45dc..5ed426a 100644 --- a/app/model/UserRule.php +++ b/app/model/UserRule.php @@ -3,7 +3,6 @@ namespace app\model; use app\model\Base; -use support\Model; /** * @property integer $id 主键(主键) * @property string $title 标题 diff --git a/app/model/Version.php b/app/model/Version.php new file mode 100644 index 0000000..01bf2a1 --- /dev/null +++ b/app/model/Version.php @@ -0,0 +1,69 @@ + ['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); + } + + +} diff --git a/app/validate/User.php b/app/validate/User.php new file mode 100644 index 0000000..019fad6 --- /dev/null +++ b/app/validate/User.php @@ -0,0 +1,31 @@ + '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'], + ]; + +} \ No newline at end of file diff --git a/config/log.php b/config/log.php index b12e2a1..1d7575e 100644 --- a/config/log.php +++ b/config/log.php @@ -18,7 +18,8 @@ return [ [ 'class' => Monolog\Handler\RotatingFileHandler::class, 'constructor' => [ - runtime_path() . '/logs/webman'.ceil(date('H')/6).'.log', + //runtime_path() . '/logs/webman'.ceil(date('H')/6).'.log', + runtime_path() . '/logs/webman.log', 7, //$maxFiles Monolog\Logger::INFO, ], diff --git a/config/process.php b/config/process.php index 5ea733f..158b85a 100644 --- a/config/process.php +++ b/config/process.php @@ -29,7 +29,7 @@ return [ base_path() . '/plugin/app', base_path() . '/support', base_path() . '/resource', - base_path() . '/.env', + base_path() . '/.env' ], // 文件后缀 'monitor_extensions' => [ diff --git a/config/route.php b/config/route.php index 1ae01f0..13056fb 100644 --- a/config/route.php +++ b/config/route.php @@ -14,6 +14,9 @@ use Webman\Route; +Route::get('/u/{code}', [\app\controller\IndexController::class, 'user']); +Route::get('/g/{code}', [\app\controller\IndexController::class, 'group']); + Route::fallback(function(){ $fn = base_path().'/public/index.html'; if(file_exists($fn)){ diff --git a/database/friend_circle_tables.sql b/database/friend_circle_tables.sql new file mode 100644 index 0000000..a105674 --- /dev/null +++ b/database/friend_circle_tables.sql @@ -0,0 +1,49 @@ +-- 朋友圈功能数据库表结构 + +-- 朋友圈动态表 +CREATE TABLE IF NOT EXISTS `friend_circle` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` int(11) NOT NULL COMMENT '用户ID', + `body` text COMMENT '内容', + `files` text COMMENT '图片列表(JSON)', + `like_count` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数', + `comment_count` int(11) NOT NULL DEFAULT '0' COMMENT '评论数', + `created_at` int(11) NOT NULL COMMENT '创建时间', + `updated_at` int(11) NOT NULL COMMENT '更新时间', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:隐藏 1:正常)', + PRIMARY KEY (`id`), + KEY `user_id` (`user_id`), + KEY `status` (`status`), + KEY `created_at` (`created_at`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='朋友圈动态表'; + +-- 朋友圈点赞表 +CREATE TABLE IF NOT EXISTS `friend_circle_like` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `circle_id` int(11) NOT NULL COMMENT '朋友圈动态ID', + `user_id` int(11) NOT NULL COMMENT '用户ID', + `created_at` int(11) NOT NULL COMMENT '创建时间', + PRIMARY KEY (`id`), + UNIQUE KEY `circle_user` (`circle_id`,`user_id`), + KEY `circle_id` (`circle_id`), + KEY `user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='朋友圈点赞表'; + +-- 朋友圈评论表 +CREATE TABLE IF NOT EXISTS `friend_circle_comment` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `circle_id` int(11) NOT NULL COMMENT '朋友圈动态ID', + `user_id` int(11) NOT NULL COMMENT '用户ID', + `reply_user_id` int(11) NOT NULL DEFAULT '0' COMMENT '回复的用户ID(0表示直接评论)', + `body` text NOT NULL COMMENT '评论内容', + `created_at` int(11) NOT NULL COMMENT '创建时间', + `updated_at` int(11) NOT NULL COMMENT '更新时间', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0:隐藏 1:正常)', + PRIMARY KEY (`id`), + KEY `circle_id` (`circle_id`), + KEY `user_id` (`user_id`), + KEY `reply_user_id` (`reply_user_id`), + KEY `status` (`status`), + KEY `created_at` (`created_at`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='朋友圈评论表'; + diff --git a/plugin/admin/app/controller/ArchivesController.php b/plugin/admin/app/controller/ArchivesController.php index 387fa21..317a347 100644 --- a/plugin/admin/app/controller/ArchivesController.php +++ b/plugin/admin/app/controller/ArchivesController.php @@ -85,8 +85,8 @@ class ArchivesController extends Crud $result = $this->model->save($params); Db::commit(); } catch (Exception $e) { - Db::rollback(); - return $this->fail($e->getMessage()); + Db::rollback(); + return $this->fail($e->getMessage()); } if ($result === false) { return $this->fail(__('No rows were inserted')); diff --git a/plugin/admin/app/controller/AttachController.php b/plugin/admin/app/controller/AttachController.php new file mode 100644 index 0000000..6eceee8 --- /dev/null +++ b/plugin/admin/app/controller/AttachController.php @@ -0,0 +1,168 @@ +model = new \app\model\Files(); + } + function list(Request $request) + { + return view('', [ + + ]); + } + function feupload(Request $request): Response + { + $user = ['id'=>admin_id()]; + $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']; + $maxSize = 1024*1024*100; //100M + //多文件上传 + $files = $request->file(); + try { + $result = Storage::adapter('public') + ->path($savePath) + ->size(1024*1024*10) + ->extYes(['image/jpeg','image/png']) + ->uploads($files,0,$maxSize,false); + $save_datas = []; + foreach($result as $k=>$fileinfo){ + $save_datas[] = [ + 'user_id' => $user['id'], + '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::saveAll($save_datas); + return $this->success(__('successful'),[ + 'link' => $result[0]['path'], + ]); + }catch (\Exception $e){ + return $this->fail($e->getMessage()); + } + } + function upload(Request $request): Response + { + log_alert(0); + $savePath = $request->post('savePath','files'); + $validate = Validate::rule('savePath', 'alphaNum'); + $data = ['savePath' => $savePath]; + log_alert($data); + if (!$validate->check($data)) { + cp($validate->getError()); + return $this->fail( '参数错误:'.$validate->getError()); + } + log_alert('1'); + $file = current($request->file()); + if (!$file || !$file->isValid()) { + return $this->fail('未找到文件'); + } + log_alert('2'); + try { + $data = $this->base($request, $savePath); + } catch (\Exception $e) { + log_alert($e->getMessage()); + //throw $th; + } + log_alert('3'); + //cp($data); + return $this->success( '上传成功', [ + 'url' => $data['realpath'], + 'name' => $data['name'], + 'fullurl' => $data['url'], + 'size' => $data['size'], + 'url1' => $data['url'], + ]); + } + + /** + * 获取上传数据 + * @param Request $request + * @param $savePath 保存位置 + * @return array + * @throws \Exception + */ + protected function base(Request $request, $savePath): array + { + $user = ['id'=>admin_id()]; + // 适配器 local默认是存储在runtime目录下 public默认是存储在public目录下 + // 可访问的静态文件建议public + // 默认适配器是local + //Storage::adapter('public'); + $savePath = trim($savePath,'/'); + $savePath = 'upload/'.$savePath; + cp($savePath); + $file = current($request->file()); + cp($file); + $mimetype = explode(',',Config('site.upload_mimetype')); + $maxsize = Config('site.upload_maxsize')*1024*1024; + $result = Storage::adapter('public') + ->path($savePath) + ->size($maxsize) + ->extYes($mimetype) + ->upload($file); + cp($result); + + $save_datas = [ + 'user_id' => $user['id'], + 'category' => 'default', + 'title' => $result->origin_name, + 'path' => $result->file_name, + 'size' => $result->size, + 'mime_type' => $result->mime_type, + 'extension' => $result->extension, + 'height' => $result->file_height, + 'width' => $result->file_width, + 'sha1' => sha1_file(public_path($result->file_name)), + 'use_count' => 0, + ]; + (new \app\model\Files)->save($save_datas); + return [ + 'code' => 0, + 'url' => $result->file_url, + 'name' => $result->origin_name, + 'realpath' => '/'.$result->file_name, + 'size' => $result->size, + 'mime_type' => $result->mime_type, + 'image_with'=> $result->file_width, + 'image_height' => $result->file_height, + 'ext' => $result->extension, + ]; + } +} diff --git a/plugin/admin/app/controller/AttachmentController.php b/plugin/admin/app/controller/AttachmentController.php deleted file mode 100644 index fab3769..0000000 --- a/plugin/admin/app/controller/AttachmentController.php +++ /dev/null @@ -1,127 +0,0 @@ -file()); - if (!$file || !$file->isValid()) { - return $this->fail('未找到文件'); - } - $data = $this->base($request, '/upload/files/' . date('Ymd')); - return json([ - 'link' => $data['url'], - ]); - } - function upload(Request $request): Response - { - - $file = current($request->file()); - if (!$file || !$file->isValid()) { - return $this->fail('未找到文件'); - } - $data = $this->base($request, '/upload/files/' . date('Ymd')); - //cp($data); - return $this->json(0, '上传成功', [ - 'url' => $data['realpath'], - 'name' => $data['name'], - 'fullurl' => $data['url'], - 'size' => $data['size'], - ]); - } - - /** - * 获取上传数据 - * @param Request $request - * @param $relative_dir - * @return array - * @throws \Exception - */ - protected function base(Request $request, $relative_dir): array - { - // 适配器 local默认是存储在runtime目录下 public默认是存储在public目录下 - // 可访问的静态文件建议public - // 默认适配器是local - //Storage::adapter('public'); - $relative_dir = ltrim($relative_dir, '\\/'); - $file = current($request->file()); - try { - if (!$file || !$file->isValid()) { - throw new \support\exception\BusinessException('未找到上传文件', 400); - } - - $ext = $file->getUploadExtension() ?: null; - $mime_type = $file->getUploadMimeType(); - $file_name = $file->getUploadName(); - $file_size = $file->getSize(); - - if (!$ext && $file_name === 'blob') { - [$___image, $ext] = explode('/', $mime_type); - unset($___image); - } - - $ext = strtolower($ext); - $ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp']; - if (in_array($ext, $ext_forbidden_map)) { - throw new \support\exception\BusinessException('不支持该格式的文件上传', 400); - } - $mimetype = explode(',',Config('site.mimetype')); - $result = Storage::adapter('public') - ->path($relative_dir) - ->size(1024 * 1024 * 5) - ->extYes($mimetype) - //->extNo(['image/png']) - ->upload($file); - } catch (\Exception $e) { - return [ - 'code' => 1, - 'msg' => $e->getMessage() - ]; - } - // cp($result); - // stdClass Object - // ( - // [adapter] => public - // [origin_name] => OIP-C (1).jpg - // [file_name] => upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg - // [storage_key] => eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76 - // [file_url] => //luru.oss-ap-southeast-1.aliyuncs.com/upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg - // [size] => 15370 - // [mime_type] => image/jpeg - // [extension] => jpg - // [file_height] => 474 - // [file_width] => 474 - // ) - return [ - 'code' => 0, - 'url' => $result->file_url, - 'name' => $result->origin_name, - 'realpath' => '/'.$result->file_name, - 'size' => $result->size, - 'mime_type' => $result->mime_type, - 'image_with' => $result->file_width, - 'image_height' => $result->file_height, - 'ext' => $result->extension, - ]; - } -} diff --git a/plugin/admin/app/controller/FilesController.php b/plugin/admin/app/controller/FilesController.php new file mode 100644 index 0000000..0238bd1 --- /dev/null +++ b/plugin/admin/app/controller/FilesController.php @@ -0,0 +1,160 @@ +model = new \app\model\Files(); + } + function list(Request $request) + { + return view('', [ + + ]); + } + function feupload(Request $request): Response + { + $user = ['id'=>admin_id()]; + $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']; + $maxSize = 1024*1024*100; //100M + //多文件上传 + $files = $request->file(); + try { + $result = Storage::adapter('public') + ->path($savePath) + ->size(1024*1024*10) + ->extYes(['image/jpeg','image/png']) + ->uploads($files,0,$maxSize,false); + $save_datas = []; + foreach($result as $k=>$fileinfo){ + $save_datas[] = [ + 'user_id' => $user['id'], + '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::saveAll($save_datas); + return $this->success(__('successful'),[ + 'link' => $result[0]['path'], + ]); + }catch (\Exception $e){ + return $this->fail($e->getMessage()); + } + } + function upload(Request $request): Response + { + cp('0'); + $savePath = $request->post('savePath','files'); + $validate = Validate::rule('savePath', 'alphaNum'); + $data = ['savePath' => $savePath]; + cp($data); + if (!$validate->check($data)) { + cp($validate->getError()); + return $this->fail( '参数错误:'.$validate->getError()); + } + cp('1'); + $file = current($request->file()); + if (!$file || !$file->isValid()) { + return $this->fail('未找到文件'); + } + cp('2'); + $data = $this->base($request, $savePath); + cp('3'); + //cp($data); + return $this->success( '上传成功', [ + 'url' => $data['realpath'], + 'name' => $data['name'], + 'fullurl' => $data['url'], + 'size' => $data['size'], + 'url1' => $data['url'], + ]); + } + + /** + * 获取上传数据 + * @param Request $request + * @param $savePath 保存位置 + * @return array + * @throws \Exception + */ + protected function base(Request $request, $savePath): array + { + $user = ['id'=>admin_id()]; + // 适配器 local默认是存储在runtime目录下 public默认是存储在public目录下 + // 可访问的静态文件建议public + // 默认适配器是local + //Storage::adapter('public'); + $savePath = trim($savePath,'/'); + $savePath = 'upload/'.$savePath; + $file = current($request->file()); + $mimetype = explode(',',Config('site.upload_mimetype')); + $maxsize = Config('site.upload_maxsize')*1024*1024; + $result = Storage::adapter('public') + ->path($savePath) + ->size($maxsize) + ->extYes($mimetype) + ->upload($file); + + $save_datas = [ + 'user_id' => $user['id'], + 'category' => 'default', + 'title' => $result->origin_name, + 'path' => $result->file_name, + 'size' => $result->size, + 'mime_type' => $result->mime_type, + 'extension' => $result->extension, + 'height' => $result->file_height, + 'width' => $result->file_width, + 'sha1' => sha1_file(public_path($result->file_name)), + 'use_count' => 0, + ]; + (new \app\model\Files)->save($save_datas); + return [ + 'code' => 0, + 'url' => $result->file_url, + 'name' => $result->origin_name, + 'realpath' => '/'.$result->file_name, + 'size' => $result->size, + 'mime_type' => $result->mime_type, + 'image_with'=> $result->file_width, + 'image_height' => $result->file_height, + 'ext' => $result->extension, + ]; + } +} diff --git a/plugin/admin/app/controller/IndexController.php b/plugin/admin/app/controller/IndexController.php index 254cd9e..0f6e12b 100644 --- a/plugin/admin/app/controller/IndexController.php +++ b/plugin/admin/app/controller/IndexController.php @@ -37,7 +37,7 @@ class IndexController extends Base $admin = admin(); if (!$admin) { $title = config('site.name') ?? 'admin'; - $logo = cdnurl(config('site.admin_logo') ?? '/app/admin/images/logo.png'); + $logo = cdnurl(config('site.admin_logo') ?? admin_path().'/images/logo.png'); return view('account/login',['logo'=>$logo,'title'=>$title]); } //缓存 diff --git a/plugin/admin/app/controller/TeamController.php b/plugin/admin/app/controller/TeamController.php index 469deaf..fe53b0c 100644 --- a/plugin/admin/app/controller/TeamController.php +++ b/plugin/admin/app/controller/TeamController.php @@ -8,7 +8,7 @@ use support\Request; use support\Response; /** - * 用户管理 + * 团队管理 */ class TeamController extends Crud { diff --git a/plugin/admin/app/controller/ThaliController.php b/plugin/admin/app/controller/ThaliController.php new file mode 100644 index 0000000..0343135 --- /dev/null +++ b/plugin/admin/app/controller/ThaliController.php @@ -0,0 +1,34 @@ +model = new Thali(); + $statusList = $this->model->getStatusList(); + $this->assign("statusList", $statusList); + $this->assignconfig("statusList", $statusList); + } +} diff --git a/plugin/admin/app/controller/UserController.php b/plugin/admin/app/controller/UserController.php index 1e7d4cd..ce28c73 100644 --- a/plugin/admin/app/controller/UserController.php +++ b/plugin/admin/app/controller/UserController.php @@ -33,7 +33,7 @@ class UserController extends Crud ['value'=>1,'label'=>"内部用户"], ['value'=>2,'label'=>"联盟商"], ]; - $roleList = \app\model\UserRole::order('id','desc')->column('name as label,id as value'); + $roleList = \app\model\UserRole::order('id','asc')->column('name as label,id as value'); $this->assign('groupList',$groupList); $this->assignconfig('groupList',$groupList); $this->assign('roleList',$roleList); diff --git a/plugin/admin/app/controller/VersionController.php b/plugin/admin/app/controller/VersionController.php new file mode 100644 index 0000000..bfa0380 --- /dev/null +++ b/plugin/admin/app/controller/VersionController.php @@ -0,0 +1,43 @@ +model = new \app\model\Version(); + $osList = $this->model->getOsList(); + $this->assign("osList", $osList); + $this->assignconfig("osList", $osList); + $forceList = $this->model->getForceList(); + $this->assign("forceList", $forceList); + $this->assignconfig("forceList", $forceList); + $typeList = $this->model->getTypeList(); + $this->assign("typeList", $typeList); + $this->assignconfig("typeList", $typeList); + $statusList = $this->model->getStatusList(); + $this->assign("statusList", $statusList); + $this->assignconfig("statusList", $statusList); + } + +} diff --git a/plugin/admin/app/functions.php b/plugin/admin/app/functions.php index 54ddaa7..9b77ff3 100644 --- a/plugin/admin/app/functions.php +++ b/plugin/admin/app/functions.php @@ -23,7 +23,7 @@ function url($path='',$args=[]){ } $path = $path.'?'.$args; } - return '/app/admin/'.$path; + return admin_path().'/'.$path; } /** * 当前管理员id diff --git a/plugin/admin/app/middleware/AccessControl.php b/plugin/admin/app/middleware/AccessControl.php index b694ad7..d4e10f8 100644 --- a/plugin/admin/app/middleware/AccessControl.php +++ b/plugin/admin/app/middleware/AccessControl.php @@ -31,8 +31,8 @@ class AccessControl implements MiddlewareInterface $response = json(['code' => $code, 'msg' => $msg, 'data' => []]); } else { if ($code === 401) { - $response = response('',401); - //$response = response('',301, ['Location'=> '/app/admin/index/index']); + $response = response('',401); + //$response = response('',301, ['Location'=> admin_path().'/index/index']); } else { $request->app = ''; $request->plugin = 'admin'; diff --git a/plugin/admin/app/middleware/Config.php b/plugin/admin/app/middleware/Config.php index 631e36f..377d29a 100644 --- a/plugin/admin/app/middleware/Config.php +++ b/plugin/admin/app/middleware/Config.php @@ -26,7 +26,8 @@ class Config implements MiddlewareInterface $config['debug'] = config('app.debug'); $config['controller'] = $request->controller_name; $config['action'] = $request->action_name; - $config['moduleurl'] = '/app/admin'; + $config['moduleurl'] = admin_path(); + $config['admin_path'] = admin_path(); $request->_view_vars = array_merge((array) $request->_view_vars,[ 'user' => session('admin'), 'config' => $config diff --git a/plugin/admin/app/view/account/profile.html b/plugin/admin/app/view/account/profile.html index bf9482f..2ae5fad 100644 --- a/plugin/admin/app/view/account/profile.html +++ b/plugin/admin/app/view/account/profile.html @@ -47,8 +47,8 @@ diff --git a/plugin/admin/app/view/address/index.html b/plugin/admin/app/view/address/index.html index 91d0afd..d5fd08f 100644 --- a/plugin/admin/app/view/address/index.html +++ b/plugin/admin/app/view/address/index.html @@ -1,6 +1,6 @@ {layout name="layout"}
- + 新增 diff --git a/plugin/admin/app/view/admin/index.html b/plugin/admin/app/view/admin/index.html index 1436d58..3a274a7 100644 --- a/plugin/admin/app/view/admin/index.html +++ b/plugin/admin/app/view/admin/index.html @@ -1,7 +1,7 @@ {layout name="layout"}
diff --git a/plugin/admin/app/view/admin_role/index.html b/plugin/admin/app/view/admin_role/index.html index 810b8fc..a7001ce 100644 --- a/plugin/admin/app/view/admin_role/index.html +++ b/plugin/admin/app/view/admin_role/index.html @@ -1,7 +1,7 @@ {layout name="layout"}
-
-
-{include file="common/chooseicontpl" /} \ No newline at end of file +
\ No newline at end of file diff --git a/plugin/admin/app/view/archives/index.html b/plugin/admin/app/view/archives/index.html index 1dd11d0..0a0535f 100644 --- a/plugin/admin/app/view/archives/index.html +++ b/plugin/admin/app/view/archives/index.html @@ -1,6 +1,6 @@ {layout name="layout"}
- + 新增 diff --git a/plugin/admin/app/view/archives/update.html b/plugin/admin/app/view/archives/update.html index 6af9edb..ed8e597 100644 --- a/plugin/admin/app/view/archives/update.html +++ b/plugin/admin/app/view/archives/update.html @@ -103,7 +103,7 @@
@@ -115,7 +115,7 @@ diff --git a/plugin/admin/app/view/card/index.html b/plugin/admin/app/view/card/index.html index 1dd11d0..0a0535f 100644 --- a/plugin/admin/app/view/card/index.html +++ b/plugin/admin/app/view/card/index.html @@ -1,6 +1,6 @@ {layout name="layout"}
- + 新增 diff --git a/plugin/admin/app/view/category/index.html b/plugin/admin/app/view/category/index.html index 1dd11d0..0a0535f 100644 --- a/plugin/admin/app/view/category/index.html +++ b/plugin/admin/app/view/category/index.html @@ -1,6 +1,6 @@ {layout name="layout"}
- + 新增 diff --git a/plugin/admin/app/view/common/chooseicontpl.html b/plugin/admin/app/view/common/chooseicontpl.html deleted file mode 100644 index cc23a07..0000000 --- a/plugin/admin/app/view/common/chooseicontpl.html +++ /dev/null @@ -1,44 +0,0 @@ - - - \ No newline at end of file diff --git a/plugin/admin/app/view/dev/form.html b/plugin/admin/app/view/dev/form.html index d7a2cbc..16985f0 100644 --- a/plugin/admin/app/view/dev/form.html +++ b/plugin/admin/app/view/dev/form.html @@ -40,12 +40,12 @@