User.php 11.4 KB
<?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;

/**
 * 会员接口
 */
class User extends Base
{
    protected $noNeedLogin = ['login', 'mobilelogin', 'accountLogin', 'wxMiniProgramLogin', 'getWxMiniProgramSessionKey', 'getUserDefaultFields'];
    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": "1607588102",
        "data": {
            "id": 1, //用户ID
            "group_id": 1, //分组ID
            "nickname": "123", //昵称
            "avatar": "shuoshenme", //头像
            "money": "0.00", //余额
            "score": 0, //积分
            "token": "1419ae8b-dd47-4ab5-9c10-c88d42dc4cb3", //token
            "user_id": 1, // 用户ID
            "createtime": 1607397247, //注册时间
            "expiretime": 1609989247, //token过期时间
            "expires_in": 2401145, //过期时间段
            "group": { //分组
                "name": "默认组", //分组名称
                "image": "http://www.ant.top" //分组图片
            },
            "coupons_num": 0, //优惠券数量
            "is_store": 0, //是否是店铺管理员:0=否,1=是
            "store_id": 0 //店铺ID
        }
    })
     */
    public function index()
    {
        $auth = \app\common\library\Auth::instance();
        $auth->setAllowFields(['id', 'nickname', 'avatar', 'score', 'money','group_id']);
        $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'];
        }

        $this->success('用户信息', $data);
    }

    /**
     * @ApiWeigh    (99)
     * @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")
     *
     * @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);
        }

        $ret = $this->oauthLoginOrRegister($decryptData, 'wxMiniProgram', 'Wechat');
        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 有效时长
     */
    private function oauthLoginOrRegister($decryptData, $platform, $provider, $keeptime = 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();
                    $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();
    }

    private function getUserDefaultFields()
    {
        $userConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'user'])->value,true);
        return $userConfig;
    }
}