cqpCow 1 год назад
Родитель
Сommit
fd6d9998e4

+ 58 - 0
app/Http/Controllers/Api/WxController.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Service\ConstructionService;
+use App\Service\Wx\WxEmployeeService;
+use Illuminate\Http\Request;
+
+class WxController extends BaseController
+{
+    public function setUser(Request $request)
+    {
+        $service = new WxEmployeeService();
+        list($status, $data) = $service->setUser($request->all());
+
+        if ($status) {
+            return $this->json_return(200, '', $data);
+        } else {
+            return $this->json_return(201, $data);
+        }
+    }
+
+    public function setMobile(Request $request)
+    {
+        $service = new WxEmployeeService();
+        list($status, $data) = $service->setMobile($request->all());
+
+        if ($status) {
+            return $this->json_return(200, '', $data);
+        } else {
+            return $this->json_return(201, $data);
+        }
+    }
+
+    public function login(Request $request)
+    {
+        $service = new WxEmployeeService();
+        list($status, $data) = $service->login($request->all());
+
+        if ($status) {
+            return $this->json_return(200, '', $data);
+        } else {
+            return $this->json_return(201, $data);
+        }
+    }
+
+    public function constructionList(Request $request){
+        $service = new ConstructionService();
+        $userData = $request->userData->toArray();
+        list($status,$data) = $service->constructionList($request->all(),$userData);
+
+        if($status){
+            return $this->json_return(200,'',$data);
+        }else{
+            return $this->json_return(201,$data);
+        }
+    }
+}

+ 59 - 0
app/Http/Middleware/CheckWx.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Model\WxEmployee;
+use App\Service\EmployeeService;
+use Closure;
+
+class CheckWx
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $data=$request->all();
+
+        if (!isset($data['openid'])) return response()->json(['code'=> 1,'msg'=>'缺少openid','data'=>null]);
+        $openid = $data['openid'];
+        //校验openid是否绑定
+        $employee = new WxEmployee();
+        $employee_id = $employee->where('openid',$openid)->value('employee_id');
+        if ($employee_id <= 0) return response()->json(['code'=> 1,'msg'=>'用户信息错误!','data'=>null]);
+
+        //校验用户
+        $service = new EmployeeService();
+        $checkResult = $service->checkUser($employee_id);
+        list($state, $data) = $checkResult;
+        if(! $state) return response()->json(['code'=> 1,'msg'=>$data,'data'=>null]);
+
+        //人员角色
+        $data['role'] = EmployeeService::getPersonRole($employee_id);
+        $return = EmployeeService::getLoginDepart($employee_id);
+        //所属部门
+        $data['rule_depart'] = $return[0] ?? [];
+        //顶级公司
+        $data['depart_top'] = $return[1] ?? [];
+        //部门对应的顶级公司
+        $data['depart_map'] = $return[2] ?? [];
+        //权限范围内的部门以及公司
+        $data['depart_range'] = $return[3] ?? [];
+        //是否有所有的部门权限
+        $data['is_all_depart'] = $return[4] ?? 0;
+        //总公司
+        $data['head'] = $return[5] ?? [];
+        //是否是总公司下的人
+        $data['is_behind_main'] = $return[6] ?? 0;
+        //是否库存校验
+        $data['is_check_stock'] = true;
+
+        $request->userData = $data;
+
+        return $next($request);
+    }
+}

+ 20 - 0
app/Model/WxEmployee.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 人员管理
+ * Class Unit
+ * @package App\Models
+ */
+class WxEmployee extends Model
+{
+    protected $table = "wx_employee"; //指定表
+    const CREATED_AT = 'crt_time';
+    const UPDATED_AT = 'upd_time';
+    protected $dateFormat = 'U';
+    const SPECIAL_ADMIN = 1;
+
+}

+ 9 - 0
app/Providers/RouteServiceProvider.php

@@ -46,6 +46,7 @@ class RouteServiceProvider extends ServiceProvider
 
         $this->mapWebRoutes();
 
+        $this->mapWxRoutes();
         //
     }
 
@@ -77,4 +78,12 @@ class RouteServiceProvider extends ServiceProvider
              ->namespace($this->namespace)
              ->group(base_path('routes/api.php'));
     }
+
+    protected function mapWxRoutes()
+    {
+        Route::prefix('wx')
+            ->middleware('api')
+            ->namespace($this->namespace)
+            ->group(base_path('routes/wx.php'));
+    }
 }

+ 134 - 0
app/Service/Wx/Service.php

@@ -0,0 +1,134 @@
+<?php
+
+namespace App\Service\Wx;
+
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Redis;
+
+
+/**
+ * 公用的公共服务
+ * @package App\Models
+ */
+class Service
+{
+
+    public $log;
+    public $total = 0;
+
+    public function __construct()
+    {
+
+    }
+
+
+
+
+
+    function curlOpen($url, $config = array())
+    {
+        $arr = array('post' => false,'referer' => $url,'cookie' => '', 'useragent' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; customie8)', 'timeout' => 100, 'return' => true, 'proxy' => '', 'userpwd' => '', 'nobody' => false,'header'=>array(),'gzip'=>true,'ssl'=>true,'isupfile'=>false,'returnheader'=>false,'request'=>'post');
+        $arr = array_merge($arr, $config);
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, $arr['return']);
+        curl_setopt($ch, CURLOPT_NOBODY, $arr['nobody']);
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+        curl_setopt($ch, CURLOPT_USERAGENT, $arr['useragent']);
+        curl_setopt($ch, CURLOPT_REFERER, $arr['referer']);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $arr['timeout']);
+
+
+        curl_setopt($ch, CURLOPT_HEADER, $arr['returnheader']);//��ȡheader
+        if($arr['gzip']) curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
+        if($arr['ssl'])
+        {
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        }
+        if(!empty($arr['cookie']))
+        {
+            curl_setopt($ch, CURLOPT_COOKIEJAR, $arr['cookie']);
+            curl_setopt($ch, CURLOPT_COOKIEFILE, $arr['cookie']);
+        }
+
+        if(!empty($arr['proxy']))
+        {
+            //curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+            curl_setopt ($ch, CURLOPT_PROXY, $arr['proxy']);
+            if(!empty($arr['userpwd']))
+            {
+                curl_setopt($ch,CURLOPT_PROXYUSERPWD,$arr['userpwd']);
+            }
+        }
+
+        //ip�Ƚ����⣬�ü�ֵ��ʾ
+        if(!empty($arr['header']['ip']))
+        {
+            array_push($arr['header'],'X-FORWARDED-FOR:'.$arr['header']['ip'],'CLIENT-IP:'.$arr['header']['ip']);
+            unset($arr['header']['ip']);
+        }
+        $arr['header'] = array_filter($arr['header']);
+
+        if(!empty($arr['header']))
+        {
+            curl_setopt($ch, CURLOPT_HTTPHEADER, $arr['header']);
+        }
+
+        if($arr['request'] === 'put'){
+            curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "PUT");
+            curl_setopt($ch, CURLOPT_POSTFIELDS,$arr['post']);
+        }elseif($arr['post'] != false)
+        {
+            curl_setopt($ch, CURLOPT_POST, true);
+            if(is_array($arr['post']) && $arr['isupfile'] === false)
+            {
+                $post = http_build_query($arr['post']);
+            }
+            else
+            {
+                $post = $arr['post'];
+            }
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
+        }
+
+        $result = curl_exec($ch);
+        curl_close($ch);
+
+        return $result;
+    }
+
+    //分页共用
+    public function limit($db, $columns, $request)
+    {
+        $per_page = $request['page_size'] ?? 9999;
+        $page = $request['page_index'] ?? 1;
+        $return = $db->paginate($per_page, $columns, 'page', $page)->toArray();
+
+        $data['total'] = $return['total'];
+        $data['data'] = $return['data'];
+        return $data;
+    }
+
+    //判断是否为空
+    protected function isEmpty($data, $word)
+    {
+        if (isset($data[$word]) && (!empty($data[$word]) || $data[$word] === '0'|| $data[$word] === 0)) return false;
+        return true;
+    }
+
+    //后台端 某些需要限制请求频率的接口
+    public function limitingSendRequestBackg($key,$ttl = 5){
+        if($ttl < 5) $ttl = 5;
+
+        // 使用Redis Facade设置,当键名不存在时才设置成功
+        if (Redis::setnx($key, 1)) {
+            Redis::expire($key, $ttl); //多少秒后过期
+
+            return [true, ''];
+        }
+
+        return [false,'操作频繁, 请在 ' . $ttl . '秒后重试'];
+    }
+}

+ 287 - 0
app/Service/Wx/WxEmployeeService.php

@@ -0,0 +1,287 @@
+<?php
+
+namespace App\Service\Wx;
+
+use App\Model\Employee;
+use App\Model\EmployeeDepartPermission;
+use App\Model\EmployeeFoursShop;
+use App\Model\EmployeeTeamPermission;
+use App\Model\FoursShop;
+use App\Model\StorehouseEmployee;
+use App\Model\TemporaryJs;
+use App\Model\WxEmployee;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Hash;
+
+/**
+ * 区域相关
+ * @package App\Models
+ */
+class WxEmployeeService extends Service
+{
+
+    public function setUser($data){
+
+        $code = $data['code'];
+        $service = new WxService();
+        list($status,$openid) = $service->getOpenid($code);
+        if(!$status) return [false,$openid];
+
+        $user = WxEmployee::where('openid',$openid)->first();
+        if(empty($user)) {
+            $user = new WxEmployee();
+            $user->mobile = '';
+            $user->openid = $openid;
+            $user->appid = $service->appid;
+            $user->save();
+
+            $state = 0;
+        }else{
+            $state = 1;
+            if(empty($user->mobile) || empty($user->employee_id)) $state = 0;
+        }
+
+        return [true,['openid'=>$openid,'state'=>$state ]];
+    }
+
+
+    public function setMobile($data){
+        $code = $data['code'];
+        $openid = $data['openid'];
+        $service = new WxService();
+        list($status,$mobile) = $service->getMobile($code);
+        if(!$status) return [false,$mobile];
+
+        $user = WxEmployee::where('openid',$openid)->first();
+        if(empty($user))  return [false,'请先登陆'];
+
+        $user->mobile = $mobile;
+        $user->save();
+
+        return [true, $mobile];
+    }
+
+    public function login($data){
+        $account = $data['account'];
+        $password = $data['password'];
+        $openid = $data['openid'];
+
+        list($status,$data) = $this->loginRule([
+            'account' => $account,
+            'password' => $password,
+        ]);
+
+        if(!$status) return [false,$data];
+        $user_id = $data['id'];
+        $user = WxEmployee::where('openid',$openid)->first();
+        if(empty($user)||empty($user->mobile))  return [false,'请先登陆'];
+
+        $user->employee_id = $user_id;
+        $user->save();
+
+        return [true,$data];
+    }
+
+    public function loginRule($data){
+        if($this->isEmpty($data,'account')) return [false,'账号不能为空!'];
+        if($this->isEmpty($data,'password')) return [false,'密码不存在!'];
+
+        $account = $data['account'];
+        $res = Employee::where('del_time',0)
+            ->where(function ($query)use($account) {
+                $query->where('account', $account)
+                    ->orWhere('mobile', $account);
+            })
+            ->get()->toArray();
+
+        if(empty($res)) return [false,'账号不存在或已被删除!'];
+        if(count($res) > 1) return [false,'手机号绑定多个账户!'];
+
+        $res = reset($res);
+        if(! Hash::check($data['password'], $res['password'])) return [false,'密码错误!'];
+        if($res['state'] == Employee::NOT_USE) return [false,'账号停用!'];
+        list($status,$construction) = $this->isConstruction($res['id']);
+        if(! $status) return [false,'账号授权的门店不存在或者过期!'];
+
+        return [true, ['id'=>$res['id'], 'name'=>$res['emp_name'], 'account' => $res['account'],'construction' => $construction ?? []]];
+    }
+
+    //是否施工技师
+    public function isConstruction($emp_id){
+        if(empty($emp_id)) return [false,''];
+
+        //管理员
+        if(Employee::SPECIAL_ADMIN == $emp_id){
+            $foursShop = FoursShop::where('del_time',0)
+                ->select('id')
+                ->get()->toArray();
+            return [true, array_column($foursShop,'id')];
+        }
+
+        $result = EmployeeFoursShop::where('employee_id', $emp_id)
+            ->select('four_shop_id','use','expires_time')
+            ->where('del_time',0)
+            ->get()->toArray();
+
+        $return = [];
+        if(! empty($result)){
+            date_default_timezone_set("PRC");
+            $now = date("Y-m-d");
+            foreach ($result as $value){
+                if($value['use']){
+                    if(($value['expires_time'] == 0) || ($value['expires_time'] > 0 && ($now <= date("Y-m-d",$value['expires_time'])))){
+                        $return[] = $value['four_shop_id'];
+                    }
+                }
+            }
+            if(empty($return)) return [false,''];
+
+            return [true,$return];
+        }
+
+        return [false,''];
+    }
+
+    public function checkWxUser($userId){
+        $res = Employee::where('id', $userId)
+            ->where('del_time',0)
+            ->where('state',Employee::USE)->get()->first();
+        if(empty($res)) return [false, '该账号无法登录,请联系管理员!'];
+
+        list($status,$msg) = $this->isConstruction($userId);
+        if(! $status) return [false,'账号授权的门店不存在或者过期!'];
+
+        return [true, $res];
+    }
+
+    public function createTemporaryJs($data,$user){
+        list($status,$msg) = $this->createTemporaryJsRule($data,$user);
+        if(! $status) return [false,$msg];
+
+        try {
+            DB::beginTransaction();
+
+            $emp = Employee::where('del_time',0)
+                ->where('mobile',$data['mobile'])
+                ->first();
+            if(! empty($emp)){
+                Employee::where('id',$emp->id)
+                    ->update(['state' => Employee::STATUS_ONE]);
+                $employee_id = $emp->id;
+            }else{
+                $model = new Employee();
+                $model->emp_name = '外包技师:' . $data['mobile'];
+                $model->state = Employee::STATUS_ONE;
+                $model->is_wb = 1;
+                $model->crt_id = $user['id'];
+                $model->mobile = $data['mobile'];
+                $model->password = Hash::make(Employee::DEFAULT_PASS);
+                $model->entry_time = date("Y-m-d");
+                $model->save();
+                $employee_id = $model->id;
+
+                $permisson_model = new EmployeeDepartPermission();
+                $permisson_model->employee_id = $employee_id;
+                $permisson_model->depart_id = 72;
+                $permisson_model->save();
+            }
+
+            EmployeeFoursShop::where('employee_id',$employee_id)->update(['del_time' => time()]);
+            $insert = [];
+            foreach ($data['four_shop'] as $value){
+                $insert[] =  [
+                    "employee_id" => $employee_id,
+                    "four_shop_id" => $value['four_shop_id'],
+                    "use" => 1,
+                    'expires_time' => $value['expires_time'],
+                    'crt_time' => time(),
+                    'upd_time' => time(),
+                ];
+            }
+            EmployeeFoursShop::insert($insert);
+
+            DB::commit();
+        }catch (\Exception $e){
+            DB::rollBack();
+            return [false,$e->getMessage()];
+        }
+
+        return [true, ['account' => $data['mobile'], 'password' => Employee::DEFAULT_PASS]];
+    }
+
+    public function createTemporaryJsRule($data,$user){
+        $key = TemporaryJs::LimitationSign . $user['id'];
+        list($status,$msg) = $this->limitingSendRequestBackg($key,10);
+        if(! $status) return [false,$msg];
+
+        if(empty($data['mobile'])) return [false, '外包技师手机号不能为空'];
+        $bool = Employee::where('del_time',0)
+            ->where('mobile',$data['mobile'])
+            ->where('is_wb',0)
+            ->exists();
+        if($bool) return [false, '手机号已绑定内部员工!'];
+
+        if(empty($data['four_shop'])) return [false, '绑定4s店信息不能为空'];
+        //验证重复项
+        $four_shop_id = array_column($data['four_shop'],'four_shop_id');
+        foreach ($four_shop_id as $value){
+            if(! $value) return [false,'4s店不能为空!'];
+        }
+        $four_shop_id = array_map(function($val) {
+            return $val !== null ? $val : 0;
+        }, $four_shop_id);
+        $arr = array_count_values($four_shop_id);
+        foreach ($arr as $value){
+            if($value > 1) return [false,'4s店信息不能重复'];
+        }
+
+        if($user['id'] != Employee::SPECIAL_ADMIN){
+            $area_manager = $this->getAreaManagerBy4S();
+            if(! in_array($user['id'], $area_manager)) return [false,'非区域经理,操作失败'];
+        }
+
+        return [true, ''];
+    }
+
+    public function wxCheck($data,$user){
+        return [true,''];
+    }
+
+    public function getAreaManagerBy4S(){
+        $result = FoursShop::where('del_time',0)
+            ->select('regional_manager')
+            ->distinct()
+            ->get()->toArray();
+        return array_column($result,'regional_manager');
+    }
+
+    public function getAreaManagerByStore(){
+        $result = StorehouseEmployee::select('employee_id')
+            ->distinct()
+            ->where('del_time',0)
+            ->get()->toArray();
+        return array_column($result,'employee_id');
+    }
+
+    public function is_area_manager($user_id){
+        $is_area = [
+            'by_4s' => 0,
+            'by_store' => 0
+        ];
+        $return = $this->getAreaManagerBy4S();
+        if(in_array($user_id,$return)) $is_area['by_4s'] = 1;
+        $return = $this->getAreaManagerByStore();
+        if(in_array($user_id,$return)) $is_area['by_store'] = 1;
+
+        return $is_area;
+    }
+
+    public function is_check($user_id){
+        if($user_id == Employee::SPECIAL_ADMIN) return 1;
+
+        $bool = EmployeeTeamPermission::where('employee_id',$user_id)
+            ->exists();
+
+        return $bool;
+    }
+}

+ 72 - 0
app/Service/Wx/WxService.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Service\Wx;
+
+use Illuminate\Support\Facades\Redis;
+
+class WxService extends Service
+{
+//    public $appid = 'wx4e1324c600df37a6';
+//    public $secret = '72f8c912d462b0f4ff46cbedac0c80bf';
+
+    public $appid = 'wxe2c90ef3f853cdf8';
+    public $secret = '6ce9c60df493ef0a086674d41b02d39d';
+
+    public function getOpenid($code){
+
+
+        $appid = $this->appid;
+        $secret = $this->secret;
+//        $code = '0b1tFv100Sm91Q1kko0004vZGu0tFv12';
+        $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$appid.'&secret='.$secret.'&js_code='.$code.'&grant_type=authorization_code';
+
+        list($status,$res) = $this->wx_return($url);
+        if($status) return [true,$res['openid']];
+        else return [false,$res];
+
+
+
+    }
+
+    public function getToken(){
+
+        $token_key = $this->appid.'_wx_token';
+
+        $token = Redis::get($token_key);
+        if(!empty($token)){
+            return [true,$token];
+        }
+        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->secret;
+        list($status,$res) = $this->wx_return($url);
+        if($status) {
+            Redis::setex($token_key,7100,$res['access_token']);
+            return [true,$res['access_token']];
+        }
+        else return [false,$res];
+
+    }
+
+    public function getMobile($code){
+        list($status,$token) = $this->getToken();
+        $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token='.$token;
+        $post = [
+            'post'=>json_encode([
+                'code' => $code,
+            ]),
+        ];
+        $post['header'][] = "Content-Type:application/json";
+        list($status,$res) = $this->wx_return($url,$post);
+        if($status) return [true,$res['phone_info']['phoneNumber']];
+        else return [false,$res];
+    }
+
+
+
+    private function wx_return($url,$data=[]){
+        $res = $this->curlOpen($url,$data);
+        $res = json_decode($res,true);
+        if(isset($res['errcode'])&&$res['errcode'] !== 0) return [false,$res['errmsg']];
+
+        return [true,$res];
+    }
+}

+ 21 - 0
routes/wx.php

@@ -0,0 +1,21 @@
+<?php
+
+use Illuminate\Http\Request;
+/*
+|--------------------------------------------------------------------------
+| API Routes
+|--------------------------------------------------------------------------
+|
+| Here is where you can register API routes for your application. These
+| routes are loaded by the RouteServiceProvider within a group which
+| is assigned the "api" middleware group. Enjoy building your API!
+|
+*/
+
+Route::any('wxSetUser', 'Api\WxController@setUser');
+Route::any('wxSetMobile', 'Api\WxController@setMobile');
+Route::any('wxLogin', 'Api\WxController@login');
+
+Route::group(['middleware'=> ['checkWx']],function ($route){
+    $route->any('constructionList', 'Api\WxController@constructionList');
+});