afa 5 months ago
parent
commit
ac27fed050

+ 11 - 13
app/api/controller/Api.php

@@ -33,26 +33,24 @@ class Api extends BaseController
 
     protected function _initialize()
     {
-
+        
         $token=request()->header('token');
         if(!$token){
             $token=Cookie::get('token');
         }
-        if(!$token){
-            $token=request()->get('token');
-        }
-        if(!$token){
-            $token=request()->post('token');
-        }
-        //$this->auth=ApiAuthService::newInstance(['adapter'=>new $class($token)]);
-    
+        // if(!$token){
+        //     $token=request()->get('token');
+        // }
+        // if(!$token){
+        //     $token=request()->post('token');
+        // }
         $actionname = $this->request->action();
         $noNeedLoginSet=is_string($this->noNeedLogin)?[$this->noNeedLogin]:$this->noNeedLogin;
         $noNeedLogin = in_array('*',$noNeedLoginSet) || in_array($actionname,$noNeedLoginSet);
         //需要登陆
-        // if(!$noNeedLogin && !$this->auth->isLogin()){
-        //     $response = Response::create(__('请先登录!'), 'html', 401);
-        //     throw new HttpResponseException($response);
-        // }
+        if(!$noNeedLogin && !ApiAuthService::getToken($token)){
+            $response = Response::create(__('请先登录!'), 'html', 401);
+            throw new HttpResponseException($response);
+        }
     }
 }

+ 12 - 2
app/api/controller/Common.php

@@ -3,13 +3,15 @@ declare(strict_types=1);
 
 namespace app\api\controller;
 
-
+use think\annotation\route\Post;
+use think\annotation\route\Get;
+use think\annotation\route\Group;
 use app\common\service\upload\PublicUploadService;
 
 
 class Common extends Api{
-    protected $noNeedLogin = ['*'];
 
+    protected $noNeedLogin = ['*'];
     /**
      * 上传文件
      * @param File $file 文件流
@@ -34,4 +36,12 @@ class Common extends Api{
     }
 
 
+    public function area($pid)
+    {
+        if(!class_exists('\app\common\model\Area')){
+           $this->error('请先安装插件-省份城市地区数据');
+        }
+        $area=\app\common\model\Area::where('pid',$pid)->field('id,name')->select();
+        $this->success('',$area);
+    }
 }

+ 14 - 8
app/api/controller/Index.php

@@ -4,18 +4,22 @@ declare (strict_types = 1);
 namespace app\api\controller;
 
 use app\api\service\msg\WechatMsg;
+use think\annotation\route\Get;
+use think\annotation\route\Group;
+use think\annotation\route\Post;
 
-
-
+/**
+ * 测试控制器,实际开发请删除全部方法
+ */
 class Index extends Api
 {
     protected $noNeedLogin = ['*'];
-
-
-    public function hello()
+ 
+    public function testget()
     {
-      
-        $this->success('返回消息');
+        sleep(1);
+        $data=$this->request->get();
+        $this->success('返回消息',$data);
     }
 
 
@@ -26,7 +30,7 @@ class Index extends Api
         $this->success('返回消息',$data);
     }
 
-
+   
     public function list()
     {
         $page=$this->request->get('page/d');
@@ -53,6 +57,7 @@ class Index extends Api
         $this->success('',$res);
     }
 
+
     public function mpconfig()
     {
         $result=[
@@ -63,6 +68,7 @@ class Index extends Api
         $this->success('',$result);
     }
 
+ 
     public function sendtempmsg()
     {
         WechatMsg::testMsg($this->auth->id);

+ 6 - 2
app/api/controller/Miniapp.php

@@ -4,12 +4,15 @@ declare (strict_types = 1);
 namespace app\api\controller;
 
 use app\common\model\Third;
+use think\annotation\route\Group;
+use think\annotation\route\Post;
 
-
+#[Group("miniapp")]
 class Miniapp extends Api
 {
     protected $noNeedLogin = ['login','getMobile','mockLogin'];
 
+    #[Post('login')]
     public function login()
     {
         $code=$this->request->post('code');
@@ -32,7 +35,7 @@ class Miniapp extends Api
         $this->success('登录成功',compact('token','userinfo'));
     }
 
-
+    #[Post('getMobile')]
     public function getMobile()
     {
         $code=$this->request->post('code');
@@ -46,6 +49,7 @@ class Miniapp extends Api
     }
 
     //模拟登陆
+    #[Post('mock-login')]
     public function mockLogin()
     {
         $openid=$this->request->post('openid');

+ 8 - 1
app/api/controller/Mpapp.php

@@ -7,9 +7,12 @@ use app\common\model\MpSubscribe;
 use app\common\model\Qrcode;
 use app\common\model\Third;
 use app\common\model\QrcodeScan;
+use think\annotation\route\Get;
+use think\annotation\route\Group;
+use think\annotation\route\Route;
 use app\common\model\User;
 
-
+#[Group("mpapp")]
 class Mpapp extends Api{
     protected $noNeedLogin = ['*'];
 
@@ -37,6 +40,7 @@ class Mpapp extends Api{
     /**
      * 发起授权
      */
+    #[Get('connect')]
     public function connect()
     {
         if($this->auth->id){
@@ -63,6 +67,7 @@ class Mpapp extends Api{
     /**
      * 授权回调
      */
+    #[Get('callback')]
     public function callback()
     {
         // 授权成功后的回调
@@ -92,6 +97,7 @@ class Mpapp extends Api{
     /**
      * 创建菜单
      */
+    #[Get('menu')]
     public function menu()
     {
         $this->error('请删除这行代码后重试');
@@ -136,6 +142,7 @@ class Mpapp extends Api{
     /**
      * 公众号事件接收方法
      */
+    #[Route('POST,GET','event')]
     public function event()
     {
         $api = new \WeChat\Receive($this->config);

+ 26 - 45
app/api/controller/User.php

@@ -3,64 +3,45 @@ declare (strict_types = 1);
 
 namespace app\api\controller;
 
-
-use app\common\model\Qrcode;
+use app\api\validate\User as UserValidate;
+use app\api\service\ApiAuthService;
+use think\annotation\route\Post;
+use think\exception\ValidateException;
 
 
 class User extends Api
 {
+    
+    protected $noNeedLogin = ['login'];
 
 
-    protected $allowFields = ['id', 'nickname', 'mobile', 'avatar', 'balance', 'score'];
-    private Adapter $adapter;
-
-    public function userinfo(bool $allinfo = false)
+    public function userinfo(ApiAuthService $apiAuth)
     {
-        $user=$this->adapter->userinfo();
-        if(!$user){
-            return false;
-        }
-        if($allinfo){
-            return $user;
-        }else{
-            return array_intersect_key($user,array_flip($this->allowFields));
-        }
+        $user= $apiAuth->userinfo();
+        return $this->jsonSuccess('登录成功', $user); 
     }
 
-    // public function userinfo()
-    // {
-    //     $user=$this->auth->userinfo();
-    //     $this->success('',$user);
-    // }
+  
 
- 
- 
 
-    public function logout()
+    //登录
+    public function login(ApiAuthService $apiAuth)
     {
-        $this->adapter->logout();
+        $data=$this->request->post();
+        try {
+
+            validate(UserValidate::class)->scene('edit')->check($data);
+            $ret = $apiAuth->login($data['username'], $data['password']);
+            return $this->jsonSuccess('登录成功', $ret);    
+            
+        } catch (ValidateException $e) {
+            return $this->jsonError($e->getError());
+        }catch (\Exception $e) {
+        
+            return $this->jsonError($e->getMessage());
+        }
     }
 
-    public function getToken()
-    {
-        $usertoken=$this->adapter->getUserToken();
-        return $usertoken->token;
-    }
 
-    public function login(string $username, string $password)
-    {
-        $token=uuid();
-        $user=User::where('username',$username)->find();
-        if(!$user){
-            throw new \Exception('账号或密码错误');
-        }
-        if($user->password!=md5(md5($password.$user->salt))){
-            throw new \Exception('账号或密码错误');
-        }
-        if($user->status!='normal'){
-            throw new \Exception('账号已经被禁用');
-        }
-        $this->adapter->login($token,$user);
-        $this->login_user=$this->adapter->userinfo();
-    }
+    
 }

+ 25 - 21
app/api/service/ApiAuthService.php

@@ -2,8 +2,8 @@
 declare(strict_types=1);
 namespace app\api\service;
 
-use app\api\service\auth\Adapter;
-
+use think\facade\Cookie;
+use app\api\service\auth\MysqlAdapter;
 use app\common\model\User;
 use app\common\model\UserToken;
 use app\common\service\AuthService;
@@ -12,35 +12,35 @@ use app\common\service\AuthService;
 class ApiAuthService extends AuthService
 {
     protected $allowFields = ['id', 'nickname', 'mobile', 'avatar', 'balance', 'score'];
-    private Adapter $adapter;
+   
 
     public function userinfo(bool $allinfo = false)
-    {
-        $user=$this->adapter->userinfo();
-        if(!$user){
+    {   
+        $time=time();
+        $token =  Cookie::get('token');
+        if(!$token){
             return false;
         }
-        if($allinfo){
-            return $user;
-        }else{
-            return array_intersect_key($user,array_flip($this->allowFields));
-        }
+        $user = UserToken::where('token',$token)->where('expire','>',$time)->field('mobile')->value('user_id');
+        return $user?User::where('id',$user)->field($this->allowFields)->find()->toArray():false;
     }
 
     public function logout()
-    {
-        $this->adapter->logout();
+    {   
+        $adapter = new MysqlAdapter();
+        $adapter->logout();
     }
 
-    public function getToken()
-    {
-        $usertoken=$this->adapter->getUserToken();
-        return $usertoken->token;
+    public static function getToken($token):int
+    {   
+        $time=time();
+        return UserToken::where('token',$token)->where('expire','>',$time)->count();
     }
 
+    //登录
     public function login(string $username, string $password)
     {
-        $token=uuid();
+        $token= uuid();
         $user=User::where('username',$username)->find();
         if(!$user){
             throw new \Exception('账号或密码错误');
@@ -51,16 +51,20 @@ class ApiAuthService extends AuthService
         if($user->status!='normal'){
             throw new \Exception('账号已经被禁用');
         }
-        $this->adapter->login($token,$user);
-        $this->login_user=$this->adapter->userinfo();
+
+        $adapter = new MysqlAdapter();
+        $token = $adapter->login($token,$user);
+        $this->login_user=$adapter->userinfo();
+        return ['userinfo' => $this->login_user, 'token' => $token];
     }
 
+
     public function loginByMobile(string $mobile, string $code)
     {
         // TODO: Implement loginByMobile() method.
     }
 
-
+ 
     public function updateToken(array $arr)
     {
         $usertoken=$this->adapter->getUserToken();

+ 0 - 25
app/api/service/auth/Adapter.php

@@ -1,25 +0,0 @@
-<?php
-declare(strict_types=1);
-namespace app\api\service\auth;
-use app\common\model\User;
-use app\common\model\UserToken;
-
-interface Adapter{
-    /**
-     * 获取用户信息
-     */
-    public function userinfo():array|bool;
-
-    /**
-     * 获取用户token
-     */
-    public function getUserToken():UserToken|false;
-    /**
-     * 退出登录
-     */
-    public function logout();
-    /**
-     * 登录
-     */
-    public function login(string $token,User $user);
-}

+ 12 - 30
app/api/service/auth/MysqlAdapter.php

@@ -2,38 +2,16 @@
 declare(strict_types=1);
 namespace app\api\service\auth;
 
-
+use think\facade\Cookie;
 use app\common\model\UserToken;
 use app\common\model\User;
 use think\facade\Config;
 
-class MysqlAdapter implements Adapter
+class MysqlAdapter 
 {
     private UserToken $usertoken;
 
-    public function __construct(string $token=null)
-    {
-        if(!$token){
-            return;
-        }
-        $time=time();
-        $usertoken=UserToken::where(function ($query) use ($token,$time){
-            $token=md5($token);
-            $query->where('token','=',$token);
-            $query->where('expire','>',$time);
-        })->withJoin('user','right')->find();
-        if($usertoken){
-            $auth=Config::get('site.auth');
-            //当登陆时间小于保持登陆时间的一半时,自动续时
-            if($auth['keepalive'] && $usertoken->expire-$time<$auth['keepalive_time']/2){
-                $usertoken->expire=$time+$auth['keepalive_time'];
-                $usertoken->save();
-            }
-            $usertoken->token=$token;
-            $this->usertoken=$usertoken;
-        }
-    }
-
+ 
     public function userinfo():array|false
     {
         if(isset($this->usertoken)){
@@ -52,15 +30,16 @@ class MysqlAdapter implements Adapter
 
     public function login(string $token,User $user)
     {
-        $keepalive_time=Config::get('site.auth.keepalive_time');
+        $keepalive_time=Config::get('app.auth.keepalive_time');
+        $token = md5($token);
         $this->usertoken=UserToken::create([
-            'token'=>md5($token),
-            'user_id'=>$user->id,
-            'expire'=>time()+$keepalive_time
+            'token'  => $token,
+            'user_id'=> $user->id,
+            'expire' => time()+$keepalive_time
         ]);
         $this->usertoken->token=$token;
         $this->usertoken->user=$user;
-        $allow_device_num=Config::get('site.auth.allow_device_num');
+        $allow_device_num=Config::get('app.auth.allow_device_num');
         //如果数据库中保存的设备数大于允许的设备数,如果超出则挤出去最早登陆的设备
         $time=time();
         $count=UserToken::where('user_id',$user->id)->where('expire','>',$time)->count();
@@ -68,10 +47,13 @@ class MysqlAdapter implements Adapter
             $usertoken=UserToken::where('user_id',$user->id)->where('expire','>',$time)->order('id','asc')->find();
             $usertoken->delete();
         }
+        Cookie::set('token', $token ,$keepalive_time);
+        return $token;
     }
 
     public function logout()
     {
         UserToken::where('token',$this->usertoken->token)->delete();
+        Cookie::delete('token');
     }
 }

+ 0 - 68
app/api/service/msg/WechatMsg.php

@@ -1,68 +0,0 @@
-<?php
-declare(strict_types=1);
-namespace app\api\service\msg;
-
-use app\common\model\MpSubscribe;
-use app\common\model\Third;
-use app\common\service\MsgService;
-use app\common\model\Msg;
-
-class WechatMsg extends MsgService{
-
-    protected $msg_type='wechat';
-
-    //模板列表
-    const 模拟模板='111111111111111111111111111111111111';
-
-    protected function sendEvent(Msg $msg): bool
-    {
-        $config=[
-            'appid'=>site_config("weichat.mp_appid"),
-            'appsecret'=>site_config("weichat.mp_secret"),
-        ];
-        // 实例接口
-        $wechat = new \WeChat\Template($config);
-        // 执行操作
-        try{
-            $wechat->send(json_decode($msg->content,true));
-            return true;
-        }catch (\Exception $e){
-            $this->error=$e->getMessage();
-            return false;
-        }
-    }
-
-
-    public static function testMsg($user_id)
-    {
-        $openid=self::getUserMpOpenid($user_id);
-        if(!$openid){
-            return;
-        }
-        $postdata=[
-            'touser'=>$openid,
-            'template_id'=>self::模拟模板,
-            //跳转到h5首页
-            //'url'=>request()->domain().'/h5/#/pages/index/index',
-            //跳转到小程序
-            'miniprogram'=>[
-                'appid'=>site_config("uniapp.miniapp_id"),
-                'pagepath'=>'/pages/index/index',
-            ],
-            'data'=>[
-                'thing1'=>['value'=>'测试1'],
-                'thing2'=>['value'=>'测试2'],
-            ]
-        ];
-        $postdata=json_encode($postdata,JSON_UNESCAPED_UNICODE);
-        $service=self::newInstance();
-        $service->create($postdata,$user_id);
-    }
-
-    private static function getUserMpOpenid($user_id)
-    {
-        $unionid=Third::where(['user_id'=>$user_id])->value('unionid');
-        $openid=MpSubscribe::where(['unionid'=>$unionid])->value('openid');
-        return $openid;
-    }
-}

+ 25 - 0
app/api/validate/User.php

@@ -0,0 +1,25 @@
+<?php
+namespace app\api\validate;
+
+use think\Validate;
+
+class User extends Validate
+{
+    protected $rule =   [
+        'username'  => 'require|max:25',
+        'password'  => 'require|length:6,32',
+        'email' => 'email',    
+    ];
+    
+    protected $message  =   [
+        'name'      => '名称必须',
+        'password'  => '密码长度只能在6-32之间',
+        'email'        => '邮箱格式错误',    
+    ];
+
+
+ 
+    protected $scene = [
+        'login'  =>  ['name','password'],
+    ]; 
+}

+ 20 - 0
app/common/controller/BaseController.php

@@ -67,6 +67,16 @@ class BaseController
         $this->result($msg,$data,1,$type);
     }
 
+     /**
+     * 返回Json成功的操作
+     * @param string $msg
+     * @param mixed|null $data
+     */
+    protected function jsonSuccess(string $msg='',mixed $data=null)
+    {
+        return json(['code' => 1,'msg' => 1111, 'data' => $data]);
+    }
+
     /**
      * 返回失败的操作
      * @param string $msg
@@ -81,6 +91,16 @@ class BaseController
         $this->result($msg,$data,0,$type);
     }
 
+    /**
+     * 返回Json成功的操作
+     * @param string $msg
+     * @param mixed|null $data
+     */
+    protected function jsonError(string $msg='',mixed $data=null)
+    {
+        return json(['code' => 0,'msg' => $msg, 'data' => $data]);
+    }
+
     /**
      * 返回请求结果,当ajax请求时返回json,其他请求时返回html
      * @param string      $msg     提示消息

+ 11 - 0
config/app.php

@@ -31,6 +31,17 @@ return [
     // 显示错误信息
     'show_error_msg'   => false,
 
+    // 第三方服务
+    'auth'=>[
+          //允许同时在线的设备数量
+         'allow_device_num'=>10,
+          //使用期间自动续时
+         'keepalive'=>true,
+          //保持登陆时间,单位秒
+         'keepalive_time'=>24*3600*30,
+         //用户信息保存适配器,更换适配器需要实现app\api\service\auth\Adapter接口
+         'adapter'=>app\api\service\auth\MysqlAdapter::class,
+    ],
     //平台配置
     'platform_list'              => [
         '1' => '抖音',

+ 4 - 2
route/route.php

@@ -6,7 +6,9 @@ use think\facade\Route;
 //员工端
 Route::group('/user/api', function () {
 
-      //News/update
-      Route::get('hello', 'Index@hello');
+      //登录
+      Route::post('login', 'User@login');
+      Route::post('userinfo', 'User@userinfo');
+      
       //->controller('api/Index','hello');
 })->namespace('app\api\controller');