使用koa+mysql写一个简易论坛(四)
2019-04-17 本文已影响5人
Qibing_Fang
一、本期目标
1、 管理员后台
- 创建子论坛
- 子论坛展示
- 帖子分类展示
2、主页及帖子展示页
- 子论坛展示
- 贴在分类展示
3、用户行为
- 发表帖子
二、后台布局及管理员登录
1、首先我们得定一个入口用于管理员登录
=> 在页面底部提供一个按钮,该按钮绑定一个模态框,用作登录入口


2、管理员登录功能的实现
=> 因为管理员是固定的,所以我们直接预设一个管理员的用户名(admin)及密码(admin),直接判断就可以了
=> 代码如下:

登录成功,则跳转至后台主页
=>

⚠️:在这里我们引用了本地的静态文件 ---- 一张图片
所以我们得安装一个中间件 koa-stati ,这个必须得有,要不然就无法正确显示
三、子论坛的创建
1、首先我们得建一个表 =>

2、 创建的话呢我们依旧使用模态框,将其绑定的按钮放在右上角,主体部分用于展示现有的子论坛, 页面布局如图:

3、创建 =>
1、获取到管理员输入的子论坛名称
2、操作做数据库表boards,获取到里面的所有信息(数组: listBoard)
3、创建一个数组existBoardArray,用于保存现有的子论坛名称,遍历listBoard并将其中的board_name存入existBoardArray
3、如果返回的数组(existBoardArray)长度为0,说明还没有子论坛,直接添加
4、如果不为0,则使用indexOf判断新的名称是否被占用,没有则创建,有则创建失败
5、代码:

四、子论坛的展示
1、在请求页面的时候操作数据库表boards,获取其中的所有数据,得到一个数组listBoard, 里面存储了当前所有子论坛信息
2、将listBoard传入页面 =>

3、在对应的html文件中使用koa-ejs的模版语法将所有子论坛遍历出来即可
=>

4、结果展示

⚠️: 表格中的edit这一列是用于存放论坛操作按钮的,可以后面再加
五、 主页及帖子展示页
1、我们还得在主页和帖子展示页展示子论坛,做法跟上面的完全一样,就不写了
// 请求主页 ---- Http
router.get("/", async (ctx) => { //路由
const user = ctx.session.user;
const listBoardPromise = editBoard.listBoardAll();
const listBoard = await listBoardPromise;
await ctx.render('index', {
user: user,
listBoard: listBoard
});
});
// 请求帖子展示页面 ---- Http
router.get("/showTopics/:id", async (ctx) => { //路由
const user = ctx.session.user;
const listBoardPromise = editBoard.listBoardAll();
const listBoard = await listBoardPromise;
await ctx.render('/topics/show_topics', {
user: user,
listBoard: listBoard
});
});


六、用户发表帖子
1、建表 topic
create table topic(
id int primary key not null auto_increment,
title varchar(64) not null,
article varchar(255) not null,
board_id int not null
) default charset=utf8 auto_increment=1;
2、页面布局

3、重点:用户发表帖子的时候我们肯定得让他选个子论坛,而不是任其随便填一个,那么如何获取select标签里的option的value和text就成了关键了(当然,我们只需要获得一种就可以了)
解决方法:设置一个type="hidden"的input的标签,我们用过JS或者jQuery获取到value或者text将其放到input里面上传,这样我们就可以从后台获取到其数值了。
=>


4、解决了这个的话后面的其实就很简单
-
获取到用户输入的标题title、正文article 和 隐式上传过来的board_id,并将其何为一个数组data,然后将data存入表topic中即可
image.png
addTopic函数为:

七 、各页面展示帖子到对应子论坛
主页 =>
1、多常见几个子论坛和帖子用于测试,最好留一个子论坛没有任何帖子作为特殊情况
2、 经过之前的铺垫,其实之一步也是非常简单的,涉及到的知识点无非就是模版语法而已
- 主页 主页比较特殊,我们只需要在全部这个选项下展示全部的帖子即可
- 回到index.js, 在请求主页的router里我们将所有的帖子取到,然后放入index.html
下面的listAllTopic函数就是用于取所有的topic,其中order by id desc的作用是根据id倒叙取数据
async listAllTopic () {
const sql = "select * from topic where useful=1 order by id desc";
const [rows, fields] = await promisePool.query(sql);
return rows;
},
-
(index.js)get请求 =>
image.png
-
(index.html)模版语法 =>
image.png

帖子展示页 =>
同理=>




⚠️下面的这段代码用于给被电击的导航按钮添加active类(上图中的蓝色背景)

后台 =>
同理


