实战4 ele与tp:登录状态路由跳转,ticket加密登录
一、涉及代码文件文件:
1、Login.vue文件代码
2、Index.vue文件代码
3、Ticket.php
4、Login.php文件代码
4、User.vue
5、Index.php
6、运行截图6.1、登录退出
6.2、用户部门
- /shop/src/views/Login.vue(更新登录成功路由跳转验证)
- /shop/src/views/Index.vue(更新登录成功路由跳转验证。更新查询所有组)
- /tp6/extend/ouyangke/Ticket.php(新建ticket登录认证)
- /tp6/app/admin/controller/Login.php(更新)
- /shop/src/views/User.vue(更新部门列表,新增修改用户部门)
- /tp6/app/admin/controller/Index.php(更新部门查询)
1、Login.vue文件代码
<template>
<div class="container">
<div style="text-align: center">
<!--<img src="@/assets/logo.jpg" alt="logo" />-->
<h3>后台管理</h3>
</div>
<div class="main">
<!-- label-width="auto" 导致ElementPlusError: [ElForm] unexpected width 0 -->
<el-form :model="form" size="large">
<el-form-item prop="account">
<el-input v-model="form.account" name="account" class="w-50 m-2" placeholder="请输入账号">
<template #prefix>
<el-icon class="el-input__icon" style="color: #1890ff"><Avatar /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="form.password" name="password" type="password" class="w-50 m-2" placeholder="请输入密码" show-password>
<template #prefix>
<el-icon class="el-input__icon" style="color: #1890ff"><Lock /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="remember">
<el-checkbox v-model="form.remember" label="1" size="large">保存账密</el-checkbox>
</el-form-item>
<el-form-item>
<el-button type="primary" style="width: 100%" @click="onSubmit()">登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<style>
.container {
position: relative;
width: 100%;
min-height: 100%;
padding: 110px 0 144px;
background-repeat: no-repeat;
background-position: center 110px;
background-size: 100%;
}
.main {
width: 368px;
min-width: 260px;
margin: 50px auto;
}
.el-icon {
color: #359eff;
}
</style>
<script>
import { reactive } from "vue";
//import { request } from "../network/request.js";
import { login } from "../network/index.js";
// 登录成功用路由进行跳转:
import { useRouter } from "vue-router";
export default {
setup() {
const form = reactive({
account: "428188207@qq.com",
password: "123456",
remember: true,
});
const router = useRouter();
// 读取保存在缓存中的用户uid信息
let ticket = window.localStorage.getItem('ticket');
// 如果有登录就跳转到home页面
if(ticket){
router.push({
path: "/index/home"
});
}
const onSubmit = ()=>{
login({
account : form.account,
password : form.password,
}).then(res =>{
console.log(res.data);
// html5有个保存到本地的缓存机制.
// 把用户的唯一标识,用户UID.保存到缓存中.
// 接入ticket
window.localStorage.setItem("ticket", res.data.data.ticket);
if(res.data.code == 0){
// 跳转到新页面
router.push("/Index");
// 另外一种写法
// router.push({
// path: "/index"
//});
}
})
}
return {
form,
onSubmit
};
}
};
</script>
2、Index.vue文件代码
<!-- 1、新建 /src/views/Index/Index.vue 文件 -->
<template>
<el-container class="layout" style="height: 100%">
<aside style="height: 100%">
<el-menu default-active="-1" class="el-menu-vertical-demo" :collapse="isCollapse" active-text-color="#ffd04b" background-color="#545c64" text-color="#fff">
<div class="logo">
<router-link to="/index/home" class="router">
<!--<img src="@/assets/logo.jpg" alt="logo" />-->
<h1>phpAdmin</h1>
</router-link>
</div>
<router-link to="/index/home">
<el-menu-item index="-1">
<template #title>首页</template>
</el-menu-item>
</router-link>
<router-link to="/index/home">
<el-menu-item index="-2">
<template #title>个人中心</template>
</el-menu-item>
</router-link>
<template v-for="(item,index,key) in menu">
<el-sub-menu :index="item.mid" v-if="item.type == 0">
<template #title>
<span>{{ item.label }}</span>
</template>
<template v-for="(items,indexs,keys) in item.son">
<router-link :to="items.src" v-if="items.type == 1">
<el-menu-item :index="item.mid + items.mid">
<span>{{ items.label }}</span>
</el-menu-item>
</router-link>
<a :href="items.src" target="_blank" v-if="items.type == 2">
<el-menu-item :index="item.mid + items.mid">
<span>{{ items.label }}</span>
</el-menu-item>
</a>
</template>
</el-sub-menu>
<router-link :to="item.src" v-if="item.type == 1">
<el-menu-item :index="index + item.mid">
<template #title>{{ item.label }}</template>
</el-menu-item>
</router-link>
<router-link :to="item.src" v-if="item.type == 2">
<el-menu-item :index="index + item.mid">
<template #title>{{ item.label }}</template>
</el-menu-item>
</router-link>
</template>
</el-menu>
<div class="flexible" @click="isCollapse = !isCollapse">
<el-icon v-if="isCollapse" color="white" :size="40"><ArrowRight /></el-icon>
<el-icon v-else color="white" :size="40"><ArrowLeft /></el-icon>
</div>
</aside>
<el-container>
<el-header style="text-align: right; font-size: 20px">
<div class="toolbar">
<el-dropdown size="large" type="primary">
<span>{{name}}<el-icon style="margin-left: 8px; margin-top: 1px"><ArrowDown /></el-icon></span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item @click="out()">退出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
import { reactive, toRefs } from "vue";
import { Index } from "../network/index";
import { useRouter } from "vue-router";
import { ElMessage } from 'element-plus';
export default {
name: "App",
setup() {
// 获取左侧菜单和用户信息
const state = reactive({
isCollapse: false,
name : "",
menu : []
});
// 读取保存在缓存中的用户uid信息
let ticket = window.localStorage.getItem('ticket');
// 如果没有获取到登录信息,就跳转
const router = useRouter();
if(!ticket){
router.push({
path: "/"
});
}
// console.log(uid);
Index({ticket:ticket}).then( (e) => {
if(e.data.code == 1){
alert(e.data.msg);
router.push({
path: "/"
});
} else if(e.data.code == 2){
alert(e.data.msg);
} else{
state.menu = e.data.data.menu;
}
state.name = e.data.data.name;
console.log(state);
console.log(e.data);
ElMessage('登录成功');
})
const out = ()=>{
window.localStorage.setItem('ticket','');
ElMessage('退出成功');
setTimeout( ()=>{
router.push({
path : "/"
});
}, 500 )
}
return {
...toRefs(state),
out,
};
}
};
</script>
<style>
body,
html{
margin : 0px 0px;
height: 100%;
}
a {
text-decoration: none;
}
.layout {
background-color: #f0f2f5;
}
.layout .el-header {
position: relative;
background-color: white;
color: var(--el-text-color-primary);
}
.layout aside {
color: var(--el-text-color-primary);
background: #001529;
}
.layout .el-menu {
border-right: none;
}
.layout .el-main {
margin: 30px 10px;
background-color: white;
}
.layout .toolbar {
display: inline-flex;
align-items: center;
justify-content: center;
height: 100%;
right: 20px;
}
aside {
position: relative;
}
.flexible {
background-color: #002140;
text-align: center;
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 200px;
min-height: 100vh;
}
.layout aside .logo .router {
display: flex;
justify-content: space-evenly;
align-items: center;
animation-duration: 0.1s;
overflow: hidden;
text-decoration: none;
padding-left: 1px;
position: relative;
left: 2px;
}
.layout aside .logo .router h1 {
margin-left: 10px;
color: aliceblue;
overflow: hidden;
}
.layout aside .logo .router img {
padding-left: 5px;
width: 48px;
height: 48px;
}
</style>
3、Ticket.php
<?php
namespace ouyangke;
/**
* ticket
* @author ouyangke
*/
class Ticket {
/**
* 创建ticket
*
* @param integer $uid 用户id
* @param integer $bind 关键词
* @param number $time 有效期
* @param string $durable
* @return multitype:number string
*/
public static function create($uid, $bind='ouyangke',$time=7*24*60*60, $durable = false) {
$expire = time() + $time;
// 获取key
$key = self::_genKey($uid, $bind, $expire);
// 生成票据 ticket
$ticket = self::_buildTicket($bind, $uid, $key, $expire, $durable);
return $ticket;
// return array('ticket' => $ticket, 'expire_time' => $expire);
}
/**
* 获取ticket信息
*
* @param integer $ticket
* @param boolean $checked
* @return Ambigous <mixed, NULL, multitype:number >
*/
public static function get($ticket, $bind='ouyangke', $checked = false) {
$checked || self::checkFormat($ticket);
$uid = 0;
$key = 0;
$expire = 0;
$durable = false;
$info = self::_parseTicket($ticket, $bind, $uid, $key, $expire, $durable);
if (time() < $expire) {
$info = array();
$info['uid'] = $uid;
$info['expire'] = $expire;
return $uid;
return $info;
}
return false;
}
/**
* 生成ticket
* @param string $bind
* @param integer $uid
* @param integer $key
* @param integer $expire
* @param boolean $durable
* @return string
*/
protected static function _buildTicket($bind, $uid, $key, $expire, $durable = false) {
// decbin 函数把十进制数转换为二进制数
$uBit = decbin($uid);
// strlen 函数返回字符串的长度
$uLen = strlen($uBit);
// sprintf 把百分号(%)符号替换成一个作为参数进行传递的变量
$eBit = sprintf('%032b', $expire);
$kBit = sprintf('%032b', $key);
// mt_rand 生成随机数
// uniqid 生成一个唯一的 ID
// md5 函数计算字符串的 MD5 散列
// substr 函数返回字符串的一部分
// base_convert 把十六进制数转换为八进制数
$rBit = sprintf('%058s%05b%d', substr(base_convert(substr(md5(uniqid(mt_rand(), true)), mt_rand(0, 16), 16), 16, 2), 0, 58), $uLen % 32, $durable ? 1 : 0);
$cBit = sprintf('%032b', crc32($uBit . $eBit . $kBit . $rBit . $bind));
$uBit .= substr(sprintf('%032b', mt_rand()), $uLen - 32);
$bin = '';
for ($i = 0; $i < 32; $i++) {
$bin .= $rBit[$i * 2];
$bin .= $eBit[$i];
$bin .= $kBit[$i];
$bin .= $rBit[$i * 2 + 1];
$bin .= $uBit[$i];
$bin .= $cBit[$i];
}
// bindec 函数把二进制转换为十进制。
// chr 函数从指定的 ASCII 值返回字符
// str_split 函数把字符串分割到数组中
// array_map 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新的值的数组。
// implode 函数返回一个由数组元素组合成的字符串。
// base64_encode 函数用base64加密
return strtr(base64_encode(implode('', array_map(function($item){ return chr(bindec($item)); }, str_split($bin, 8)))), '+/', '-_');
}
/**
* 解析Ticket
*
* @param string $ticket
* @param string $bind
* @param integer $uid
* @param integer $key
* @param integer $expire
* @param boolean $durable
* @return boolean
*/
protected static function _parseTicket($ticket, $bind, &$uid = NULL, &$key = NULL, &$expire = NULL, &$durable = NULL) {
$rBit = '';
$eBit = '';
$kBit = '';
$uBit = '';
$cBit = '';
// strtr 函数转换字符串中特定的字符
// base64_decode 函数用base64解密
// str_split 函数把字符串分割到数组中
// sprintf 把百分号(%)符号替换成一个作为参数进行传递的变量
// array_map 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新的值的数组
// implode 函数返回一个由数组元素组合成的字符串
$bin = implode('', array_map(function($item){ return sprintf('%08b', ord($item)); }, str_split(base64_decode(strtr($ticket, '-_', '+/')), 1)));
for ($i = 0; $i < 192; $i += 6) {
$rBit .= $bin[$i];
$eBit .= $bin[$i + 1];
$kBit .= $bin[$i + 2];
$rBit .= $bin[$i + 3];
$uBit .= $bin[$i + 4];
$cBit .= $bin[$i + 5];
}
// substr 函数返回字符串的一部分
// bindec 函数把二进制转换为十进制
$uLen = bindec(substr($rBit, 58, 5));
if ($uLen < 32) {
$uBit = substr($uBit, 0, $uLen);
}
// crc32 函数计算字符串的 32 位 CRC(循环冗余校验)
//32位系统会产生整型溢出,必需输出格式化
// bindec 函数把二进制转换为十进制
// sprintf 把百分号(%)符号替换成一个作为参数进行传递的变量
if (sprintf('%u', crc32($uBit . $eBit . $kBit . $rBit . $bind)) == bindec($cBit)) {
$uid = bindec($uBit);
if ($uid > 0) {
$expire = bindec($eBit);
$key = bindec($kBit);
$durable = ($rBit[63] === '1');
return true;
}
}
return false;
}
/**
* 生成key
*
* @param integer $uid
* @param string $bind
* @param integer $expire
* @return integer
*/
protected static function _genKey($uid, $bind, $expire) {
// sprintf 把百分号(%)符号替换成一个作为参数进行传递的变量
// md5 函数计算字符串的 MD5 散列
// crc32 函数计算字符串的 32 位 CRC(循环冗余校验)
return crc32(md5(sprintf('%d|%s|%d', $uid, $bind, $expire), true));
}
/**
* 发送ticket http头
*
* @param string $ticket
* @param integer $uid
* @param integer $ttl
*/
protected static function _headerTicket($ticket, $uid, $ttl) {
header(sprintf('Set-Ticket: %s; uid=%d; expires=%s; Max-Age=%d', $ticket, $uid, Request::httpDate(time() + $ttl), $ttl));
}
/**
* 判断格式是否正确
*
* @param string $ticket
* @return boolean
*/
protected static function _isTicket($ticket) {
return strlen($ticket) == 32 && strspn($ticket, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_') == 32;
}
/**
* 检查格式是否正确
*
* @param string $ticket
*/
public static function checkFormat($ticket) {
if (!self::_isTicket($ticket)) {
return false;
}
}
}
4、Login.php文件代码
<?php
namespace app\admin\controller;
use think\facade\Db;
use ouyangke\Ticket;
class Login
{
public function index()
{
// 跨域请求
header("Access-Control-Allow-Origin:*");
// 一个接口有3段
// 1、获取传值的数据,并且检查这些信息(非必须)
// 2、通过传值进行数据查询,并处理这些数据(非必须),可以自己组装数据
// 3、返回查询的数据结果(必须)
$account = input('post.account');
$password = input('post.password');
$password = md5($password);
$user = Db::table('bew_admin_user')->where('account', $account)->find();
//print_r($user);
if(empty($user)){
echo json_encode(['code'=>1, 'msg'=>'账号不存在']);
exit;
}
if($user['password'] != $password){
echo json_encode(['code'=>1, 'msg'=>'密码错误']);
exit;
}
$user['ticket'] = Ticket::create($user['uid']);
echo json_encode(['code'=>0,'msg'=>'成功','data'=>$user]);
}
}
4、User.vue
<template>
<div>
<el-space wrap style="margin-bottom:20px;">
<el-input v-model="data.search" size="small" placeholder="Type to search" />
<el-button type="" @click="search()">搜索</el-button>
</el-space>
<el-space wrap>
<el-button type="" @click="add()">添加</el-button>
</el-space>
<el-table
:data="data.table"
border
style="width: 100%"
@select="select"
>
<!--
<el-table-column align="right">
</el-table-column>
<el-table-column label="选择" type="selection" />-->
<el-table-column prop="uid" label="ID" min-width="50" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="account" label="账号" />
<el-table-column prop="group" label="部门" />
<el-table-column prop="phone" label="手机号" />
<el-table-column prop="qq" label="QQ">
</el-table-column>
<el-table-column prop="sex" label="性别">
<!--插槽-->
<!-- scope 相当于循环里的一次数据
foreach ( $data['table] as $v)
scope.row 就是相当于是 $v
-->
<template #default="scope">
<span v-if="scope.row.sex == 'mimi'">
保密
</span>
<span v-else-if="scope.row.sex == 'nan'">
男
</span>
<span v-else-if="scope.row.sex == 'nv'">
女
</span>
</template>
</el-table-column>
<el-table-column prop="uid" label="修改" width="160px;">
<template #default="scope">
<el-space wrap>
<!--传点击这条数据的( scope.row )-->
<el-button type="warning" @click="add(scope.row)">修改</el-button>
</el-space>
<el-space wrap>
<el-button type="danger" @click="del(scope.row)">删除</el-button>
</el-space>
</template>
</el-table-column>
</el-table>
<el-pagination
layout="prev, pager, next"
:total="data.total"
:page-size="5"
:default-current-page="1"
@current-change="fun"
/>
<!--
total:总条数
page-size:一页显示多少条
-->
<!--添加/修改 弹窗-->
<el-dialog v-model="data.add_form" :title="data.title">
<el-form :model="form" label-width="120px">
<el-form-item label="账号">
<el-input v-model="form.account" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password" />
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="部门">
<el-select v-model="form.group_id" class="m-2" placeholder="Select" size="large">
<el-option :label="item.group_name" :value="item.group_id" v-for="(item,index,key) in data.group" />
</el-select>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="QQ号">
<el-input v-model="form.qq" />
</el-form-item>
<el-form-item label="性别">
<el-select v-model="form.sex" class="m-2" placeholder="Select" size="large">
<el-option label="男" value="nan" />
<el-option label="女" value="nv" />
<el-option label="保密" value="mimi" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="data.add_form = false">取消</el-button>
<el-button type="primary" @click="add_form_json()">
{{ data.title }}
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { reactive } from "vue"; // 引入动态创建
import { UserLists , UserAdd ,UserDel } from "../network/index";
export default{
setup () {
// 展示数据
const data = reactive({
table : [],
total : 0,
group : [],
search : '',
add_form : false,
title : '添加',
});
// 展示的请求接口
UserLists().then( (e)=>{
data.table = e.data.data.user;
data.total = e.data.data.count;
data.group = e.data.data.group;
console.log(data.table);
})
// 选择事件
const select = (selection,row)=>{
console.log(selection);
console.log(row);
}
// 翻页方法
const fun = (p) => {
UserLists({p:p}).then( (e)=>{
data.table = e.data.data.user;
data.total = e.data.data.count;
})
// Index.php接收传值
}
// 搜索方法
const search = () => {
UserLists({search:data.search}).then( (e)=>{
data.table = e.data.data.user;
data.total = e.data.data.count;
})
}
// 添加 修改
// 展开form表单
const form = reactive({
uid : 0,
account: '',
password: '',
name : '',
group_id: '',
phone : '',
qq: '',
sex: 'nan',
})
// 添加方法,如果为真,打开表单
// 点击接收传uid数据,若有
const add = (e) => {
console.log(e);
data.add_form = true;
if(e){
form.uid = e.uid;
form.account = e.account;
form.password = '';
form.name = e.name;
form.group_id = e.group_id;
form.phone = e.phone;
form.qq = e.qq;
form.sex = e.sex;
data.title = '修改';
}else{
form.uid = 0;
form.account = '';
form.password = '';
form.name = '';
form.group_id = '';
form.phone = '';
form.qq = '';
form.sex = 'nan';
data.title = '添加';
}
}
// 确定提交添加的数据
const add_form_json = () => {
// 需要把数据提交给php接口
// console.log(form);
UserAdd(form).then((e) =>{
// console.log(e);
alert(e.data.msg);
if(e.data.code == 0){
UserLists().then( (e)=>{
// 添加成功后自动刷新数据
data.table = e.data.data.user;
data.total = e.data.data.count;
data.group = e.data.data.group;
console.log(data.table);
// 关闭添加表单
data.add_form = false;
})
}
})
}
// 删除
const del = (e) => {
UserDel({uid:e.uid}).then( (res) => {
alert(res.data.msg);
if( res.data.code == 0 ){
UserLists().then( (e)=>{
// 添加成功后自动刷新数据
data.table = e.data.data.user;
data.total = e.data.data.count;
data.add_form = false;
})
}
})
}
// 数据暴露出去
return {
data,
select,
fun,
search,
add,
form,
add_form_json,
del,
}
}
}
</script>
5、Index.php
<?php
namespace app\admin\controller;
use app\BaseController;
use think\facade\Db;
use ouyangke\Ticket;
class Index extends BaseController
{
public function __construct(){
// 跨域请求
header("Access-Control-Allow-Origin:*");
}
// 首页左侧菜单
public function index(){
$ticket = input('post.ticket');
$uid = Ticket::get($ticket);
if(empty($uid)){
echo json_encode([
'code' => 1,
'msg' => '用户已过期'
]);
exit;
}
$user = Db::table('bew_admin_user')->where('uid',$uid)->find();
if(empty($user)){
echo json_encode([
'code' => 1,
'msg' => '请重新登录',
'data' => [
'name' => $user['name']
]
]);
exit;
}
$group = Db::table('bew_admin_user_group')->where('group_id',$user['group_id'])->find();
if(empty($group)){
echo json_encode([
'code' => 2,
'msg' => '用户还没添加组,请联系管理员',
'data' => [
'name' => $user['name']
]
]);
exit;
}
// 状态为1的全部展示出来,但是1级和2级的都在一起
$tmp = Db::table('bew_admin_sys_menu')->where('status',1)->where('mid','in',json_decode($group['rights'],true))->order('parent_id')->select()->toArray();
//print_r($tmp);
$menu = [];
foreach ($tmp as $v){
if($v['parent_id'] == 0){
// 将 menu为1000或者100的下标 保存到 这个菜单
$menu[ $v['mid'] ] = $v;
} else {
// 现在时二级菜单,它的上一级,就是parent_id,找到它自己的parent_id
// $v['mid'] 一级菜单的下标 $v['parent_id'] 二级菜单的上级下标
$menu[ $v['parent_id'] ] ['son'] [] = $v;
}
}
echo json_encode([
'code' => 0,
'msg' => '成功',
'data' => [
'menu' => $menu,
'name' => $user['name'],
]
]);
}
/*
public function index()
{
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:) </h1><p> ThinkPHP V' . \think\facade\App::version() . '<br/><span style="font-size:30px;">16载初心不改 - 你值得信赖的PHP框架</span></p><span style="font-size:25px;">[ V6.0 版本由 <a href="https://www.yisu.com/" target="yisu">亿速云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ee9b1aa918103c4fc"></think>';
}
*/
// =======================管理员方法===============================
// 管理员列表
public function UserLists(){
$p = input('post.p',1);
$search = input('post.search','');
// 在查询数出来的时候,
// $user = Db::table('xpcms_admin')->select()->toArray();
// limit方法、pgae方法
// count方法统计数据库有多少条数据
$where = [];
if(!empty($search)){
$where1 = [['account','like','%'.$search.'%']];
$where2 = [['name','like','%'.$search.'%']];
$where3 = [['phone','like','%'.$search.'%']];
$where = [$where1,$where2,$where3];
}
$count = Db::table('bew_admin_user')->whereOr($where)->where('status','<>','2')->count();
$user = Db::table('bew_admin_user')->whereOr($where)->where('status','<>','2')->page($p,5)->select()->toArray();
// toArray 数组形式,显示时间戳
// 查询所有组
$tmp = Db::table('bew_admin_user_group')->where('status',1)->select()->toArray();
$group = [];
foreach($tmp as $v){
$group[$v['group_id']] = $v;
}
foreach($user as &$u){
$u['time_add_s'] = date('Y-m-d H:i:s',$u['time_add']);
if($u['group_id'] != 0 ){
$u['group'] = $group [ $u['group_id'] ] ['group_name'];
}
}
$arr = [
'count' => $count,
'user' => $user,
'group' => $group
];
// php接口、只能有一次输出结果值
echo json_encode([
'code' => 0,
'msg' => '成功',
'data' => $arr
]);
}
// 添加&修改管理员,接收数据
public function UserAdd(){
$post = input('post.');
$data = [
'account' => $post['account'],
'name' => $post['name'],
'group_id' => $post['group_id'],
'phone' => $post['phone'],
'qq' => $post['qq'],
'sex' => $post['sex'],
'time_last' => time(),
];
// 查询单条数据
$user = Db::table('bew_admin_user')->where('account',$post['account'])->find();
if ( $post['uid'] == 0 ){
// 判断查询出来的用户是否存在,若存在就退出,否则新建
if(!empty($user)){
echo json_encode([
'code' => 1,
'msg' => '账号已存在'
]);
exit;
}
// 如果为0.就添加
$data['password'] = md5($post['password']);
$data['time_add'] = time();
$ret = Db::table('bew_admin_user')->insert($data);
} else {
// 判断查询出来的用户名是否存在,且是不等于查询出来的uid,则修改
if(!empty($user) && $post['uid'] != $user['uid']){
echo json_encode([
'code' => 1,
'msg' => '账号已存在'
]);
exit;
}
// 如果不为0 就修改
if(!empty($post['password'])){
$data['password'] = md5($post['password']);
}
$ret = Db::table('bew_admin_user')->where('uid', $post['uid'])->update($data);
}
// 添加&修改 后输出结果
if( $post['uid'] == 0 ){
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '添加失败,请重试'
]);
exit;
};
echo json_encode([
'code' => 0,
'msg' => '添加成功'
]);
} else {
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '修改失败,请重试'
]);
exit;
};
echo json_encode([
'code' => 0,
'msg' => '修改成功'
]);
}
}
// 删除方法
public function UserDel(){
$uid = input('post.uid',0);
if($uid ==0){
echo json_encode([
'code' => 1,
'msg' => '请选择要删除的账号'
]);
exit;
}
$del = Db::table('bew_admin_user')->where('uid', $uid)->update([
'status'=>2,
'time_last' => time(),
]);
if(empty($del)){
echo json_encode([
'code' => 1,
'msg' => '删除失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '删除成功'
]);
exit;
}
// =======================管理组方法===============================
// 管理组列表接口
public function GroupLists(){
$p = input('post.p',1);
$search = input('post.search','');
$where = [];
if(!empty($search)){
$where[] = ['group_name','like','%'.$search.'%'];
}
$count = Db::table('bew_admin_user_group')->where($where)->count();
$group = Db::table('bew_admin_user_group')->where($where)->page($p,8)->select()->toArray();
foreach($group as &$u){
$u['time_add_s'] = date('Y-m-d H:i:s',$u['time_add']);
}
// =================================================================================================
// 新增权限管理
// 状态为1的全部展示出来,但是1级和2级的都在一起
$tmp = Db::table('bew_admin_sys_menu')->where('status',1)->order('parent_id')->select()->toArray();
$menu = [];
foreach ($tmp as $v){
if($v['parent_id'] == 0){
// 将 menu为1000或者100的下标 保存到 这个菜单
$menu[ $v['mid'] ] = $v;
} else {
// 现在时二级菜单,它的上一级,就是parent_id,找到它自己的parent_id
// $v['mid'] 一级菜单的下标 $v['parent_id'] 二级菜单的上级下标
$menu[ $v['parent_id'] ] ['son'] [] = $v;
}
}
// =================================================================================================
$arr = [
'count' => $count,
'group' => $group,
'menu' => $menu,
];
// php接口、只能有一次输出结果值
echo json_encode([
'code' => 0,
'msg' => '成功',
'data' => $arr
]);
}
// 添加管理组
public function GroupAdd(){
$post = input('post.');
$group = Db::table('bew_admin_user_group')->where('group_name', $post['group_name'])->find();
if($post['group_id'] == 0){
if(!empty($group)){
echo json_encode([
'code' => 1,
'msg' => '添加失败,部门已存在'
]);
exit;
}
$ret = Db::table('bew_admin_user_group')->insert([
'group_name' => $post['group_name'],
'status' => $post['status'],
'rights' => json_encode($post['checkList']),
'time_add' => time()
]);
} else {
if(!empty($group) && $group['group_id'] != $post['group_id']){
echo json_encode([
'code' => 1,
'msg' => '修改失败,部门已存在'
]);
exit;
}
$ret = Db::table('bew_admin_user_group')->where('group_id',$post['group_id'])->update([
'group_name' => $post['group_name'],
'status' => $post['status'],
'rights' => json_encode($post['checkList']),
'time_add' => time(),
'time_last' => time()
]);
}
if($post['group_id'] == 0 ){
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '添加失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '添加成功'
]);
} else {
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '修改失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '修改成功'
]);
}
}
// 删除管理组
public function GroupDel(){
$group_id = input('post.group_id',0);
if($group_id == 0){
echo json_encode([
'code' => 1,
'msg' => '请选择要删除的管理组'
]);
exit;
}
$ret = Db::table('bew_admin_user_group')->where('group_id',$group_id)->update([
'status' => 0,
'time_last' => time()
]);
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '删除失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '删除成功'
]);
}
// =======================菜单方法===============================
/**
* 一般分php文件,是根据功能来分
* 用户相关放一个文件,并且统一处理
* 用户个人中心、订单列表、订单详情、充值功能、登录日志等
* 登录、注册放在一个文件,用户的未登录文件,统一处理的
*
* @return void
*/
public function MenuLists(){
$p = input('post.p',1);
// 接收数据 mid
$mid = input('post.mid',0);
$count = Db::table('bew_admin_sys_menu')->where('parent_id',$mid)->count();
$menu = Db::table('bew_admin_sys_menu')->where('parent_id',$mid)->order('sort DESC')->page($p,5)->select()->toArray();
//需要把一级菜单获取出来,作为添加时选择项
$ss = Db::table('bew_admin_sys_menu')->where('parent_id',0)->where('type',0)->order('sort DESC')->select()->toArray();
$arr = [
'menu' => $menu,
'count' => $count,
'ss' => $ss,
];
echo json_encode([
'code' => 0,
'msg' => '成功',
'data' => $arr
]);
}
// 添加 修改 菜单方法
public function MenuAdd(){
$post = input('post.');
$data = [
'label' => $post['label'],
'parent_id' => $post['parent_id'],
'type' => $post['type'],
'src' => $post['src'],
'sort' => $post['sort'],
'status' => $post['status'],
'time_last' => time(),
];
if($post['mid'] == 0){
$ret = Db::table('bew_admin_sys_menu')->insert($data);
} else {
$ret = Db::table('bew_admin_sys_menu')->where('mid',$post['mid'])->update($data);
}
if($post['mid'] == 0 ){
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '添加失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '添加成功'
]);
} else {
if(empty($ret)){
echo json_encode([
'code' => 1,
'msg' => '修改失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '修改成功'
]);
}
}
// 删除菜单方法
public function MenuDel(){
$mid = input('post.mid',0);
if($mid == 0){
echo json_encode([
'code' => 1,
'msg' => '请选择要删除的菜单'
]);
exit;
}
$del = Db::table('bew_admin_sys_menu')->where('mid',$mid)->update([
'status' => 2,
'time_last' => time(),
]);
if(empty($del)){
echo json_encode([
'code' => 1,
'msg' => '删除失败,请重试'
]);
exit;
}
echo json_encode([
'code' => 0,
'msg' => '删除菜单成功'
]);
}
public function hello($name = 'ThinkPHP6')
{
return 'hello,' . $name;
}
}
6、运行截图6.1、登录退出
6.2、用户部门