<?php namespace app\api\controller; use app\common\library\Ems; use app\common\library\Sms; use fast\Random; use think\Validate; use addons\shopro\library\Wechat; use think\Db; use addons\shopro\model\UserOauth; use addons\shopro\model\User as UserModel; use addons\shopro\model\UserStore; use app\api\model\PackageOrder; use app\api\model\Package; /** * 会员接口 */ class User extends Base { protected $noNeedLogin = ['package','login', 'mobilelogin', 'accountLogin', 'wxMiniProgramLogin', 'getWxMiniProgramSessionKey', 'getUserDefaultFields','serviePhone']; protected $noNeedRight = '*'; public function _initialize() { return parent::_initialize(); } /** * @ApiWeigh (99) * @ApiTitle (会员中心) * @ApiSummary (会员中心) * @ApiMethod (GET) * * @ApiHeaders (name=token, type=string, required=true, description="请求的token") * * @ApiReturn({ "code": 1, "msg": "用户信息", "time": "1607908165", "data": { "id": 1, //用户ID "group_id": 1, //分组ID "nickname": "123", //昵称 "avatar": "shuoshenme", //头像 "money": "0.00", //余额 "score": 0, //积分 "token": "1419ae8b-dd47-4ab5-9c10-c88d42dc4cb3", "user_id": 1, "createtime": 1607397247, "expiretime": 1609989247, "expires_in": 2081082, "group": { "name": "默认组", "image": "http://www.ant.top" }, "coupons_num": 0, //优惠券数量 "is_store": 1, "store_id": 1, "avatar_full": "http://www.ant.topshuoshenme", //头像全路径 "is_vip": 1, //是否会员:0=否,1=是 "vip_start_time": "2020/08/02", //开通会员初始时间 "vip_end_time": "2021/08/02", //会员到期时间 "commission": 0", //待提现佣金 } }) */ public function index() { $auth = \app\common\library\Auth::instance(); $auth->setAllowFields(['id', 'nickname', 'avatar', 'score', 'money','group_id','vip_start_time','vip_end_time','commission']); $data = $auth->getUserinfo(); if (!isset($data['group'])) { $data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']); } // 查询用户优惠券数量 $userCoupons = \addons\shopro\model\Coupons::getCouponsList(1); $data['coupons_num'] = count($userCoupons); // 查询用户是否是门店管理员 $userStores = UserStore::where('user_id', $data['id'])->select(); $data['is_store'] = $userStores ? 1 : 0; $data['store_id'] = 0; if (count($userStores) == 1) { // 只有一个店铺 直接进入店铺 $data['store_id'] = $userStores[0]['store_id']; } // 头像全路径 $data['avatar_full'] = !empty($data['avatar']) ? cdnurl($data['avatar'],true) : ''; // 是否会员:0=否,1=是 $data['is_vip'] = $data['vip_end_time'] > time() ? 1 : 0; $data['vip_start_time'] = date('Y/m/d',$data['vip_start_time']); $data['vip_end_time'] = date('Y/m/d',$data['vip_end_time']); $this->success('用户信息', $data); } /** * @ApiWeigh (98) * @ApiTitle (会员套餐) * @ApiSummary (会员套餐) * @ApiMethod (GET) * * @ApiReturn({ "code": 1, "msg": "会员套餐", "time": "1608621344", "data": [{ //会员套餐列表 "id": 1, //套餐ID "package_name": "季度会员", //套餐名称 "package_price": "150.00", //套餐价格 "month": 3, //会员持续月数 "content": "富文本内容" //会员权益 }], }) */ public function package() { $data = Package::field('id,package_name,package_price,month,content') ->order('weigh desc') ->select(); $this->success('会员套餐',$data); } /** * @ApiWeigh (98) * @ApiTitle (会员套餐-购买记录) * @ApiSummary (会员套餐-购买记录) * @ApiMethod (GET) * * @ApiHeaders (name=token, type=string, required=true, description="请求的token") * @ApiParams (name=page, type=inter, required=true, description="分页") * * @ApiReturn({ "code": 1, "msg": "会员套餐-购买记录", "time": "1608723584", "data": { "total": 2, //数据总数 "per_page": 10, "current_page": 1, "last_page": 1, "data": [{ //记录列表 "id": 4, //记录ID "remark": "续费(12个月)", //注释 "pay_fee": "150.00", //支付费用 "paytime": "2020.12.23" //充值时间 }] } }) */ public function packageOrderList() { $list = PackageOrder::where('user_id',$this->auth->id) ->where('status',1) ->field('id,remark,pay_fee,paytime') ->order('paytime desc') ->paginate(10) ->each(function($v){ $v->paytime = date('Y.m.d',$v['paytime']); }); $this->success('会员套餐-购买记录',$list); } /** * @ApiWeigh (98) * @ApiTitle (会员登录) * @ApiSummary (会员登录) * @ApiMethod (POST) * * @ApiParams (name=account, type=string, required=true, description="账号") * @ApiParams (name=password, type=string, required=true, description="密码") * * @ApiReturn() */ public function accountLogin() { $account = $this->request->post('account'); $password = $this->request->post('password'); if (!$account || !$password) { $this->error(__('Invalid parameters')); } $ret = $this->auth->login($account, $password); if ($ret) { $data = ['userinfo' => $this->auth->getUserinfo()]; $this->success(__('Logged in successful'), $data); } else { $this->error($this->auth->getError()); } } /** * @ApiWeigh (97) * @ApiTitle (获取微信小程序session_key) * @ApiSummary (获取微信小程序session_key) * @ApiMethod (POST) * * @ApiParams (name=code, type=string, required=true, description="加密code") * * @ApiReturn({ "code": 1, "msg": "用户信息", "time": "1607588102", "data": { "openid": 123456, //openid "session_key": 123456, //session_key } }) */ public function getWxMiniProgramSessionKey() { $post = $this->request->post(); $wechat = new Wechat('wxMiniProgram'); $decryptSession = $wechat->code($post['code']); $this->success('获取session_key', $decryptSession); } /** * @ApiWeigh (97) * @ApiTitle (微信小程序登录) * @ApiSummary (微信小程序登录) * @ApiMethod (POST) * * @ApiParams (name=session_key, type=string, required=true, description="session_key") * @ApiParams (name=iv, type=string, required=true, description="iv") * @ApiParams (name=encryptedData, type=string, required=true, description="encryptedData") * @ApiParams (name=user_id, type=inter, required=false, description="扫码获取的用户ID") * * @ApiReturn({ 'code':'1', 'msg':'返回成功', "data": { "token": "9e4648c7-c640-4e41-b758-dd1a8ef7a7ae", } }) */ public function wxMiniProgramLogin() { $post = $this->request->post(); $wechat = new Wechat('wxMiniProgram'); $decryptUserInfo = $wechat->decryptData($post['session_key'], $post['iv'], $post['encryptedData']); // array(10) { // ["openId"] => string(28) "oD9ko40ZEoru7bjzN2f0Wnm3uNmA" // ["nickName"] => string(12) "Civilization" // ["gender"] => int(1) // ["language"] => string(5) "zh_CN" // ["city"] => string(0) "" // ["province"] => string(0) "" // ["country"] => string(7) "Iceland" // ["avatarUrl"] => string(124) "https://wx.qlogo.cn/mmopen/vi_32/bKchg38ErVBnuJBb4NfCOYkMsxgzZ3vZGu7y7V0BQG8clImsyvZge2HzGGYfxXKBNv8dbQOvyvmjKPEtRyrniaA/132" // ["unionId"] => string(28) "odsYQ1MLsGSGL6Gp5f6y3at2j7Hg" // ["watermark"] => array(2) { // ["timestamp"] => int(1590344429) // ["appid"] => string(18) "wx39cd0799d4567dd0" // } // } //组装decryptData $decryptData = array_change_key_case($decryptUserInfo, CASE_LOWER); $decryptData['headimgurl'] = $decryptData['avatarurl']; $decryptData['sex'] = $decryptData['gender']; $decryptData['session_key'] = $post['session_key']; if (empty($decryptData['openid'])) { $this->error(__('code错误'), $decryptData); } $pid = isset($post['user_id']) ? $post['user_id'] : 0; $ret = $this->oauthLoginOrRegister($decryptData, 'wxMiniProgram', 'Wechat',0, $pid); if ($ret) { $data = $ret->getUserinfo(); if (!isset($data['group'])) { $data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']); } $this->success(__('Logged in successful'), $data); } $this->error($this->auth->getError()); } /** * 第三方登录或自动注册 * * @param string $decryptData 解密参数 * @param string $platform 平台名称 * @param string $provider 厂商名称 * @param string $keeptime 有效时长 * @param string $pid 绑定上级 */ private function oauthLoginOrRegister($decryptData, $platform, $provider, $keeptime = 0, $pid = 0) { extract($decryptData); @$oauthData = compact('provider', 'unionid', 'platform', 'openid', 'nickname', 'sex', 'city', 'province', 'country', 'headimgurl', 'session_key', 'refresh_token', 'access_token'); $oauthData['logintime'] = time(); $oauthData['logincount'] = 1; if ($platform === 'wxMiniProgram' || $platform === 'App') { $oauthData['expire_in'] = 7200; $oauthData['expiretime'] = time() + 7200; } $auth = \app\common\library\Auth::instance(); $auth->keeptime($keeptime); $auth->setAllowFields(['id', 'username', 'nickname', 'mobile', 'avatar', 'score', 'money', 'group', 'group_id']); $userOauth = UserOauth::get(['openid' => $openid]); if (isset($decryptData['nickname'])) { $fields['nickname'] = $decryptData['nickname']; } if (isset($decryptData['headimgurl'])) { $fields['avatar'] = $decryptData['headimgurl']; } //开启事务 Db::startTrans(); try { if ($userOauth) { //找到对应已注册用户,更新oauthData数据和用户数据直接发起登录 $user_id = $userOauth->user_id; $user = UserModel::get($user_id); $oauthData['logincount'] = $userOauth->logincount + 1; $userOauth->save($oauthData); } else { //添加新的oauthData数据 //默认创建新用户 $createNewUser = true; // 判断是否有unionid 并且已存在oauth数据中 if (isset($unionid)) { //存在同厂商信息,添加oauthData数据,合并用户 $user_id = UserOauth::where(['unionid' => $unionid])->value('user_id'); $user = UserModel::get($user_id); if ($user) { $createNewUser = false; } } if ($createNewUser) { // 创建空用户 $username = Random::alnum(20); $password = ''; $domain = request()->host(); $extend = $this->getUserDefaultFields(); if($pid > 0){ //绑定上级 $extend['pid'] = $pid; } $result = $auth->register($username, $password, $username . '@' . $domain, '', $extend, $keeptime); if (!$result) { return false; } $user = $auth->getUser(); if (!isset($fields['nickname'])) { //默认昵称 $fields['nickname'] = $extend['nickname'] . $user->id; } // 更新会员资料 $user = UserModel::get($user->id); // 保存第三方信息 $user_id = $user->id; } $oauthData['user_id'] = $user_id; UserOauth::create($oauthData); } if (isset($fields)) $user->save($fields); Db::commit(); } catch (\Exception $e) { Db::rollback(); $auth->logout(); $this->error($e->getMessage()); return false; } $auth->direct($user_id); return $auth; } /** * @ApiWeigh (97) * @ApiTitle (修改会员个人信息) * @ApiSummary (修改会员个人信息) * @ApiMethod (POST) * * @ApiParams (name=nickname, type=string, required=true, description="昵称") * @ApiParams (name=avatar, type=string, required=true, description="头像") * * @ApiReturn({ "code": 1, "msg": "", "time": "1607398637", "data": null }) */ public function profile() { $user = $this->auth->getUser(); $nickname = $this->request->post('nickname'); $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars'); if(empty($nickname) && empty($avatar)){ $this->error('请填写修改内容'); } if(!empty($nickname)){ $user->nickname = $nickname; } if(!empty($avatar)){ $user->avatar = $avatar; } $user->save(); $this->success(); } /** * @ApiWeigh (95) * @ApiTitle (分销中心-我的下级-1级) * @ApiSummary (分销中心-我的下级-1级) * @ApiMethod (GET) * * @ApiHeaders (name=token, type=string, required=true, description="请求的token") * * @ApiReturn({ "code": 1, "msg": "分销中心-我的下级-1级", "time": "1608727151", "data": { "total": 1, //数据总数 "per_page": 10, "current_page": 1, "last_page": 1, "data": [{ //列表 "id": 2, //用户ID "nickname": "wn56", //昵称 "avatar": "https://yixiaoxian.qiniu.broing.cn/uploads/20201214/8f6a49f6873028e0e7aba28b28eb9d56.png", //头像 "createtime": "2020/12/11", //时间 "url": "/u/2" }] } }) */ public function lowerList() { $first_id_arr = UserModel::where('pid',$this->auth->id)->column('id'); $where = $first_id_arr ? ['id'=>['in',$first_id_arr]] : ['id'=>0]; $list = UserModel::where($where) ->paginate(10) ->each(function($v){ $v->createtime = date('Y/m/d',$v['createtime']); $v->visible(['id','createtime','avatar','nickname']); }); $this->success('分销中心-我的下级-1级',$list); } /** * @ApiWeigh (95) * @ApiTitle (分销中心-我的下级-2级) * @ApiSummary (分销中心-我的下级-2级) * @ApiMethod (GET) * * @ApiHeaders (name=token, type=string, required=true, description="请求的token") * * @ApiReturn({ "code": 1, "msg": "分销中心-我的下级-2级", "time": "1608727151", "data": { "total": 1, //数据总数 "per_page": 10, "current_page": 1, "last_page": 1, "data": [{ //列表 "id": 2, //用户ID "nickname": "wn56", //昵称 "avatar": "https://yixiaoxian.qiniu.broing.cn/uploads/20201214/8f6a49f6873028e0e7aba28b28eb9d56.png", //头像 "createtime": "2020/12/11", //时间 "url": "/u/2" }] } }) */ public function lowersList() { $second_id_arr = []; $first_id_arr = UserModel::where('pid',$this->auth->id)->column('id'); foreach ($first_id_arr as $first_id){ $second_id_arr = array_merge(UserModel::where('pid',$first_id)->column('id'),$second_id_arr); } $where = $second_id_arr ? ['id'=>['in',$second_id_arr]] : ['id'=>0]; $list = UserModel::where($where) ->paginate(10) ->each(function($v){ $v->createtime = date('Y/m/d',$v['createtime']); $v->visible(['id','createtime','avatar','nickname']); }); $this->success('分销中心-我的下级-2级',$list); } private function getUserDefaultFields() { $userConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'user'])->value,true); return $userConfig; } /** * @ApiWeigh (85) * @ApiTitle (我的二维码) * @ApiSummary (我的二维码) * @ApiMethod (GET) * * @ApiHeaders (name="token", type="string", required=true, description="请求的token") * * @ApiReturn ({ "code": 1, "msg": "成功", "time": "1609056357", "data": { "url": "http://www.ant.top/uploads/user/1.png?v=1609056359", //海报地址 "goods": { //免费领取海报商品 "id": 1, //商品ID "type": "normal", "title": "分销海报", "subtitle": "分销海报", "weigh": 0, "category_ids": "3", "image": "https://yixiaoxian.qiniu.broing.cn/uploads/20201224/FpqzUt7YTrXlZUsarlqD8heEHA4O.png", "images": [ "https://yixiaoxian.qiniu.broing.cn/uploads/20201224/FpqzUt7YTrXlZUsarlqD8heEHA4O.png" ], "params": [], "content": "海报", "price": "0", "original_price": "100.00", "is_sku": 0, "likes": 0, "views": 100, "sales": 0, "show_sales": 0, "service_ids": "", "dispatch_type": "express", "dispatch_ids": "1", "deletetime": null, "activity": null, "activity_type": null, "sku_price": [{ //商品规格 "id": 1, //规格ID "goods_sku_ids": null, "goods_id": 1, "weigh": 0, "image": null, "stock": 999999, "sales": 0, "sn": "", "weight": 0, "price": "0.00", //商品价格 "goods_sku_text": null, "status": "up", "goods_sku_id_arr": [ "" ] }], "stock": 999999, "favorite": { "id": 6, "user_id": 1, "goods_id": 1, "deletetime": null }, "dispatch_type_arr": [ "express" ], "service": [], "sku": [], "coupons": [{ "id": 1, "name": "满100减10", "type": "cash", "goods_ids": "0", "amount": "10.00", "enough": "100.00", "stock": 0, "limit": 1, "gettime": { "start": 1607875200, "end": 1610640000 }, "usetime": { "start": "2020.12.18", "end": "2021.01.30" }, "description": "满100减10", "usetimestart": 1608220800, "usetimeend": 1611936000, "gettimestart": 1607875200, "gettimeend": 1610640000 }] } } }) */ public function userPoster() { $user = UserModel::get($this->auth->id); $avatar_url = !empty($user['avatar']) ? cdnurl($user['avatar']) : ''; empty($avatar_url) && $this->error('请先上传头像'); !url_exists($avatar_url) && $this->error('头像失效,请更新头像'); // 本地路径 $dir = 'uploads/user'; if (!file_exists($dir)){ mkdir($dir,0777,true); } // 用户小程序码 // $qrcode = $dir.'/qrcode_'.$user['id'].'.png'; // if(!file_exists($qrcode)){ // $response = Wechat::miniProgram()->app_code->getUnlimit($user['id'], [ // 'page' => 'pages/indexone/indexone', // 'width' => 280, //最小宽度280 // ]); // if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { // $response->saveAs($dir, str_replace($dir.'/','',$qrcode)); // } // // 280不满足,再缩小 // \think\Image::open($qrcode)->thumb(64,64)->save($qrcode); // } $qrcode = ROOT_PATH.'public/assets/img/miniProgram/qrcode.png'; //将用户头像保存到本地 $avatar = $dir.'/avatar_'.$user['id'].'.png'; file_put_contents($avatar,file_get_contents($avatar_url)); \think\Image::open($avatar)->thumb(64,64,\think\Image::THUMB_CENTER)->save($avatar); createRoundImg($avatar); $path_ttf = ROOT_PATH.'public/assets/fonts/verdana.ttf'; $filename = $dir.'/'.$user['id'].'.png'; //将海报背景保存到本地 $share = json_decode(\addons\shopro\model\Config::where(['name' => 'share'])->value('value'), true); $user_poster_bg = ROOT_PATH.'public/assets/img/miniProgram/user_poster_bg.png'; file_put_contents($user_poster_bg,file_get_contents(cdnurl($share['user_poster_bg']))); // 生成海报 \think\Image::open($user_poster_bg) ->water($avatar,[16,441]) ->text($user['nickname'],$path_ttf,17,'#000000',[88,463]) ->water($qrcode,[253,441]) ->save($filename); $url = request()->domain().'/'.$filename.'?v='.time(); // 免费领取推广海报商品 $goods = \addons\shopro\model\Goods::withTrashed()->find(); $goods = $goods->append(['service', 'sku', 'coupons']); $this->success('成功',compact('url','goods')); } /** * @ApiWeigh (83) * @ApiTitle (分销说明) * @ApiSummary (分销说明) * @ApiMethod (GET) * * @ApiReturn({ "code": 1, "msg": "会员套餐", "time": "1608621344", "data": { "description": "富文本内容" //会员权益 } }) */ public function distribution() { $description = \addons\shopro\model\Richtext::get(2)['content']; $this->success('分销说明',compact('description')); } /** * @ApiWeigh (81) * @ApiTitle (联系客服) * @ApiSummary (联系客服) * @ApiMethod (GET) * * @ApiReturn({ "code": 1, "msg": "联系客服", "time": "1608621344", "data": { "service_phone": "0311-02056" //客服电话 } }) */ public function serviePhone() { $user = json_decode(\addons\shopro\model\Config::where(['name' => 'user'])->value('value'), true); $this->success('联系客服',[ 'service_phone' => $user['service_phone'] ]); } }