/**
  * action 'oauth', the OAuth callback
  * 
  * @param Request $request
  * @param Response $response
  */
 public function oauth(Request $request, Response $response)
 {
     //trace_debug('weixin_oauth2_callback_doing', $_GET);
     $code = $request->get('code', '');
     if ('' != $code) {
         //授权通过
         $state = $request->get('state', '');
         $refer = $request->get('refer', '/');
         $from = $request->arg(2);
         if (empty($from)) {
             $from = 'weixin';
         }
         $auth_action = $request->get('act', '');
         $refer = rawurldecode($refer);
         //收获地址base oauth回调
         if ('jsapi_address' == $auth_action) {
             $response->redirect($refer . '&code=' . $code . '&state=' . $state);
         }
         //授权出错
         if (!in_array($state, array('base', 'detail'))) {
             Fn::show_error_message('授权出错,不能访问应用!');
         }
         $wx = new Weixin();
         //用code换取access token
         $code_ret = $wx->request_access_token($code);
         if (!empty($code_ret['errcode'])) {
             Fn::show_error_message('微信授权错误<br/>' . $code_ret['errcode'] . '(' . $code_ret['errmsg'] . ')');
         }
         //获取到openid
         $openid = $code_ret['openid'];
         $uid = 0;
         $auth_method = 'oauth2_' . $state;
         //认证方式
         //查询本地是否存在对应openid的用户
         $uinfo_bd = Member::getTinyInfoByOpenid($openid, $from);
         if (empty($uinfo_bd)) {
             //用户不存在,则要尝试建立
             //保存微信用户信息到本地库
             $udata = ['openid' => $openid, 'auth_method' => $auth_method];
             $uid = Member::createUser($udata, $from);
             $uinfo_bd = ['uid' => $uid];
         } else {
             //用户已存在,对state='base',则仅需设置登录状态;而对state='detail',需保存或更新用户数据
             $uid = intval($uinfo_bd['uid']);
         }
         //detail认证模式,需更新用户数据
         if ('detail' == $state && empty($uinfo_bd['nickname'])) {
             $uinfo_wx = $wx->userInfoByOAuth2($openid, $code_ret['access_token']);
             if (!empty($uinfo_wx['errcode'])) {
                 //失败!则报错
                 Fn::show_error_message('微信获取用户信息出错!<br/>' . $uinfo_wx['errcode'] . '(' . $uinfo_wx['errmsg'] . ')');
             }
             //保存微信用户信息到本地库
             $udata = ['unionid' => isset($uinfo_wx['unionid']) ? $uinfo_wx['unionid'] : '', 'subscribe' => isset($uinfo_wx['subscribe']) ? $uinfo_wx['subscribe'] : 0, 'subscribe_time' => isset($uinfo_wx['subscribe_time']) ? $uinfo_wx['subscribe_time'] : 0, 'nickname' => isset($uinfo_wx['nickname']) ? $uinfo_wx['nickname'] : '', 'logo' => isset($uinfo_wx['headimgurl']) ? $uinfo_wx['headimgurl'] : '', 'sex' => isset($uinfo_wx['sex']) ? $uinfo_wx['sex'] : 0, 'lang' => isset($uinfo_wx['language']) ? $uinfo_wx['language'] : '', 'country' => isset($uinfo_wx['country']) ? $uinfo_wx['country'] : '', 'province' => isset($uinfo_wx['province']) ? $uinfo_wx['province'] : '', 'city' => isset($uinfo_wx['city']) ? $uinfo_wx['city'] : '', 'auth_method' => $auth_method];
             Member::updateUser($udata, $openid, $from);
             //尝试用基本型接口获取用户信息,以便确认用户是否已经关注(基本型接口存在 50000000次/日 调用限制,且仅对关注者有效)
             if (FALSE && !$uinfo_bd['subscribe'] && !$udata['subscribe']) {
                 $uinfo_wx = $wx->userInfo($openid);
                 //trace_debug('weixin_basic_userinfo', $uinfo_wx);
                 if (!empty($uinfo_wx['errcode'])) {
                     //失败!说明很可能没关注,维持现状不处理
                 } else {
                     //成功!说明之前已经关注,得更新关注标记
                     $udata = ['subscribe' => isset($uinfo_wx['subscribe']) ? $uinfo_wx['subscribe'] : 0, 'subscribe_time' => isset($uinfo_wx['subscribe_time']) ? $uinfo_wx['subscribe_time'] : 0];
                     Member::updateUser($udata, $openid, $from);
                 }
             }
         }
         //End: if ('detail'===$state)
         //设置本地登录状态
         if ('login' == $auth_action) {
             if (empty($uid)) {
                 Fn::show_error_message('微信授权登录失败!');
             }
             Member::setLocalLogin($uid);
         }
         //跳转
         $response->redirect($refer);
     } else {
         //授权未通过
         Fn::show_error_message('未授权,不能访问应用!');
     }
 }