功能部分
登陆:
注册:手机验证码,密码加密存储
修改密码:修改时间存储
删除用户:
1.功能效果图
2.数据库存储
3.redis desktop manager可视化管理工具,验证码存储
4.代码部分目录
一、详细代码
1.indeAjax.html前台页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
form {
width: 300px;
margin: 30px;
padding: 30px 50px 50px;
border: 1px solid #dcdcdc;
float: left;
}
label {
display: flex;
line-height: 30px;
margin-bottom: 20px;
}
span {
width: 100px;
}
input {
flex: 1;
border: 1px solid #dcdcdc;
}
input[type="submit"] {
color: #fff;
background: #f43553;
width: 100%;
height: 40px;
line-height: 40px;
}
div {
display: inline-block;
width: 30%;
}
</style>
</head>
<body>
<div class="userLoginBox">
<h2>登录</h2>
<label for="">
<span>用户名</span>
<input type="text" name="name" />
</label>
<label for="">
<span>密码</span>
<input type="password" name="password" />
</label>
<input type="submit" id="userLogin" value="提交">
</div>
<div class='userRegisterBox'>
<h2>注册</h2>
<label for="">
<span>用户名</span>
<input type="text" name="name" />
</label>
<label for="">
<span>真实姓名</span>
<input type="text" name="realname" />
</label>
<label for="">
<span>密码</span>
<input type="password" name="password" />
</label>
<label for="">
<span>输入手机号</span>
<input type="tel" id="PhoneNumbers" name="PhoneNumbers" />
</label>
<label for="">
<span>输入验证码</span>
<input type="text" id="getRegisterCode" /><button id="bt01">发送验证码</button>
</label>
<input type="submit" id="userRegister" value="提交">
</div>
<div class='userUpdatePasswordBox'>
<h2>修改密码</h2>
<label for="">
<span>用户名</span>
<input type="text" name="name" />
</label>
<label for="">
<span>旧密码</span>
<input type="text" name="oldPassword" />
</label>
<label for="">
<span>新密码</span>
<input type="text" name="newPassword" />
</label>
<label for="">
<span>再输入新密码</span>
<input type="text" name="againPassword" />
</label>
<input type="submit" id="userUpdatePassword" value="提交">
</div>
<div class="userDeleteUserBox">
<h2>删除用户</h2>
<label for="">
<span>用户名</span>
<input type="text" name="name" />
</label>
<label for="">
<span>密码</span>
<input type="password" name="password" />
</label>
<input type="submit" id="userDeleteUser" value="提交">
</div>
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<!-- <script type="text/javascript" src="/js/sha512.js"></script> -->
<script src="https://cdn.bootcdn.net/ajax/libs/js-sha512/0.8.0/sha512.js"></script>
<script>
// 登陆
$('#userLogin').on('click', function () {
console.log($('.userLoginBox').find('input[name="name"]').val());
var $username = $('.userLoginBox').find('input[name="name"]').val();
var $password = $('.userLoginBox').find('input[name="password"]').val();
$password = encryptionPassWord($username, $password) // 加密-密码
$.ajax({
type: "GET",
url: "http://localhost:8088/user/login",
data: {
name: $username,
password: $password
},
dataType: "json",
success: function (data) {
if (data.code == 200) {
console.log(data)
}
},
error: function (jqXHR) {
console.log("Error: " + jqXHR.status);
}
});
});
// 注册
$('#userRegister').on('click', function () {
var $username = $('.userRegisterBox').find('input[name="name"]').val();
var $realname = $('.userRegisterBox').find('input[name="realname"]').val();
var $password = $('.userRegisterBox').find('input[name="password"]').val();
$password = encryptionPassWord($username, $password) // 加密-密码
var $phoneNumbers = $('#PhoneNumbers').val();
var $getRegisterCode = $('#getRegisterCode').val();
if (!isPhoneNum($phoneNumbers)){
console.log('手机号码输入不正确!');
return false;
};
if(!$getRegisterCode){
console.log('请输入验证码');
return false;
}else{
register($username, $realname, $password, $phoneNumbers, $getRegisterCode);
}
function register($username, $realname, $password, $phoneNumbers, $getRegisterCode) {
$.ajax({
type: "POST",
url: "http://localhost:8088/user/register",
data: {
name: $username,
realname: $realname,
password: $password,
phoneNumbers: $phoneNumbers,
getRegisterCode: $getRegisterCode
},
dataType: "json",
success: function (data) {
if (data.code == 200) {
console.log(data)
}
},
error: function (jqXHR) {
console.log("Error: " + jqXHR.status);
}
});
};
});
// 修改密码
$('#userUpdatePassword').on('click', function () {
console.log($('.userUpdatePasswordBox').find('input[name="name"]').val());
var $username = $('.userUpdatePasswordBox').find('input[name="name"]').val();
var $oldPassword = $('.userUpdatePasswordBox').find('input[name="oldPassword"]').val();
$oldPassword = encryptionPassWord($username, $oldPassword) // 加密-密码
var $newPassword = $('.userUpdatePasswordBox').find('input[name="newPassword"]').val();
var $againPassword = $('.userUpdatePasswordBox').find('input[name="againPassword"]').val();
$newPassword = encryptionPassWord($username, $newPassword) // 加密-密码
$againPassword = encryptionPassWord($username, $againPassword) // 加密-密码
$.ajax({
type: "POST",
url: "http://localhost:8088/user/updatePassword",
data: {
name: $username,
oldPassword: $oldPassword,
newPassword: $newPassword,
againPassword: $againPassword
},
dataType: "json",
success: function (data) {
if (data.code == 200) {
console.log(data)
}
},
error: function (jqXHR) {
console.log("Error: " + jqXHR.status);
}
});
});
// 删除用户
$('#userDeleteUser').on('click', function () {
console.log($('.userDeleteUserBox').find('input[name="name"]').val());
var $username = $('.userDeleteUserBox').find('input[name="name"]').val();
var $password = $('.userDeleteUserBox').find('input[name="password"]').val();
$password = encryptionPassWord($username, $password) // 加密-密码
$.ajax({
type: "GET",
url: "http://localhost:8088/user/deleteUser",
data: {
name: $username,
password: $password
},
dataType: "json",
success: function (data) {
if (data.code == 200) {
console.log(data)
}
},
error: function (jqXHR) {
console.log("Error: " + jqXHR.status);
}
});
});
// 加密-密码
function encryptionPassWord($userId, $userPwd) {
var $vi = '1';
return sha512($userId + $userPwd + $vi);
};
// 短信验证码
var bt01 = document.getElementById("bt01");
bt01.onclick = function () {
bt01.disabled = true; //当点击后倒计时时候不能点击此按钮
var time = 60; //倒计时5秒
var timer = setInterval(fun1, 1000); //设置定时器
var $PhoneNumber = $('#PhoneNumbers').val();
$.ajax({
type: "POST",
url: "http://localhost:8088/user/getRegisterCode",
data: {
PhoneNumber: $PhoneNumber
},
dataType: "json",
success: function (data) {
if (data.code == 200) {
console.log(data)
}
},
error: function (jqXHR) {
console.log("Error: " + jqXHR.status);
}
});
function fun1() {
time--;
if (time >= 0) {
bt01.innerHTML = time + "s后重新发送";
} else {
bt01.innerHTML = "重新发送验证码";
bt01.disabled = false; //倒计时结束能够重新点击发送的按钮
clearTimeout(timer); //清除定时器
time = 60; //设置循环重新开始条件
}
};
};
// 手机号码验证
function isPhoneNum(str) {
return /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/.test(str)
}
</script>
</body>
</html>
2.index.js node启动文件,端口监听
const { app, pool } =require('./connect')
const user = require('./router/user')
app.all('*', (req, res, next) => {
//这里处理全局拦截,一定要写在最上面
next()
})
app.get('/', (req,res) => { //首页路由
res.sendFile(__dirname+'/'+'index.html')
});
app.get('/index.html', (req,res) => { //首页路由
res.sendFile(__dirname+'/'+'index.html')
});
app.get('/indexAjax.html', (req,res) => { //首页路由
res.sendFile(__dirname+'/'+'indexAjax.html')
});
app.all('/', (req, res) => {
pool.getConnection((err, conn) => {
res.json({ type: 'test'})
pool.releaseConnection(conn) // 释放连接池,等待别的连接使用
})
})
app.use('/user', user)
app.listen(8088, () => {
console.log('服务启动','localhost:8088')
})
3.connect.js,数据库连接
// 创建连接池
const mysql = require('mysql');
const express = require('express');
const app = express();
const router = express.Router();
// 解析参数
const bodyParser = require('body-parser');
// json请求
// app.use(bodyParser.json());
// //表单请求
// app.use(bodyParser.urlencoded({extended: false}));
//引用bodyParser 这个不要忘了写
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
// 设置跨域访问
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1');
// res.header("Content-Type", "application/json;charset=utf-8");
next();
});
/**
* 配置mysql
*/
const option = {
host: 'localhost',
user: 'root',
password: 'root',
port: '3306',
database: 'nodecms',
connecTimeout: 500,//连接超时
multipleStatements: false//是否允许一个query中包含多条sql语句
};
let pool;
repool();
function Res ({code = 200, msg = '', data = {}}){
this.code = code;
this.msg = msg;
this.data = data;
};
function resJson (_res, result) {
return _res.json(new Res(result))
};
//断线重连机制
function repool() {
//创建连接池
pool = mysql.createPool({
...option,
waitForConnection: true,//当无连接池可用时,等待(true) 还是抛错(false)
connectionLimit: 100,//连接限制
queueLimit: 0//最大连接等待数(0为不限制)
});
pool.on('error', err => {
err.code === 'PROTOCOL_CONNECTION_LOST' &&setTimeout(repool, 2000);
});
app.all('*', (_,__, next) => {
pool.getConnection(err => {
err && setTimeout(repool, 2000) || next();
});
});
};
module.exports = {app, pool, router, resJson}
4.db/userSQL.js,sql语句【接口部分】
// 操作数据库语句-用户增删改查
const userSQL = {
queryAll: 'select * from user', // 查询所有用户
queryByName: 'select * from user where username=?', // 通过用户名索引查询用户
queryByNamePassword: 'select * from user where username=? and password=?', // 通过用户名和密码索引查询用户
insert: 'insert into user set ?', // 插入新用户
updateUser: 'update user set ? where username=?',// 更新用户信息
deleteUser: 'delete from user where username=?' // 删除用户
}
module.exports = userSQL
5.router/user.js,接口文件
// 用户操作接口
const {
pool,
router,
resJson
} = require('../connect');
const userSQL = require('../db/userSQL');
const moment = require('moment');
const smsCode = require("./smscode.js");
const redisHelper = require("./redis.js");
/**
* 获取手机验证码
*/
router.post('/getRegisterCode', (req, res) => {
let mobile = req.body.PhoneNumber
console.log(mobile);
// 获取redis值
redisHelper.getString(mobile)
.then(result=>{
if(result){
let _data = {
msg: "验证码5分钟内有效",
code: 200 //str1是自行产生的手机验证码,返回到前端以做验证
}
return res.json(_data)
}else{
smsCode(res, mobile);//获取验证码
}
})
.catch(err=>{
console.log(err)
});
// 存储Redis缓存
// redisHelper.setString('mobile',mobile,60 * 3).then((res)=>{
// console.log('设置成功')
// }).catch((err=>{
// console.log('设置失败',err)
// }));
// 获取redis值
// redisHelper.getString('name')
// .then(result=>{
// console.log(result)
// return res.json(result)
// })
// .catch(err=>{
// console.log(err)
// });
});
/**
* 用户登录功能
*/
router.get('/login', (req, res) => {
let user = {
username: req.query.name,
password: req.query.password
};
let _res = res;
//判断参数是否为空
if (!user.username) {
return resJson(_res, {
code: -1,
msg: '用户名不能为空'
});
}
if (!user.password) {
return resJson(_res, {
code: -1,
msg: '密码不能为空'
});
}
let _data;
//从连接池获取连接
pool.getConnection((err, conn) => {
conn.query(userSQL.queryByNamePassword, [user.username, user.password], (e, result) => {
if (e) _data = {
code: -1,
msg: e
}
// 通过用户名和密码索引查询数据,用数据说明用户存在且密码正确,
// 只能返回登录成功,否则返回用户不存在或登录密码错误
console.log(result)
if (result && result.length) {
_data = {
msg: '登陆成功',
data: {
userInfo: {
usrename: user.username
}
}
}
} else {
_data = {
code: -1,
msg: '用户名不存在或登录密码错误'
}
}
resJson(_res, _data);
});
pool.releaseConnection(conn); //释放连接池,等待别的连接池使用
});
});
/**
* 注册用户功能
*/
router.post('/register', (req, res) => {
//获取前台页面传过来的参数
let user = {
username: req.body.name,
realname: req.body.realname,
password: req.body.password,
create_time: moment().format('YYYY-MM-DD HH:mm:ss'),
update_time: moment().format('YYYY-MM-DD HH:mm:ss')
}
let code = {
phoneNumbers: req.body.phoneNumbers,
getRegisterCode: req.body.getRegisterCode,
}
// 获取redis值
redisHelper.getString(code.phoneNumbers)
.then(result => {
if (result && code.getRegisterCode == result) {
console.log('验证码正确');
codeSucess();
} else {
console.log('ss')
let _data = {
msg: "验证码错误" + code.getRegisterCode,
code: 200 //str1是自行产生的手机验证码,返回到前端以做验证
}
res.send(_data);
}
})
.catch(err => {
let _data = {
msg: "验证码错误",
code: 200 //str1是自行产生的手机验证码,返回到前端以做验证
}
res.send(_data);
});
function codeSucess() {
let _res = res;
// 判断参数是否为空
if (!user.username) {
return resJson(_res, {
code: -1,
msg: '用户名不能为空'
});
}
if (!user.password) {
return resJson(_res, {
code: -1,
mgs: "密码不能为空"
});
}
let _data;
// 整合参数
// 从连接池获取连接
pool.getConnection((err, conn) => {
// 查询数据库该用户是否已存在
conn.query(userSQL.queryByName, user.username, (e, r) => {
if (e) _data = {
code: -1,
msg: e
}
if (r) {
// 判断用户列表是否为空
if (r.length) {
// 如不为空,这说明存在此用户
_data = {
code: -1,
msg: '用户存在'
}
} else {
// 插入用户信息
conn.query(userSQL.insert, user, (err, result) => {
if (result) {
_data = {
msg: '注册成功'
}
} else {
_data = {
code: -1,
msg: '注册失败'
}
}
});
}
}
setTimeout(() => {
// 把操作结果返回给当前页面
resJson(_res, _data);
}, 200);
});
pool.releaseConnection(conn); //释放连接池,等待别的连接池使用
});
}
});
/**
* 修改密码
*/
router.post('/updatePassword', (req, res) => {
let user = {
username: req.body.name,
oldPassword: req.body.oldPassword,
newPassword: req.body.newPassword,
againPassword: req.body.againPassword,
// create_time: moment().format('YYYY-MM-DD HH:mm:ss'),
update_time: moment().format('YYYY-MM-DD HH:mm:ss')
}
let _res = res;
// 判断参数是否为空
if (!user.username) {
return resJson(_res, {
code: -1,
msg: '用户名不能为空'
});
}
if (!user.oldPassword) {
return resJson(_res, {
code: -1,
msg: '旧密码不能为空'
});
}
if (!user.newPassword) {
return resJson(_res, {
code: -1,
msg: '新密码不能为空'
});
}
if (!user.againPassword || user.againPassword !== user.newPassword) {
return resJson(_res, {
code: -1,
msg: '请确认新密码或两次新密码不一致'
});
}
// 整合参数
// 从连接池获取连接
pool.getConnection((err, conn) => {
// 查询数据库该用户是否已经存在
conn.query(userSQL.queryByNamePassword, [user.username, user.oldPassword], (e, r) => {
if (e) _data = {
code: -1,
msg: e
}
if (r) {
//判断用户列表是否为空
if (r.length) {
//如不为空,则说明存在此用户且密码正确
conn.query(userSQL.updateUser, [{
password: user.newPassword,
update_time: user.update_time
}, user.username], (err, result) => {
console.log(err);
if (result) {
_data = {
msg: '密码修改成功'
}
} else {
_data = {
code: -1,
msg: '密码修改失败'
}
}
});
} else {
_data = {
code: -1,
msg: '用户不存在或旧密码输入错误'
}
}
}
setTimeout(() => {
// 把操作结果返回给前台页面
resJson(_res, _data);
}, 200);
});
pool.releaseConnection(conn); //释放连接池,等待别的连接使用
});
});
/**
* 删除用户
*/
router.get('/deleteUser', (req, res) => {
// 获取前台页面穿过来的参数
let user = {
username: req.query.name,
password: req.query.password,
};
let _res = res;
//判断参数是否为空
if (!user.username) {
return resJson(_res, {
code: -1,
msg: '用户名不能为空'
})
}
if (!user.password) {
return resJson(_res, {
code: -1,
msg: '密码不能为空'
});
}
let _data;
// 整合参数
// 从连接池获取连接
pool.getConnection((err, conn) => {
// 查询数据库该用户是否已经存在
conn.query(userSQL.queryByNamePassword, [user.username, user.password], (e, r) => {
if (e) _data = {
code: -1,
msg: e
};
if (r) {
// 判断用户列表是否为空
if (r.length) {
//如不为空,则说明存在此用户
conn.query(userSQL.deleteUser, user.username, (err, result) => {
if (err) _data = {
code: -1,
msg: e
}
if (result) {
_data = {
msg: '删除用户操作成功'
}
}
});
} else {
_data = {
code: -1,
msg: '用户不存在,操作失败'
}
}
}
setTimeout(() => {
//把操作结果返回给前台页面
resJson(_res, _data)
}, 200);
});
pool.releaseConnection(conn) // 释放连接池,等待别的连接使用
});
});
module.exports = router;
6.router/key.js,redis连接参数
module.exports = {
redis:{
url:'127.0.0.1',
port:6379,
password:'123456'
}
};
7.router/redis.js,存储、获取等方法
const redis = require('redis');
const config = require('./keys').redis
const client = redis.createClient(config.port, config.url); // 实例redis对象
//连接错误处理
client.on("error", err => {
console.log('redis connect err', err);
});
client.on('connect', () => {
console.log('redis connect success');
})
//验证redis
client.auth(config.password);
const redisHelper = {};
/**
* redisHelper setString function
* @param key
* @param value
* @param expire
*/
redisHelper.setString = (key, value, expire) => {
return new Promise((resolve, reject) => {
client.set(key, value, function (err, result) {
if (err) {
console.log(err);
reject(err);
}
if (!isNaN(expire) && expire > 0) {
client.expire(key, parseInt(expire));
}
resolve(result)
})
})
}
/**
* redisHelper getString function
* @param key
*/
redisHelper.getString = (key) => {
return new Promise((resolve, reject) => {
client.get(key, function (err, result) {
if (err) {
console.log(err);
reject(err)
}
resolve(result)
});
})
}
module.exports = redisHelper;
8.router/smscode.js,获取短信验证码【这里写了两种,一种是阿里云发送到手机,一种是测试用的】
//smscode.js
/**
* 阿里云短信验证码
*/
const Core = require('@alicloud/pop-core'); // 引入模块
const redisHelper = require("./redis.js");
let smsCode = (res, mobile) => {
var client = new Core({
accessKeyId: '***', // 你的阿里云短信服务accessKeyId
accessKeySecret: '***', // 你的阿里云短信服务accessKeySecret
endpoint: 'https://dysmsapi.aliyuncs.com',
apiVersion: '2017-05-25'
});
var Num = ""; // 随机6位数
for (var i = 0; i < 6; i++) {
let n = Math.floor(Math.random() * 10)
Num += n === 0 ? '0' : n;
}
var params = {
"RegionId": "cn-hangzhou",
"PhoneNumbers": mobile, // 电话号码
"SignName": "唐策网站验证码", // 你的短信签名
"TemplateCode": "****", // 你的短信模板代码
"TemplateParam": `{'code':${Num},'product':'test'}` // 短信模板变量对应的实际值,JSON格式
}
var requestOption = {
method: 'POST'
};
// 1.手机验证码发送
// client.request('SendSms', params, requestOption).then((result) => {
// console.log(JSON.stringify(result));
// res.send({
// msg:"ok",
// code: Num//str1是自行产生的手机验证码,返回到前端以做验证
// })
// }, (ex) => {
// console.log(ex);
// res.send(ex)
// });
// 2.测试
let _data = {
msg:"ok",
code: Num//str1是自行产生的手机验证码,返回到前端以做验证
}
res.send(_data);
// 存储Redis缓存
redisHelper.setString(mobile,Num,60*5).then((res)=>{
console.log('设置成功')
}).catch((err=>{
console.log('设置失败',err)
}));
}
module.exports = smsCode;
9.package.json,这是我的配置文件,送上了
{
"name": "db",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@alicloud/pop-core": "^1.7.10",
"body-parser": "^1.19.0",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"express": "^4.17.1",
"moment": "^2.29.1",
"mysql": "^2.18.1",
"redis": "^3.0.2",
"sms-code": "^0.1.2",
"tencentcloud-sdk-nodejs": "^4.0.30"
}
}
10.nodecms/user.slq,数据库/数据表
这里是数据表导出结果
-- phpMyAdmin SQL Dump
-- version 4.1.14
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: 2020-12-15 03:55:23
-- 服务器版本: 5.6.17
-- PHP Version: 5.5.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `nodecms`
--
-- --------------------------------------------------------
--
-- 表的结构 `user`
--
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(11) NOT NULL,
`realname` varchar(11) NOT NULL,
`password` varchar(255) NOT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
`extend1` varchar(255) NOT NULL COMMENT '扩展1',
PRIMARY KEY (`username`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
--
-- 转存表中的数据 `user`
--
INSERT INTO `user` (`id`, `username`, `realname`, `password`, `create_time`, `update_time`, `extend1`) VALUES
(6, '1', 'tang', 'fb131bc57a477c8c9d068f1ee5622ac304195a77164ccc2d75d82dfe1a727ba8d674ed87f96143b2b416aacefb555e3045c356faa23e6d21de72b85822e39fdd', '2020-12-14 15:40:39', '2020-12-14 15:40:39', ''),
(15, '2', 'tang', 'cc9aab6fee3af4f819209bf43e3bc6f8f02ecbf5d2f27815b9a2132d3dbbfe9ba72d6024794487c37affbc6828040ed74d3d2671bb962b44c95f9070d4e2db48', '2020-12-14 16:25:59', '2020-12-14 16:25:59', ''),
(16, '3', 'tang', '64a6ca7074f7c31c6bd8e5f4f0e690f595652f80fc7797e7ae8140731898650fe170ff53b2debd7380c50cd5a631cc79c66c813a8985e4ca1499307ff5360122', '2020-12-14 16:29:29', '2020-12-14 16:29:29', ''),
(8, '4', 'tang', '532d070987041f345225ca98c24bbfd024e20da2307b1538eef7b6d9d2d8357e3b376e0a99de4cbec873fe2f7182116dea5411a1c9fc018a7b3a7cc11458b675', '2020-12-14 15:49:14', '2020-12-14 15:49:14', ''),
(4, '5', 'tang', '19c7a8d2900e7eb43ad2e9cdaa64a5a574e6e039ca67897c26678e3f7b749433e3692a6c979e2b669f1ee6fa19f1fcaf8bba152805ca9c48123cfe5d1e303702', '2020-12-04 16:49:23', '2020-12-04 16:49:23', ''),
(9, '6', 'tang', 'dd03187dfdcc80b47ed97d1feff0cb797179389ec5c87af1e2591f7a67007d5e5ae0df9bdc4be045c7a1c080b316122b1224beffeddbdbfe7873cb747e2877fa', '2020-12-14 15:51:52', '2020-12-14 15:51:52', '');
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
说明:项目需要修改的地方请留言,共同进步。