crmeb多商户3.0PHP版二开之-后台管理员免密登录用户账户
第一步,先修改uniapp前端,用HBuilder X打开uniapp前端项目,新增加一个页面,路径是/pages/users/login/tokenlogin.vue,在项目的pages.json中注册路由,并分包到users
{ "path" : "login/tokenlogin", "style" : { "navigationBarTitleText" : "令牌登录", "enablePullDownRefresh": false } }
接着在/api/user.js的第39行下面,也就是loginH5方法下面,增加一个token令牌登录的方法,如下
/** * h5用户令牌登录登录 * @param data object Token令牌 */ export function loginToken(data) { return request.post("auth/logintoken", data, { noAuth: true }); }
接着在tokenlogin.vue中编写代码如下:
<template> <div> </div> </template>
<script> import {loginToken} from '@/api/user.js'; export default { onLoad(options) { const that = this; const Token = options.token; if ( !Token ){ that.gotip('没有令牌', false); } else { uni.showLoading(); loginToken({token : Token}).then(res => { console.log(res.data); uni.hideLoading(); that.$store.commit("LOGIN", { 'token': res.data.token, 'time': res.data.exp }); that.$store.commit("SETUID", res.data.user.uid); that.$store.commit('UPDATE_USERINFO', res.data.user); that.gotip('令牌登录成功', true); }).catch(err => { uni.hideLoading(); that.gotip(err, false); }); } }, methods : { gotip(title, s){ uni.showToast({ title: title, icon:'none', duration:2000, }); setTimeout(() => { !s ? uni.redirectTo({ url:'/pages/users/login/index', }) : uni.switchTab({ url : '/pages/user/index' }); }, 2000); } } } </script>
完成后,发布H5,打包到站点根目录中的public目录下,解压覆盖,这样就手机h5端二开好了。
第二步,修改后端接口,首先,打开根目录下的/route/api.php 进行路由的设置,
在
Route::post('auth/login', 'api.Auth/login');
这行的下面增加一行
Route::post('auth/logintoken', 'api.Auth/logintoken');
保存,重启守护进程
然后,在数据库执行以下sql,给用户表增加俩个字段:
ALTER TABLE `eb_user` ADD `token` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '登录令牌' AFTER `svip_save_money`, ADD `tokentime` BIGINT(20) NOT NULL DEFAULT '0' COMMENT '令牌过期时间' AFTER `token`;
修改/app/common/dao/user/UserDao.php, 在accountByUser方法下面(大概332行)增加如下方法:
public function tokenByUser( string $token ){ return User::getDB() -> where('token', $token) -> find(); } public function setUserToken( int $uid, string $token, int $time){ return User::getDB() -> where('uid', $uid) -> data(['token' => $token, 'tokentime' => $time]) -> update(); }
修改/app/controller/api/Auth.php, 在login方法下面(大概83行)增加如下方法,
/** * TODO token令牌登录 * @param token string 令牌 * */ public function logintoken(UserRepository $repository){ $token = $this -> request -> param('token'); if ( !$token ) { return app('json') -> fail('无令牌'); } else { $user = $repository -> tokenByUser( $token ); if( !$user ) { return app('json') -> fail('令牌错误'); } elseif ( $user -> tokentime < time() ){ return app('json') -> fail('令牌已过期' . time()); } else { $user = $repository -> mainUser($user); $pid = $this->request -> param('spread', 0); $repository->bindSpread($user, intval($pid)); $tokenInfo = $repository -> createToken($user); $repository->loginAfter($user); return app('json') -> success($repository -> returnToken($user, $tokenInfo)); } } }
至此,手机端H5和api接口就修改好了,接下来修改后台的界面和逻辑。
用phpstrom打开admin项目,
修改/src/api/user.js, 增加如下方法
/** * @description 设置用户的Token令牌 */ export function userTokenApi(data) { return request.post(`user/token`, data) }
修改/src/views/user/list/index.vue, 找到“更多”这里,在设置余额一行的上面增加一行:
<el-dropdown-item @click.native="tokenlogin(scope.row.uid)">登录用户</el-dropdown-item>
接着在模板底部增加如下代码:
<!--token登录--> <el-dialog v-if="loginwin" title="登录用户" :visible.sync="loginwin" width="300px"> <div style="width: 100%;text-align: center;margin: 20px auto;"> <el-button type="primary" @click="loginopen(false)">复制链接</el-button> <el-button type="primary" @click="loginopen(true)">直接登录</el-button> </div> </el-dialog>
在JavaScript代码的data中,添加两个字段,loginwin : false 和 logintoken : ''
导入userTokenApi方法
最后在methods内增加下面方法:
/**生成登录token*/ tokenlogin(uid) { const loading = this.$loading(); userTokenApi({uid : uid}).then(res => { loading.close(); console.log(res.data); this.logintoken = res.data; this.loginwin = true; }).catch(error => { loading.close(); this.$message.error(error); }) }, getCurrentUrl() { const { protocol, hostname, port } = window.location; let url; if (port === '80') { url = `${protocol}//${hostname}`; } else if (port === '443') { url = `${protocol}//${hostname}`; } else { url = `${protocol}//${hostname}:${port}`; } return url; }, async loginopen(t){ let loginurl = `${this.getCurrentUrl()}/pages/users/login/tokenlogin?token=${this.logintoken}`; if(!t){ try{ await navigator.clipboard.writeText(loginurl); this.$message.success('复制成功'); } catch (err) { this.$message.error('复制失败'); } } else { window.open(loginurl); } },
修改完成后,使用命令打包源码:
npm run build:prod
打包完成后,压缩上传到服务器public目录下,解压覆盖
至此,后台免密登录二开完成。下面是演示效果