【nodejs】大事件后台管理系统(四)——layui前端布局与改进

6. layui大事件项目

文件位置:1.Node.js零基础入门教程node.js—资料day8素材大事件项目
assets/js/baseAPI.js中修改统一请求根路径

6.1 调整接口名称

纯粹是因为之前本人手贱,故意修改名称与端口所致的。
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图

assets/js/login.js中修改注册的post接口
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图1

6.2 express启动

先在VSCode的扩展中加上express插件先
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图2
接着启动之前的api_server后端项目

nodemon app.js

然后再回到前端项目,按住ctrl+shift+p调出Express: Host Current Workspace and Open in Browser
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图3

6.3 最终效果

输入我的数据库信息(因人而异):

  • 账号:ks
  • 密码:123456
    【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图4

6.4 Layui布局问题

6.4.1 文章类别列表删除失效问题

打开assets/js/article/art_cate.js,找到删除文章类别的异步处理函数,通过console.log控制台打印命令发现,之所以不能删除是因为没有返回status,没返回它则是因为找不到id,因为它返回为空。
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图5
而造成这个问题的原因则是因为前端找不到这个属性名ID,但我们数据库写的是id。
aricle/art_cate.html
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图6

6.4.2 文章类别列表的编辑失效问题

因为上一节的更新文章类别的校验规则对象body参数里面定义了我们数据库的id为Id,但是我们的前端只能找数据库的存在的信息,而不是跑去后端验证,所以出现跟上面一样的问题。

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图7

更改schema/artcate.js的更新分类校验对象。

// 校验规则对象 - 更新分类
exports.update_cate_schema = {
	body: {
		id,
		name,
		alias,
	},
}

更改router_handler/artcate.js里面的更新文章处理分类对象的body校验对象的Id为id。

// 更新文章分类的处理函数
exports.updateCateById = (req, res) => {
	// const sql = `select * from ev_article_cate where name=? or alias=?`
	const sql = `select * from ev_article_cate where id != ? and (name=? or alias=?)`

	// 执行查重操作
	db.query(
		sql,
		[req.body.id, req.body.name, req.body.alias],
		(err, results) => {
			// 执行 SQL 语句失败
			if (err) return res.cc(err)

			// 判断 分类名称 和 分类别名 是否被占用
			if (results.length === 2)
				return res.cc('分类名称与别名被占用,请更换后重试!')
			if (
				results.length === 1 &&
				results[0].name === req.body.name &&
				results[0].alias === req.body.alias
			)
				return res.cc('分类名称与别名被占用,请更换后重试!')
			if (results.length === 1 && results[0].name === req.body.name)
				return res.cc('分类名称被占用,请更换后重试!')
			if (results.length === 1 && results[0].alias === req.body.alias)
				return res.cc('分类别名被占用,请更换后重试!')

			// 更新文章分类
			const sql = `update ev_article_cate set ? where id=?`

			db.query(sql, [req.body, req.body.id], (err, results) => {
				// 执行 SQL 语句失败
				if (err) return res.cc(err)
				// console.log(results)
				// SQL 语句执行成功,但是影响行数不等于 1
				if (results.affectedRows !== 1)
					return res.cc('更新文章分类失败!')

				// 更新文章分类成功
				res.cc('更新文章分类成功!', 0)
			})
		}
	)
	// res.send('ok')
}

之后通过测试软件进行接口测试是没问题,这里就懒得展示了。

但是即便这点击编辑后,弹出修改表单窗口也没多大的关系,它会提示Id必须为Number,这就很奇怪了。

回到我们前端的编辑问题上,编辑要依靠id绑定了btn-editform-edit经过的接口有两个,第一个是根据id获取文章分类,绑定点击事件click的异步操作,看到之前把$value.Id改为了$value.id,控制台显示的data数据没有问题。
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图8

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图9

可是当点击修改弹窗的修改表单时,即到第二个接口updatacate,控制台打印的信息却是:
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图10

这就很令人困惑了,明明都通过接口测试了,控制台却说没把第一个接口的data.id值传给了第二个接口?也许真的没有传到,查看修改类别的this对象,可以看到控制台输出的data值没有id,而是Id。
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图11

这也正好说明了之前Id必须为Number的怪相。

后面在aricle/art_cate.html的form表单修改隐藏域的Id为id即可:
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图12

后面拿个alter也可以看到数据没问题了
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图13

6.4.3 文章发布的类别下拉框问题

方案一:改用input(垃圾的方案)
在文章发布那块,使用layui的select组件后,尽管能够方便下拉显示数据库中文章分类的内容,但是无论怎么填写都会提示这里是必填项,要么选择去掉select,要么改成input项,完全不清楚发生了什么bug?
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图14

方案二:改Id为id。
art_pub.html
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图15

6.4.4 文章列表不能显示分类的内容

原因:因为数据库本身的数据都没有分类名,只有分类id而已。
art_list.html
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图16

6.5 改进页面

6.5.1 注册、重置密码页面添加密码强度

1) 重置密码页面

效果

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图17

代码

拿来博客:注册密码/修改密码之密码强度判断
user/user_pwd.html

点击查看代码


	
		
		
		Document
		
		
	
	
		
		
修改密码

user_pwd.js:

点击查看代码
$(function () {
	var form = layui.form

	form.verify({
		pwd: [/^[S]{6,12}$/, '密码必须6到12位,且不能出现空格'],
		samePwd: function (value) {
			if (value === $('[name=oldPwd]').val()) {
				return '新旧密码不能相同!'
			}
		},
		rePwd: function (value) {
			if (value !== $('[name=newPwd]').val()) {
				return '两次密码不一致!'
			}
		},
	})

	$('.layui-form').on('submit', function (e) {
		e.preventDefault()
		$.ajax({
			method: 'POST',
			url: '/my/updatepwd',
			data: $(this).serialize(),
			success: function (res) {
				if (res.status !== 0) {
					return layui.layer.msg('更新密码失败!')
				}
				layui.layer.msg('更新密码成功!')
				// 重置表单
				$('.layui-form')[0].reset()
			},
		})
	})
})
//密码强度判断
function passwordChangeStatuss(pwd) {
	if (pwd == '' || pwd == null) {
		$('.pwd-item label').attr('class', 'layui-btn layui-btn-primary')
	} else {
		S_level = checkStrong(pwd)
		switch (S_level) {
			case 0:
				$('.pwd-item label').attr(
					'class',
					'layui-btn layui-btn-primary'
				)
			case 1:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-primary')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			case 2:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			default:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn')
		}
	}
}
//判断输入密码的类型
function CharMode(iN) {
	if (iN >= 48 && iN = 65 && iN = 97 && iN >>= 1
	}
	return modes
}
//返回强度级别
function checkStrong(sPW) {
	if (sPW.length 

2) 注册页面

效果

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图18

代码

assets/login.css

点击查看代码
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  background: url('/assets/images/login_bg.jpg') no-repeat center;
  background-size: cover;
}

.loginAndRegBox {
  width: 400px;
  height: 350px;
  background-color: #fff;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.title-box {
  height: 60px;
  background: url('/assets/images/login_title.png') no-repeat center;
}

.reg-box {
  display: none;
}

.layui-form {
  padding: 0 30px;
}

.links {
  display: flex;
  justify-content: flex-end;
}

.links a {
  font-size: 12px;
}

.layui-form-item {
  position: relative;
}

.layui-icon {
  position: absolute;
  left: 10px;
  top: 10px;
}

.layui-input {
  padding-left: 32px;
}

.warn{
    display: inline-block;
    width:22px;
    height:22px;
    background: url("../images/paywarn.png");
    background-repeat: no-repeat;
    background-size:22px 22px;
    vertical-align: top;
}

login.html

点击查看代码


	
		
		
		LinFeng后台-登录/注册
		
		
		
		
	
	
		
		
【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图19

assets/js/login.js:

点击查看代码
$(function () {
	// 点击“去注册账号”的链接
	$('#link_reg').on('click', function () {
		$('.login-box').hide()
		$('.reg-box').show()
	})

	// 点击“去登录”的链接
	$('#link_login').on('click', function () {
		$('.login-box').show()
		$('.reg-box').hide()
	})

	// 从 layui 中获取 form 对象
	var form = layui.form
	var layer = layui.layer
	// 通过 form.verify() 函数自定义校验规则
	form.verify({
		// 自定义了一个叫做 pwd 校验规则
		pwd: [/^[S]{6,12}$/, '密码必须6到12位,且不能出现空格'],
		// 校验两次密码是否一致的规则
		repwd: function (value) {
			// 通过形参拿到的是确认密码框中的内容
			// 还需要拿到密码框中的内容
			// 然后进行一次等于的判断
			// 如果判断失败,则return一个提示消息即可
			var pwd = $('.reg-box [name=password]').val()
			if (pwd !== value) {
				return '两次密码不一致!'
			}
		},
	})

	// 监听注册表单的提交事件
	$('#form_reg').on('submit', function (e) {
		// 1. 阻止默认的提交行为
		e.preventDefault()
		// 2. 发起Ajax的POST请求
		var data = {
			username: $('#form_reg [name=username]').val(),
			password: $('#form_reg [name=password]').val(),
		}
		$.post('/api/register', data, function (res) {
			if (res.status !== 0) {
				return layer.msg(res.message)
			}
			layer.msg('注册成功,请登录!')
			// 模拟人的点击行为
			$('#link_login').click()
		})
	})

	// 监听登录表单的提交事件
	$('#form_login').submit(function (e) {
		// 阻止默认提交行为
		e.preventDefault()
		$.ajax({
			url: '/api/login',
			method: 'POST',
			// 快速获取表单中的数据
			data: $(this).serialize(),
			success: function (res) {
				if (res.status !== 0) {
					return layer.msg('登录失败!')
				}
				layer.msg('登录成功!')
				// 将登录成功得到的 token 字符串,保存到 localStorage 中
				localStorage.setItem('token', res.token)
				// 跳转到后台主页
				location.href = '/index.html'
			},
		})
	})
})

//密码强度判断
function passwordChangeStatuss(pwd) {
	if (pwd == '' || pwd == null) {
		$('.pwd-item label').attr('class', 'layui-btn layui-btn-primary')
	} else {
		S_level = checkStrong(pwd)
		switch (S_level) {
			case 0:
				$('.pwd-item label').attr(
					'class',
					'layui-btn layui-btn-primary'
				)
			case 1:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-primary')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			case 2:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			default:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn')
		}
	}
}
//判断输入密码的类型
function CharMode(iN) {
	if (iN >= 48 && iN = 65 && iN = 97 && iN >>= 1
	}
	return modes
}
//返回强度级别
function checkStrong(sPW) {
	if (sPW.length 

6.5.2 在登录页面添加随机校验码——(SVG-CAPTCHA库)

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图20

基本上就是直接拿别人写好的随便改

1)遇到的问题——Cannot set property 'captcha' of undefined

参考博客:项目中遇到的bug、问题总结
拿了别人的代码没认真看,出现了问题,挺尴尬的。

app.js添加session包(这个不用添加,这是个天坑,不用 VUE 你会很痛苦)

//为了验证码能通过,则需要导入session组件
const session = require('express-session')

app.use(
	session({
		secret: 'keyboard cat',
		resave: false,
		saveUninitialized: true,
	})
)

2) 编写获取校验码接口与验证码验证接口

参考博客:
下面这个是用session的,在后端判断是没有问题,但是如果搞到前端就要面临不同接口的不同session问题,网上有大量关于Vue的处理,但是没有layui的,我也找不到,所以一定要慎重考虑:
案例分享--NodeJs制作随机验证码

下面的这个则是用通过id选择器通过点击事件替换,只用考虑前端而不用管后端怎么样,非常方便。
使用node生成验证码图片,并进行验证

router/user.js:定义获取校验码与验证码验证路由

// 定义获取验证码路由
router.get('/getCaptcha', userHandler.getCaptcha)

//定义验证码验证路由
//router.get('/verifyCaptcha', userHandler.verifyCaptcha)

router_handler/user.js:实现获取校验码与验证码验证的处理函数

const captcha = require('svg-captcha') //1.引入的模块

//获取验证码处理函数
exports.getCaptcha = (req, res) => {
	const cap = captcha.create({
		size: 4, //长度
		ignoreChars: '0o1il', //排除字符
		noise: 3, //干扰线条数
		width: 120, // 宽度
		height: 36, // 高度
		color: true, // 验证码字符是否有颜色,默认是没有,如果设置了背景颜色,那么默认就是有字符颜色
		background: '#fff', // 背景色 可以自己改
	})
	// req.session.captcha = cap.text
	// console.log(req.session)
	// res.type('svg') //响应类型

	res.send(cap)
}

接口测试

【nodejs】大事件后台管理系统(四)——layui前端布局与改进插图21

如果要搞session后台判断的话,则需要弄个验证码验证接口(但是我搞不成)。

3) 修改login.html页面

login.html


点击获取验证码

assets/js/login.js
先判断完验证码,再接上登录的ajax操作

点击查看代码
$(function () {
	// 点击“去注册账号”的链接
	$('#link_reg').on('click', function () {
		$('.login-box').hide()
		$('.reg-box').show()
	})

	// 点击“去登录”的链接
	$('#link_login').on('click', function () {
		$('.login-box').show()
		$('.reg-box').hide()
	})

	// 从 layui 中获取 form 对象
	var form = layui.form
	var layer = layui.layer
	// 通过 form.verify() 函数自定义校验规则
	form.verify({
		// 自定义了一个叫做 pwd 校验规则
		pwd: [/^[S]{6,12}$/, '密码必须6到12位,且不能出现空格'],
		// 校验两次密码是否一致的规则
		repwd: function (value) {
			// 通过形参拿到的是确认密码框中的内容
			// 还需要拿到密码框中的内容
			// 然后进行一次等于的判断
			// 如果判断失败,则return一个提示消息即可
			var pwd = $('.reg-box [name=password]').val()
			if (pwd !== value) {
				return '两次密码不一致!'
			}
		},
	})

	// 监听注册表单的提交事件
	$('#form_reg').on('submit', function (e) {
		// 1. 阻止默认的提交行为
		e.preventDefault()
		// 2. 发起Ajax的POST请求
		var data = {
			username: $('#form_reg [name=username]').val(),
			password: $('#form_reg [name=password]').val(),
		}
		$.post('/api/register', data, function (res) {
			if (res.status !== 0) {
				return layer.msg(res.message)
			}
			layer.msg('注册成功,请登录!')
			// 模拟人的点击行为
			$('#link_login').click()
		})
	})

	let validation = ''
	//点击更换验证码
	$('#codeImg').on('click', function () {
		/*在请求获得验证码那块:(该方案弃用,狗都不用,还是Vue方便)
    src在启动layui模板后,它认为的端口号是80端口,但是后端开的是8080,如果两个改成一样的,
    就会端口占用,所以就需要在baseAPI.js设置ajax能跨域的端口,
    因此需要通过attr修改成我们最终的请求接口,再通过prob设置验证码点击更换。
    */
		// var cp = $(this).attr('current_port')
		// $(this).prop('src', cp + '/api/getCaptcha?=t' + Date.now())
		$.get('/api/getCaptcha', (res) => {
			// console.log(res)
			validation = res.text
			codeImg.innerHTML = res.data
		})
	})

	//验证验证码,这个后端相应的接口应该要写入到login里面去
	$('#codeInput').on('blur', function () {
		if (
			$(this).val().length == 4 &&
			$(this).val().toLowerCase() == validation.toLowerCase()
		) {
			// layer.msg('验证码正确')
			// 监听登录表单的提交事件
			$('#form_login').submit(function (e) {
				// 阻止默认提交行为
				e.preventDefault()
				$.ajax({
					url: '/api/login',
					method: 'POST',
					// 快速获取表单中的数据
					data: $(this).serialize(),
					success: function (res) {
						if (res.status !== 0) {
							return layer.msg('登录失败!')
						}
						layer.msg('登录成功!')
						// 将登录成功得到的 token 字符串,保存到 localStorage 中
						localStorage.setItem('token', res.token)
						// 跳转到后台主页
						location.href = '/index.html'
					},
				})
			})
		} else {
			layer.msg('验证码输入错误')
		}
	})
})

//密码强度判断
function passwordChangeStatuss(pwd) {
	if (pwd == '' || pwd == null) {
		$('.pwd-item label').attr('class', 'layui-btn layui-btn-primary')
	} else {
		S_level = checkStrong(pwd)
		switch (S_level) {
			case 0:
				$('.pwd-item label').attr(
					'class',
					'layui-btn layui-btn-primary'
				)
			case 1:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-primary')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			case 2:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn layui-btn-primary')
				break
			default:
				$('#l').attr('class', 'layui-btn layui-btn-danger')
				$('#m').attr('class', 'layui-btn layui-btn-warm')
				$('#h').attr('class', 'layui-btn')
		}
	}
}
//判断输入密码的类型
function CharMode(iN) {
	if (iN >= 48 && iN = 65 && iN = 97 && iN >>= 1
	}
	return modes
}
//返回强度级别
function checkStrong(sPW) {
	if (sPW.length 

任务清单

1、重置密码、注册页面:密码强度显示(完成)
2、登录页面有校验码,虽然有点丑(完成)

为什么我要改进这个项目?

当然不是什么程序员之间的革命情谊啦,何况黑马程序员也没给我钱。

主观原因: 想整属于我自己的个人项目,我希望可以在前端这块有我的痕迹,所以我选择魔改这个项目,没想到吧,

以后如果要告我侵权,请黑马程序员手下留情,当然我也不太可能商用的,我也不会选择贩卖它,
如果未来有一天我这个项目受欢迎,然后又像套娃一样,被人魔改然后贩卖。
请提醒我,让我们伟大的开源精神、名气与汗水卷死他们。

客观原因:被老师质疑我的能力,在综合实训那天被骂得狗血淋头

我的指导老师谈大事件本身就是个铭感词(也怪我选词想都没想就拿这个项目进行综合实训的答辩),

并且也谈到这个项目是不完善的,没有网站基本改有的功能,并且还问到我这个项目的研究目的是什么?

我当时非常的摆烂,直接说是整着来玩的,结果把老师气得。

他们直接把这个项目能找的缺点、我个人操作的问题能说的都说了。

我全程低头红豆泥私密马赛,你说的对,我改。。。,

其实挺好笑的,大三实习要写论文,队伍对我组长的任务分配也是基本不愿执行,非得等到最后答辩几天才肯帮忙,
结果还怪我最后对他们不理不问,挺搞笑的,简直是把我当保姆。

其余答辩的队伍,则是都选择了曾经华为的比赛项目——本质就是数据报表高级版。

图弄得花里胡哨,把我给秀到了,看到我这个大反面教材,老师也是都看不下去了。

文章来源于互联网:【nodejs】大事件后台管理系统(四)——layui前端布局与改进

THE END
分享
二维码