소스 검색

no message

panghu 1 년 전
부모
커밋
eb4d544909

+ 5 - 0
app/Http/Kernel.php

@@ -2,6 +2,7 @@
 
 namespace App\Http;
 
+use App\Http\Middleware\AdminApiAuthMiddleware;
 use Illuminate\Foundation\Http\Kernel as HttpKernel;
 
 class Kernel extends HttpKernel
@@ -43,6 +44,10 @@ class Kernel extends HttpKernel
             'throttle:api',
             \Illuminate\Routing\Middleware\SubstituteBindings::class,
         ],
+        //前后端分离后 后台验证
+        'adminApi_verify'=>[
+            AdminApiAuthMiddleware::class
+        ],
     ];
 
     /**

+ 78 - 0
app/Http/Middleware/AdminApiAuthMiddleware.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Models\User;
+use App\Servers\AdminLogsServer;
+use App\Servers\PermissionServer;
+use App\Servers\RedisDataServer;
+use Closure;
+
+class AdminApiAuthMiddleware
+{
+    private $noAuth = [
+        'adminApi.token',
+        'adminApi.index',
+        'adminApi.login',
+        'adminApi.logout',
+        'adminApi.check_code',
+        'adminApi.reset',
+        'common.send',
+    ];
+    /**
+     * Handle an incoming request.
+     *
+     * @param \Illuminate\Http\Request $request
+     * @param \Closure $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $clientRoute = request()->route()->getName();//获取当前路由
+
+        if (in_array($clientRoute, $this->noAuth)) {//不需要验证的路由
+            return $next($request);
+        }
+        //获取token
+        $api_token = $request->input('api_token');
+        if(empty($api_token))$api_token=$request->header('ApiToken');
+
+        if(empty($api_token)){
+            return response()->json([
+                'msg'   => '缺少认证信息',
+                'code'  => 401,
+                'data' => []
+            ]);
+        }
+        //获取当前用户
+        $user = RedisDataServer::creatServer()->getData( 'adminApiLogin_' . $api_token, 'json');
+        if(!$user){
+            //数据库查找当前用户
+            $user=User::where('api_token',$api_token)->where('status',1)->where('is_del',0)->first();
+            if($user){
+                //用户信息缓存
+                RedisDataServer::creatServer()->setData('adminApiLogin_' . $api_token, $user, 'json', 30);
+            }else{
+                return response()->json([
+                    'msg'   => '请先登录',
+                    'code'  => 401,
+                    'data' => []
+                ]);
+            }
+
+        }
+        //进行路由验证
+        $ret = PermissionServer::verifyAuth($user['roles_id'], $clientRoute);
+        if (empty($ret) && $user['id'] != 1) {
+            return response()->json([
+                'msg'   => '暂无权限',
+                'code'  => 402,
+                'data' => []
+            ]);
+        }
+        $request->admin_user = $user;
+        //日志记录
+        AdminLogsServer::write('',$user['id']);
+        return $next($request);
+    }
+}

+ 45 - 0
app/Models/AdminLog.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class AdminLog.
+ *
+ * @package namespace App\Models;
+ * @property int $id
+ * @property int $m_id
+ * @property string $url 请求路由
+ * @property string $msg 说明
+ * @property string $ip 请求IP
+ * @property string $data 请求参数
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog query()
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereData($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereIp($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereMId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereMsg($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereUpdatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|AdminLog whereUrl($value)
+ * @mixin \Eloquent
+ */
+class AdminLog extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 45 - 0
app/Models/Config.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class Config.
+ *
+ * @package namespace App\Models;
+ * @property int $id
+ * @property string $key 配置名称
+ * @property string $msg 配置说明
+ * @property string $value 配置值
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @method static \Illuminate\Database\Eloquent\Builder|Config newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Config newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Config query()
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereKey($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereMsg($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereUpdatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereValue($value)
+ * @mixin \Eloquent
+ * @property int|null $is_update 是否可以修改
+ * @property string|null $title 标题
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereIsUpdate($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Config whereTitle($value)
+ */
+class Config extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 41 - 0
app/Models/ErrorRecord.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class ErrorRecord.
+ *
+ * @package namespace App\Models;
+ * @property int $id
+ * @property string $msg 错误说明
+ * @property string $data 相关信息
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord query()
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereData($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereMsg($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereUpdatedAt($value)
+ * @mixin \Eloquent
+ * @property int|null $m_id 会员ID
+ * @method static \Illuminate\Database\Eloquent\Builder|ErrorRecord whereMId($value)
+ */
+class ErrorRecord extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 55 - 0
app/Models/Menu.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class Menu.
+ *
+ * @package namespace App\Models;
+ * @property int $id
+ * @property string $menu_name 菜单名称
+ * @property int $p_id 父级菜单ID
+ * @property int $level 级别
+ * @property string $url_ids 菜单路由ID
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @property string|null $label_name 标签名称
+ * @property string|null $url_name 绑定连接
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu query()
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereLabelName($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereLevel($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereMenuName($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu wherePId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereUpdatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereUrlIds($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereUrlName($value)
+ * @mixin \Eloquent
+ * @property string $p_ids 父级菜单族谱
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu wherePIds($value)
+ * @property int|null $sort 排序
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereSort($value)
+ * @property int|null $version 版本 1旧版 2新版
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereVersion($value)
+ * @property int|null $is_del
+ * @method static \Illuminate\Database\Eloquent\Builder|Menu whereIsDel($value)
+ */
+class Menu extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 43 - 0
app/Models/Region.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class Region.
+ *
+ * @package namespace App\Models;
+ * @method static \Illuminate\Database\Eloquent\Builder|Region newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Region newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Region query()
+ * @mixin \Eloquent
+ * @property int $id
+ * @property string $name 城市名称
+ * @property int $level 城市层级
+ * @property int $parent_id 父级ID
+ * @property string $p_ids 族谱
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereLevel($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereName($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region wherePIds($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereParentId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Region whereUpdatedAt($value)
+ */
+class Region extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 47 - 0
app/Models/Role.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Prettus\Repository\Contracts\Transformable;
+use Prettus\Repository\Traits\TransformableTrait;
+
+/**
+ * Class Role.
+ *
+ * @package namespace App\Models;
+ * @property int $id
+ * @property string $role_name 角色名称
+ * @property int $status 状态,0:关闭,1:开启
+ * @property string $permission_ids 拥有的权限ID
+ * @property \Illuminate\Support\Carbon|null $created_at
+ * @property \Illuminate\Support\Carbon|null $updated_at
+ * @method static \Illuminate\Database\Eloquent\Builder|Role newModelQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Role newQuery()
+ * @method static \Illuminate\Database\Eloquent\Builder|Role query()
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereCreatedAt($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereId($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Role wherePermissionIds($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereRoleName($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereStatus($value)
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereUpdatedAt($value)
+ * @mixin \Eloquent
+ * @property string $name 角色名称
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereName($value)
+ * @property string|null $role_p_ids
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereRolePIds($value)
+ * @property int|null $is_del 是否删除 0否 1是
+ * @method static \Illuminate\Database\Eloquent\Builder|Role whereIsDel($value)
+ */
+class Role extends Model implements Transformable
+{
+    use TransformableTrait;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+}

+ 35 - 0
app/Servers/AdminLogsServer.php

@@ -0,0 +1,35 @@
+<?php
+
+
+namespace App\Servers;
+
+
+use App\Models\AdminLog;
+
+class AdminLogsServer
+{
+
+
+    /**
+     * 后台日志记录
+     * @param string $msg
+     * @return AdminLog|\Illuminate\Database\Eloquent\Model
+     */
+    static public function write($msg='')
+    {
+        $user = app('auth')->user();
+        $m_id=empty($user->{'id'})?0:$user->{'id'};
+        $url = request()->url();
+        $data=request()->all();
+        $ip=CommonServer::creatServer()->getClientIp();
+        return AdminLog::create(
+            [
+                'm_id' => $m_id,
+                'url' => $url,
+                'msg' => $msg,
+                'ip' => $ip,
+                'data' => http_build_query($data),
+            ]
+        );
+    }
+}

+ 693 - 0
app/Servers/CommonServer.php

@@ -0,0 +1,693 @@
+<?php
+
+
+namespace App\Servers;
+
+use AlibabaCloud\Client\AlibabaCloud;
+use AlibabaCloud\Ecs\Ecs;
+use AlibabaCloud\Green\Green;
+use App\Models\Config;
+use App\Models\ErrorRecord;
+use App\Models\Region;
+use Illuminate\Support\Facades\Storage;
+use AlibabaCloud\Client\Exception\ClientException;
+use AlibabaCloud\Client\Exception\ServerException;
+use QCloud\COSSTS\Sts;
+
+
+/**
+ * Redis数据缓存类
+ */
+class CommonServer
+{
+
+    /**
+     * 错误信息
+     * @var string
+     */
+    private $errorMsg = '';
+
+    static private $server = null;
+
+
+    private function __construct()
+    {
+
+    }
+
+    /**
+     * 创建对象
+     * @return CommonServer
+     */
+    static function creatServer()
+    {
+        if (empty(self::$server)) self::$server = new CommonServer();
+        return self::$server;
+    }
+
+    /**
+     * 验证手机号码格式
+     * @param $phone
+     * @return bool
+     */
+    public function verifyPhoneNumber($phone)
+    {
+        if (empty($phone)) return false;
+        if (!preg_match('#^[\d]{11,11}$#', $phone)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 字符串去标签过滤及空格过滤
+     * @param $str_name
+     * @param $default
+     * @return string
+     */
+    function filtrationStr($str_name, $default = '')
+    {
+        $str = request()->input($str_name, $default);
+        if (empty($str)) return $str;
+        if (!is_string($str)) {
+            $str = json_encode($str);
+            $str = strip_tags($str);
+            $str = trim($str);
+            $str = json_decode($str, true);
+        } else {
+            $str = strip_tags($str);
+            $str = trim($str);
+        }
+        return $str;
+    }
+
+    /**
+     * 获取城市名称
+     * @param string $province_id
+     * @param string $city_id
+     * @param string $area_id
+     * @return string
+     */
+    function getCityName($province_id = '', $city_id = '', $area_id = '')
+    {
+        $ids = [$province_id, $city_id, $area_id];
+        $ids = array_filter($ids);
+        if (empty($ids)) return '';
+        $city_name = Region::whereIn('id', $ids)->orderBy('id', 'asc')->pluck('name')->toArray();
+        $city_name = implode(' ', $city_name);
+        return $city_name;
+
+    }
+
+
+    /**
+     * 字符串屏蔽
+     * @param $str
+     * @param int $start_key 开始位置
+     * @param int $end_key 尾数开始位置
+     * @param int $start_num 截取位数
+     * @param int $end_num 倒数截取位数
+     * @param int $conceal_num 最大填充数量
+     * @return string
+     */
+    function concealStr($str, $start_key = 0, $end_key = 1, $start_num = 1, $end_num = 1, $conceal_num = 3)
+    {
+        $str_len = mb_strlen($str);
+
+        $start_str = '';
+        $end_str = '';
+        if (($str_len - $start_num - $end_num) < $conceal_num) {
+            $conceal_num = $str_len - $start_num - $end_num;
+        }
+        $conceal_str = $this->getRandChar($conceal_num, '*');
+        if (empty($conceal_str)) $conceal_str = '*';
+        if ($str_len >= $start_key) {
+            $start_str = mb_substr($str, $start_key, $start_num);
+        }
+        if ($str_len > $end_key) {
+            $end_str = mb_substr($str, $end_key * -1, $end_num);
+        }
+        return $start_str . $conceal_str . $end_str;
+    }
+
+
+    /**
+     * 获取随机字符串
+     * @param int $length
+     * @param string $strPol
+     * @return string|null
+     */
+    public function getRandChar($length = 6, $strPol = '')
+    {
+        if ($length <= 0) $length = 1;
+        $str = null;
+        if (empty($strPol)) $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
+        $max = strlen($strPol) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $str .= $strPol[rand(0, $max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
+        }
+        return $str;
+    }
+
+    /**
+     * 获取数据库配置信息
+     * @param $key
+     * @return mixed
+     */
+    function getConfigValue($key)
+    {
+        return Config::where('key', $key)->value('value');
+    }
+
+    /**
+     * 创建文件夹
+     * @param $dir
+     * @return bool
+     */
+    function creatDir($dir)
+    {
+        if ($dir == '') return false;
+        if (!file_exists(public_path($dir))) {
+            mkdir(public_path($dir), 0777, true);
+            chmod(public_path($dir), 0777);
+        }
+        return true;
+    }
+
+    /**
+     * 获取本月1号至月底
+     * @param $date
+     * @return array
+     */
+    function getNextMonth($date)
+    {
+        $first_day = date("Y-m-01 00:00:00", strtotime($date));
+        $next_day = date("Y-m-d 23:59:59", strtotime("$first_day +1 month  -1 day"));
+        return [$first_day, $next_day];
+    }
+
+
+    /**
+     * 获取多少天后的日期
+     * @param $date
+     * @param $num
+     * @return false|string
+     */
+    function getManyDate($date, $num)
+    {
+        if(!is_numeric($num) || $num==0){
+            return $date;
+        }
+        if($num>0){
+            $next_day = date("Y-m-d", strtotime("$date +$num day"));
+        }else{
+            $next_day = date("Y-m-d", strtotime("$date $num day"));
+        }
+        return $next_day;
+    }
+
+
+    /**
+     * 验证是否微信浏览器
+     * @return bool
+     */
+    function isWeixin()
+    {
+        $http_user_agent = request()->header('user-agent');
+        if (strpos($http_user_agent, 'MicroMessenger') !== false) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 格式化小数位数
+     * @param $num
+     * @param int $digit
+     * @return string
+     */
+    function setFloatNum($num, $digit = 4)
+    {
+        return sprintf("%.{$digit}f", $num);
+    }
+
+    /**
+     * 获取真实IP
+     * @return mixed
+     */
+    function getClientIp()
+    {
+        $http_x_forwarded_for = request()->header('x-forwarded-for');
+        if (empty($http_x_forwarded_for)) {
+            return request()->getClientIp();
+        } else {
+            $http_x_forwarded_for = explode(',', $http_x_forwarded_for);
+            return $http_x_forwarded_for[0];
+        }
+    }
+
+
+    function delDir($dir)
+    {
+        //先删除目录下的文件:
+        $dh = opendir($dir);
+        while ($file = readdir($dh)) {
+            if ($file != "." && $file != "..") {
+                $fullpath = $dir . "/" . $file;
+                if (!is_dir($fullpath)) {
+                    unlink($fullpath);
+                } else {
+                    $this->deldir($fullpath);
+                }
+            }
+        }
+
+        closedir($dh);
+        //删除当前文件夹:
+        if (rmdir($dir)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 图片base64
+     * @param $image_file
+     * @return string
+     */
+    function base64EncodeImage($image_file)
+    {
+        $image_info = getimagesize($image_file);
+        $image_data = fread(fopen($image_file, 'r'), filesize($image_file));
+        $base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
+        return $base64_image;
+    }
+
+
+    /**
+     * 图片上传OSS
+     * @param $img
+     * @param string $path
+     * @param $is_compress
+     * @return string
+     */
+    function uploadingImg($img, $path = 'headimgurl',$is_compress=true)
+    {
+        $base64_image_content = file_get_contents($img);
+        $upload_path = "storage" . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . date('Ymd', time()) . DIRECTORY_SEPARATOR;
+        $img_url = md5(uniqid() . time()) . '.png';
+        $upload_path1 = public_path($upload_path);
+        if (!is_dir($upload_path1)) {
+            mkdir($upload_path1, 0777, true);
+        }
+        $oss = Storage::disk('oss');
+        $pathA = "{$upload_path}{$img_url}";
+        $update = $oss->put($pathA, $base64_image_content);
+        if (!$update) { // 如果失败上传本地
+            file_put_contents($upload_path1 . $img_url, base64_decode($base64_image_content));
+        }
+        return $update ? ($oss->url($pathA) . ($is_compress?'?x-oss-process=image/auto-orient,1/quality,q_85':'')) : asset($pathA);
+    }
+
+    /**
+     * OSS图片压缩
+     * @param $img
+     * @param int $resize (3,10,30,50)
+     * @param int $type 1原比例压缩,2固定高宽比列压缩(300*300)
+     * @return string|string[]
+     */
+    function ossCompress($img, $resize = 10, $type = 1)
+    {
+        $old_str=strrchr($img, '?');
+        if($old_str)$img=str_replace($old_str, '', $img);
+        if ($type == 1) {
+            return $img . '?x-oss-process=image/auto-orient,1/resize,p_' . $resize . '/quality,q_90';
+        } elseif ($type == 2) {
+            return $img . '?x-oss-process=image/auto-orient,1/resize,m_fill,w_300,h_300/quality,q_90';
+        } elseif ($type == 3) {
+            return $img . '?x-oss-process=image/auto-orient,1/resize,m_lfit,w_780/quality,q_100';
+        }
+        return $img;
+    }
+
+    /**
+     * 保留2为小数
+     * @param $num
+     * @param int $format_num
+     * @return float|int
+     */
+    function setFormatNum($num,$format_num=2){
+//        return  $num;
+        $format_num=4;
+        if(!is_numeric($num)){
+            return 0;
+        }
+        if($format_num<0){
+            return  $num;
+        }elseif ($format_num==0){
+            return  floor($num);
+        }else{
+            $num= sprintf("%.{$format_num}f", $num);
+//            $multiple=pow(10,$format_num);
+//            $num = floor($num*$multiple)/$multiple;
+        }
+        $num=$num*1;
+        return  $num;
+    }
+
+
+    /**
+     * oss图片删除
+     * @param $path
+     * @return bool
+     */
+    function delImg($path)
+    {
+        $path_num = stripos($path, '?');
+        if ($path_num !== false) {
+            $path = substr($path, 0, $path_num);
+        }
+        $path = str_replace('https://jhnewshop.oss-cn-chengdu.aliyuncs.com', '', $path);
+        $oss = Storage::disk('oss');
+        $update = $oss->delete($path);
+        return $update;
+    }
+
+    /**
+     * 获取阿里云sts临时权限
+     */
+    function getAliSts()
+    {
+        $data = RedisDataServer::creatServer()->getData('sts_data');
+        if ($data) {
+            $data = json_decode($data, true);
+        } else {
+            $accessKeyId = env('ALI_OSS_ACCESS_ID');
+            $accessSecret = env('ALI_OSS_ACCESS_KEY');
+            AlibabaCloud::accessKeyClient($accessKeyId, $accessSecret)->regionId('cn-hangzhou')->asDefaultClient();
+            //设置参数,发起请求。
+            try {
+                $result = AlibabaCloud::rpc()
+                    ->product('Sts')
+                    ->scheme('https') // https | http
+                    ->version('2015-04-01')
+                    ->action('AssumeRole')
+                    ->method('POST')
+                    ->host('sts.aliyuncs.com')
+                    ->options([
+                        'query' => [
+                            'RegionId' => "cn-chengdu",
+                            'RoleArn' => "acs:ram::1470797691368660:role/oss-js",
+                            'RoleSessionName' => "js-oss-serve",
+                            'DurationSeconds' => 900,
+                        ],
+                    ])
+                    ->request();
+                $result = $result->toArray();
+                if (empty($result['Credentials'])) {
+                    return ['code' => 0, 'msg' => '获取token信息失败'];
+                }
+                $data = $result['Credentials'];
+                unset($data['Expiration']);
+                RedisDataServer::creatServer()->setData('sts_data', $data, 'json', 800);
+            } catch (ClientException $e) {
+                return ['code' => 0, 'msg' => $e->getErrorMessage()];
+            } catch (ServerException $e) {
+                return ['code' => 0, 'msg' => $e->getErrorMessage()];
+            }
+        }
+        return ['code' => 1, 'msg' => '获取信息成功', 'data' => $data];
+
+    }
+
+
+    function getTxySts(){
+        $data = RedisDataServer::creatServer()->getData('txy_sts_data');
+        if ($data ) {
+            $data = json_decode($data, true);
+        } else {
+            $sts = new Sts();
+            $accessKeyId = env('TXY_OSS_ACCESS_ID');
+            $accessSecret = env('TXY_OSS_ACCESS_KEY');
+            $config = array(
+                'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
+                'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
+                'proxy' => '',
+                'secretId' => $accessKeyId, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
+                'secretKey' => $accessSecret, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
+                'bucket' => 'wealfavor-1257406827', // 换成你的 bucket
+                'region' => 'ap-beijing', // 换成 bucket 所在园区
+                'durationSeconds' => 1800, // 密钥有效期
+                'allowPrefix' => 'app-serve/*', // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
+                // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
+                'allowActions' => array (
+                    // 简单上传
+                    'name/cos:PutObject',
+                    'name/cos:PostObject',
+                    // 分片上传
+                    'name/cos:InitiateMultipartUpload',
+                    'name/cos:ListMultipartUploads',
+                    'name/cos:ListParts',
+                    'name/cos:UploadPart',
+                    'name/cos:CompleteMultipartUpload'
+                )
+            );
+//            dd($config);
+            try {
+                $result = $sts->getTempKeys($config);
+                if(empty($result['credentials'])){
+                    return ['code' => 0, 'msg' => '权限生成失败'];
+                }
+                $data = $result['credentials'];
+                $data['StartTime']=time();
+                $data['ExpiredTime']=time()+1700;
+                RedisDataServer::creatServer()->setData('txy_sts_data', $data, 'json', 800);
+            } catch (\Exception $e) {
+                return ['code' => 0, 'msg' => $e->getMessage()];
+            }
+
+
+        }
+        return ['code' => 1, 'msg' => '获取信息成功', 'data' => $data];
+    }
+
+    /**
+     * 阿里云图片鉴定
+     * @param $imges
+     * @return array|bool
+     * @throws ClientException
+     * @throws ServerException
+     */
+    function sendAliImgAuth($imges)
+    {
+        if (is_string($imges)) $imges = [$imges];
+        $tasks = [];
+        $auth_status = 1;
+        foreach ($imges as $key => $img) {
+            $tasks[] = [
+                'dataId' => $key . '-img' . rand(10000000, 99999999) . '-' . time(),
+                'url' => $img,
+                'status' => 0,
+            ];
+        }
+        $accessKeyId = env('ALI_OSS_ACCESS_ID');
+        $accessSecret = env('ALI_OSS_ACCESS_KEY');
+        AlibabaCloud::accessKeyClient($accessKeyId, $accessSecret)->regionId('cn-shanghai')->asDefaultClient();
+        $request = Green::v20180509()->ImageSyncScan();
+        $request->method('POST')
+            ->scheme('https') // https | http
+            ->body(json_encode([
+                'scenes' => ['porn', 'terrorism'],
+                'tasks' => $tasks,
+            ]));
+        $ret = $request->request();
+        $ret_data = $ret->toArray();
+        if (empty($ret_data['code']) || $ret_data['code'] != 200) {
+            return $auth_status;
+        } else {
+            foreach ($ret_data['data'] as $key => $item) {
+                $status = 1;
+                if ($auth_status != 1) {
+                    break;
+                }
+                foreach ($item['results'] as $value) {
+                    if ($value['suggestion'] == 'review') {
+                        $status = 0;
+                        $auth_status = 0;
+                        break;
+                    } elseif ($value['suggestion'] == 'block') {
+                        $status = 2;
+                        $auth_status = 2;
+                        break;
+                    }
+                }
+                $tasks[$key]['status'] = $status;
+            }
+        }
+        return ['auth_status' => $auth_status, 'tasks' => $tasks];
+
+    }
+
+    /**
+     * 阿里云视频鉴定
+     * @param $video 视频地址
+     * @param int $type 鉴定类型
+     * @param int $id 任务ID
+     * @return bool
+     * @throws ClientException
+     * @throws ServerException
+     */
+    function sendAliVideoAuth($video, $type = 1, $id = 0)
+    {
+        $tasks = [
+            [
+                'dataId' => $id . '-video' . rand(10000000, 99999999) . '-' . time(),
+                'url' => $video,
+                'interval' => 5,
+            ]
+        ];
+        $accessKeyId = env('ALI_OSS_ACCESS_ID');
+        $accessSecret = env('ALI_OSS_ACCESS_KEY');
+        AlibabaCloud::accessKeyClient($accessKeyId, $accessSecret)->regionId('cn-shanghai')->asDefaultClient();
+        $request = Green::v20180509()->videoAsyncScan();
+        $request->method('POST')
+            ->scheme('https') // https | http
+            ->body(json_encode([
+                'callback' => route('notify.video-auth', ['type' => $type, 'id' => $id]),
+                'seed' => $id . '-video' . rand(10000000, 99999999),
+                'scenes' => ['porn', 'terrorism'],
+                'tasks' => $tasks,
+            ]));
+        $ret = $request->request();
+        $ret_data = $ret->toArray();
+        if (empty($ret_data['code']) || $ret_data['code'] != 200) {
+            ErrorRecord::create(['msg' => '视频鉴定任务提交失败', 'data' => json_encode(compact('id', 'type', 'video'))]);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 获取文件名
+     * @param $url
+     * @return string
+     */
+    function getFileName($url)
+    {
+        $name = basename($url);
+        return empty($name) ? '' : $name;
+    }
+
+
+    function lockCapitalRoutes($mId,$routeName,$type){
+        $routeArr=   [
+            'rush.session-pay',
+            'rush.order-pay',
+            'rush.putaway-goods',
+            'change.save',//划转
+            'dealOrder.create',//转赠
+            'member.set_wallet',//修改钱包地址
+            'order.create',//商城购买
+            'order.pay',//商城支付
+            'recharge.save',//充值提交
+            'withdraw.withdraw',//提现
+        ];
+        if(in_array($routeName,$routeArr)){
+            $redisName=$mId.'lockCapital';
+            if($type){
+                $row=  RedisDataServer::creatServer()->getData($redisName);
+                $isOutput=  RedisDataServer::creatServer()->getData('dateOutput');
+                if($row || $isOutput){
+                    return false;
+                }
+                RedisDataServer::creatServer()->setData($redisName,time(),'str',3,false);
+            }else{
+                RedisDataServer::creatServer()->delData($redisName);
+            }
+        }
+        return true;
+    }
+
+    //两个经纬度直接距离
+    function getDistance($lat1, $lng1, $lat2, $lng2){
+
+        $lat1 = ($lat1 * pi() ) / 180;
+        $lng1 = ($lng1 * pi() ) / 180;
+
+        $lat2 = ($lat2 * pi() ) / 180;
+        $lng2 = ($lng2 * pi() ) / 180;
+
+        $calcLongitude = $lng2 - $lng1;
+        $calcLatitude = $lat2 - $lat1;
+        $dist = 2 * asin(sqrt(pow(sin($calcLatitude/2),2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude/2),2)));
+        $dist = $dist * 6378.137;
+        return round($dist, 2);
+    }
+
+    function utf8_filter($str)
+    {
+
+        $pattern = '/[^\x{4e00}-\x{9fa5}\w]/u';
+        // 使用正则表达式替换为空字符串
+        $data = preg_replace($pattern, '', $str);
+        return $data;
+    }
+
+
+    static function writeLog($text,$path='comm') {
+        if(is_array($text) || is_object($text)){
+            $text = json_encode($text,JSON_UNESCAPED_SLASHES);
+        }
+        $logDir = public_path('/storage/log/'.$path.'/'.date('Ymd').'/')  ;
+        if(!is_dir($logDir)){
+            mkdir($logDir,0777,true);
+        }
+
+        file_put_contents ( $logDir.$path.date("Y-m-d").".log", date("Y-m-d H:i:s") . "  Log" . $text . "\r\n", FILE_APPEND );
+    }
+
+
+    /**
+     * @param $url
+     * @param string $type 请求方式
+     * @param string $data 数据 数组格式
+     * @param $head
+     * @param $retType
+     * @return mixed
+     */
+    function sendRequest($url, $data = '', $type = 'get',$head=[],$retType='json')
+    {
+
+        $ch = curl_init();
+        if ($type == 'get' && $data) {
+            $url = $url . '?' . http_build_query($data);
+        }
+        curl_setopt($ch, CURLOPT_URL, $url); //设置访问路径
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //设置可以返回字符串
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        if(empty($head)){
+            $head = [
+                'User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
+                'Content-Type: application/json'
+            ];
+        }
+
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $head);
+        if ($type == 'post') {
+            curl_setopt($ch, CURLOPT_POST, TRUE);//post请求
+            $data = json_encode($data, JSON_UNESCAPED_UNICODE);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置传递的参数
+        }
+        $request = curl_exec($ch);
+        curl_close($ch);
+        if($request){
+            if($retType=='gzip'){
+                $request=gzdecode($request);
+            }
+            $request=json_decode($request,true);
+        }
+        return $request;
+    }
+}

+ 146 - 0
app/Servers/MenuServer.php

@@ -0,0 +1,146 @@
+<?php
+
+
+namespace App\Servers;
+
+use App\Models\Menu;
+use App\Models\Role;
+
+
+/**
+ * Redis数据缓存类
+ */
+class MenuServer
+{
+    /**
+     * 单列对象
+     * @var
+     */
+    static $server;
+    /**
+     * 缓存key
+     * @var string
+     */
+    private $key_name = 'menu_list';
+    /**
+     * 缓存时间
+     * @var string
+     */
+    private $cache_time = '10';
+
+    private function __construct()
+    {
+
+    }
+
+    /**
+     * 创建对象
+     * @return MenuServer
+     */
+    static function creatServer()
+    {
+        if (empty(self::$server)) {
+            self::$server = new MenuServer();
+        }
+        return self::$server;
+    }
+
+    /**
+     * 获取后台菜单信息
+     * @param $roles_id
+     * @return array|mixed
+     */
+    function getMenu($roles_id)
+    {
+        $key_name = $this->key_name . '_' . $roles_id;
+        $list = RedisDataServer::creatServer()->getData($key_name, 'json');
+        if (empty($list)) {
+            if ($roles_id > 0) {
+                //获取对应角色授权ID
+                $permission_ids = Role::where('id', $roles_id)->value('permission_ids');
+                if (empty($permission_ids)) $permission_ids = [0];
+                else $permission_ids = explode(',', $permission_ids);
+            } else {
+                $permission_ids = [];
+            }
+            $list = Menu::where('p_id', 0)->where('is_del',0)->where('version',1)->where(function ($query) use ($permission_ids) {
+                if ($permission_ids) {
+                    $p_ids= Menu::whereIn('id', $permission_ids)->where('level',1)->pluck('p_id')->toArray();
+                    if(empty($p_ids))$p_ids=[0];
+                    $query->whereIn('id', $p_ids);
+                }
+            })->select(['id', 'menu_name', 'label_name'])->orderBy('sort','desc')->get()->toArray();
+            foreach ($list as &$item) {
+                $item['items'] = Menu::where('p_id', $item['id'])->where('is_del',0)->where('version',1)->where(function ($query) use ($permission_ids) {
+                    if ($permission_ids) $query->whereIn('id', $permission_ids);
+                })->select(['id', 'menu_name', 'url_name'])->orderBy('sort','desc')->get()->toArray();
+            }
+            RedisDataServer::creatServer()->setData($key_name, $list, 'json', $this->cache_time);
+        }
+        return $list;
+    }
+
+    /**
+     * 根据角色传递菜单信息
+     * @param $roles_id
+     */
+    function sendMenu($roles_id = '')
+    {
+        if (!request()->ajax()) {
+            view()->composer('layouts.admin.menu', function ($view) use ($roles_id) {
+                $menu_list = self::creatServer()->getMenu($roles_id);
+                $view->with('menu_list', $menu_list);
+            });
+        }
+
+    }
+
+
+    function getPermissionsMenu($r_p)
+    {
+        //当前角色已授权信息
+        if (is_string($r_p)) {
+            $r_p = explode(',', $r_p);
+        }
+        $permission=[];
+        //权限信息
+        $one_p = Menu::where('p_id', 0)->select(['id', 'menu_name as label'])->get();
+        foreach ($one_p as $key => $item) {
+            $item->{'id'}.='';
+            $two_list = Menu::where('p_id', $item['id'])->select(['id', 'menu_name as label'])->get();
+            foreach ($two_list as $t_v) {
+                $t_v->{'id'}.='';
+                $three_list= Menu::where('p_id', $t_v['id'])->select(['id', 'menu_name as label'])->get();
+                foreach ($three_list as $three_v){
+                    $three_v->{'id'}.='';
+                }
+                $t_v->{'children'}=$three_list->toArray();
+            }
+            $item->{'children'}=$two_list->toArray();
+            $permission[]=[$item->toArray()];
+        }
+        return $permission;
+
+    }
+
+    /**
+     * 获取系统后台角色对应权限节点
+     * @param $role_id
+     * @return false|mixed|string[]
+     */
+    function getRole($role_id){
+        //获取该角色的权限节点
+        $key_name = 'role_ids_' . $role_id;
+        $url_ids = RedisDataServer::creatServer()->getData($key_name,'json');
+
+        if(empty($url_ids)){
+            $permission_ids = Role::where('id', $role_id)->value('permission_ids');
+            $url_ids = explode(',', $permission_ids);
+            RedisDataServer::creatServer()->setData($key_name,$url_ids,'json',7200);
+        }
+        if (empty($url_ids)) {
+            return false;
+        }
+        return $url_ids;
+    }
+}

+ 50 - 0
app/Servers/PermissionServer.php

@@ -0,0 +1,50 @@
+<?php
+
+
+namespace App\Servers;
+
+use App\Models\Menu;
+
+
+/**
+ * 权限验证
+ */
+class PermissionServer
+{
+
+    /**
+     * 新版后台权限检查
+     * @param $role_id
+     * @param $clientRoute
+     * @return bool
+     */
+    public static function verifyAuth($role_id, $clientRoute){
+        $url_list = [
+            'common.total',
+            'common.sts',
+            'adminApi.shop.login_url',
+            'adminApi.user.get_menu',//前端登录后获取后台菜单权限id
+            'adminApi.statistics.count',//获取概览统计
+            'adminApi.statistics.curve',//获取曲线统计
+            'adminApi.statistics.pie_chart',//获取饼图统计
+            'adminApi.statistics.bar_chart',//获取柱状图统计
+            'adminApi.adopted.type',//认养类目
+        ];
+        if (in_array($clientRoute, $url_list)) {
+            return true;
+        }
+
+        $where = [['url_name',$clientRoute]];
+        $client_id = Menu::where($where)->value('id');
+        if (empty($client_id)) {
+            return false;
+        }
+        //获取该角色的权限节点
+        $url_ids = MenuServer::creatServer()->getRole($role_id);
+        if (empty($url_ids) || !in_array($client_id, $url_ids)) {
+            return false;
+        }
+        return true;
+    }
+
+}