前篇知识点剩下最后一个基础模块管理员后台,本篇我们就来完成它。我们在前面知识点做登录的时候预留过一个管理员登录接口
/**
*
* @Title: loginAdmin
* @Description: 跳转到管理员的登录页面
* @return
* @return: String
*/
@RequestMapping("admin/toLogin.do")
public String loginAdmin() {
return "passport/login_admin";
}
选在我们来编写它的登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>管理员登录title>
<link href="/resource/css/bootstrap.min.css" rel="stylesheet">
<link href="/resource/css/jquery/screen.css" rel="stylesheet">
<script type="text/javascript" src="/resource/js/jquery-3.2.1.js">script>
<script type="text/javascript" src="/resource/js/jquery.validate.js">script>
<script type="text/javascript" src="/resource/js/bootstrap.min.js">script>
head>
<body>
<div class="container col-md-5">
<h1>管理员登录h1>
<hr>
<span id="msg" class="text-danger">span>
<form id="form1">
<div class="form-group">
<label for="username">用户名label> <input type="text"
class="form-control" name="username" id="username">
div>
<div class="form-group">
<label for="password">密码label> <input type="password"
class="form-control" name="password" id="password">
div>
<div class="form-group">
<button type="submit" class="btn btn-info" >登录button>
<button type="reset" class="btn btn-primary">重置button>
div>
form>
div>
body>
<script type="text/javascript">
$(function(){
$("#form1").validate({
//1.定义校验规则
rules:{
username:{
required:true//用户名非空
},
password:{
required:true//密码非空
}
},
//2:如果不满足规则,进行提示
messages:{
username:{
required:"用户名不能为空"
},
password:{
required:"密码非空"
}
},
submitHandler:function(){
$.post("/passport/admin/login.do",$("#form1").serialize(),function(result){
if(result.code==200){//如果登录成功
location.href="/admin/index.do";//进入管理员后台页面
}else{//登录失败
$("#msg").text(result.msg)
}
});
}
})
})
script>
html>
这此页面中如果登录成功,需要进入管理员后台首页,因此我们需要准备管理员后台Controller和页面
package com.wy.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.github.pagehelper.PageInfo;
import com.wy.bean.Article;
import com.wy.bean.User;
import com.wy.service.ArticleService;
import com.wy.service.UserService;
/**
*
* @ClassName: Adminontroller
* @Description: 管理员中心
* @author: charles
* @date: 2020年4月3日 上午10:58:11
*/
@RequestMapping("admin")
@Controller
public class Adminontroller {
@Resource
private ArticleService articleService;
@Resource
private UserService userService;
/**
*
* @Title: index
* @Description: 管理员的首页
* @return
* @return: String
*/
@RequestMapping("/index.do")
public String index() {
return "admin/index";
}
/**
*
* @Title: articles
* @Description: 文章列表
* @param model
* @param article
* @param page
* @param pageSize
* @return
* @return: String
*/
@RequestMapping("/articles.do")
public String articles(Model model,Article article,@RequestParam(defaultValue = "1")Integer pageNum,@RequestParam(defaultValue = "6")Integer pageSize) {
//管理员不需要传id但是默认要显示待审核的文章
if(article.getStatus()==null){
article.setStatus(0);
}
List<Article> selectArticle = articleService.selectArticle(article, pageNum, pageSize);
PageInfo<Article> info = new PageInfo<>(selectArticle);
model.addAttribute("info",info);
return "admin/articles";
}
/**
*
* @Title: article
* @Description: 单个文章
* @param id
* @return
* @return: Article
*/
@ResponseBody
@RequestMapping("/article.do")
public Article article(Integer id) {
return articleService.select(id);
}
/**
*
* @Title: update
* @Description: 修改文章
* @param article
* @return
* @return: boolean
*/
@ResponseBody
@RequestMapping("/update.do")
public boolean update(Article article) {
return articleService.update(article) >0;
}
/**
*
* @Title: update
* @Description: 修改用户
* @param user
* @return
* @return: boolean
*/
@ResponseBody
@RequestMapping("user/update.do")
public boolean update(User user) {
return userService.update(user) >0;
}
/**
*
* @Title: users
* @Description: 用户列表
* @param model
* @param user
* @param pageSize
* @return
* @return: String
*/
@RequestMapping("/users.do")
public String users(Model model,User user,@RequestParam(defaultValue = "1")Integer page,@RequestParam(defaultValue = "6")Integer pageSize) {
//默认查询没有禁用的用户
if(user.getLocked()==null) {
user.setLocked(0);
}
PageInfo<User> info = userService.selects(user, page, pageSize);
model.addAttribute("info", info);
model.addAttribute("user", user);
return "admin/users";
}
/**
* 到达某类查询页面
*/
@RequestMapping("section.do")
public String section(){
return "admin/section";
}
/**
* 查询某类文
* @return
*/
@RequestMapping("sections.do")
public String sections(Article article ,@RequestParam(defaultValue="1")Integer pageNum,Model model){
List<Article> list=articleService.getSections(article,pageNum);
PageInfo info=new PageInfo<>(list);
model.addAttribute("info", info);
model.addAttribute("article", article);
return "admin/sections";
}
/**
* 去添加
* @return
*/
@RequestMapping("add.do")
public String add(){
return "admin/add";
}
/**
* 添加处理
* @return
*/
@RequestMapping("toAdd.do")
public String toAdd(String title,String content){
articleService.add(title,content);
return "redirect:/admin/index.do";
}
}
随后准备管理员中心的首页,和个人中心差别不大。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>今日头条-管理员中心title>
<link href="/resource/css/bootstrap.min.css" rel="stylesheet">
<link href="/resource/css/index.css" rel="stylesheet">
<script type="text/javascript" src="/resource/js/jquery-3.2.1.js">script>
<script type="text/javascript" src="/resource/js/popper.min.js">script>
<script type="text/javascript" src="/resource/js/bootstrap.min.js">script>
head>
<body>
<div class="container-fluid">
<div class="row bg-warning">
<div class="col-md-12" style="height: 50px">
<img alt="" class="rounded-circle" src="/resource/imgs/logo.jpg" style="width: 30px; height: 30px"> <font color="white">管理员中心font>
<div class="btn-group dropleft" style="float: right;">
<button type="button" class="btn btn-dark btn-sm dropdown-toggle"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${sessionScope.admin.username }button>
<div class="dropdown-menu">
<ul>
<li><a href="/passport/logout.do">注销a>li>
<li><a href="/index.do">返回首页a>li>
ul>
div>
div>
div>
div>
<div class="row mt-1">
<div class="col-md-2 bg-light rounded " style="height: 550px">
<div class="list-group mt-2 text-center">
<a href="#" data="/admin/articles.do" class="list-group-item list-group-item-action active">审核文章 a>
<a href="#" data="/admin/users.do" class="list-group-item list-group-item-action">管理用户a>
<a href="#" data="/admin/section.do" class="list-group-item list-group-item-action">查询军事文章a>
<a href="#" data="/admin/add.do" class="list-group-item list-group-item-action">添加军事文章a>
<a href="#" class="list-group-item list-group-item-action">系统设置a>
div>
div>
<div class="col-md-10" id="center">
div>
div>
div>
body>
<script type="text/javascript">
//为菜单添加绑定点击事件
$(function() {
//默认在中间区域加载我的文章
$("#center").load("/admin/articles.do");
$("a").click(function() {
//获取a标签的url
var url = $(this).attr("data");
//先把所有菜单选中样式去除
$("a").removeClass("active");
//为当前点击的菜单添加选中的样式
$(this).addClass("active");
//在中间区域加载url
$("#center").load(url);
})
})
script>
html>
刚进入管理首页这个环节和个人中心一样有一个默认加载的文章首页,但是注意个人中心默认展示的是我的文章,管理员首页默认展示的是所有的文章,对这些文章进行审核并且决定是否热门,因此我们现在要准备这个审核文章的页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>title>
<style type="text/css">
.ex {
width: 200px;
white-space: nowrap; /*不换行的*/
overflow: hidden; /*超出范围隐藏*/
text-overflow: ellipsis; /*超出用省略号 */
}
style>
head>
<body>
<div class="form-group form-inline">
<div class="form-group">
<label for="title">文章标题label> <input id="title"
class="form-control" type="text" name="title"
value="${article.title }">
div>
<div class="form-group form-inline">
审核状态:
<div class="form-check">
<label class="form-check-label" for="check1">待审label>
div>
<div class="form-check">
<label class="form-check-label" for="check2">已审label>
div>
<div class="form-check">
<label class="form-check-label" for="check3">驳回label>
div>
div>
<div>
<button class="btn btn-info" onclick="query()">查询button>
div>
div>
<table class="table table-bordered table-hover text-center">
<tr>
<td>序号td>
<td>文章标题td>
<td>所属栏目td>
<td>所属分类td>
<td>作者td>
<td>发布时间td>
<td>是否热门td>
<td>审核状态td>
<td>操作td>
tr>
<c:forEach items="${info.list}" var="article" varStatus="index">
<tr>
<td>${index.count }td>
<td><div class="ex">${article.title }div>td>
<td>${article.channel.name }td>
<td>${article.category.name }td>
<td>${article.user.username }td>
<td><fmt:formatDate value="${article.created }"
pattern="yyyy-MM-dd HH:mm:ss" />td>
<td>
<c:if test="${article.hot==0}">
<button class="btn btn-info btn-sm" type="button" onclick="update(${article.id},this)">否button>
c:if>
<c:if test="${article.hot==1}">
<button class="btn btn-danger btn-sm" type="button" onclick="update(${article.id},this)">是button>
c:if>
td>
<td>${article.status==0?"待审":article.status==1?"已审":"驳回" }td>
<td><button class="btn btn-link btn-sm"
onclick="detail(${article.id})" data-toggle="modal"
data-target="#exampleModalLong" >详情button>
td>
tr>
c:forEach>
<tr>
<td colspan="10"><jsp:include
page="/WEB-INF/view/common/bookstappages.jsp">jsp:include>td>
tr>
table>
<div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle"><span id="mtitle">span> h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×span>
button>
div>
<div class="modal-body" id="content">
div>
<div class="modal-footer">
<span id="msg" class="text-danger">span>
<button type="button" class="btn btn-success" onclick="check(1)">通过button>
<button type="button" class="btn btn-warning" onclick="check(-1)">驳回button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Closebutton>
div>
div>
div>
div>
body>
<script type="text/javascript">
function update(id,obj){
//如果按钮的值为否则应该传递1,否则就是 0
var hot = $(obj).text()=='否'?1:0;
$.post("/admin/update.do",{id:id,hot:hot},function(flag){
if(flag){
//改变按钮的内容
hot==1?$(obj).text("是"):$(obj).text("否");
//改变颜色
$(obj).attr("class",$(obj).text()=="是"?"btn btn-danger btn-sm":"btn btn-info btn-sm");
}
})
}
var articleId;//文章ID
//审核文章
function check(status){
$.post("/admin/update.do",{id:articleId,status:status},function(flag){
if(flag){
$("#msg").text("操作成功");
}else{
$("#msg").text("操作失败");
}
})
}
//文章详情
function detail(id){
articleId=id;//为全局变量赋值 文章ID
//先清空
$("#mtitle").empty();
$("#content").empty();
//根据文章id查询文章内容
$.get("/admin/article.do",{id:id},function(article){
$("#mtitle").append(article.title);
$("#content").append(article.content);
})
}
//查询
function query(){
var title =$("[name='title']").val();//标题
var status= $("[name='status']:checked").val();//审核状态
//在中间区域加载分页
$("#center").load("/admin/articles.do?title="+title+"&status="+status);
}
//分页
function goPage(pageNum) {
var title =$("[name='title']").val();//标题
var status=$("[name='status']:checked").val();//审核状态
//在中间区域加载分页
$("#center").load("/admin/articles.do?pageNum=" + pageNum+"&title="+title+"&status="+status);
}
script>
html>
到此你可以运行项目查看一下管理员登录是否可以正常进入管理员首页。


在首页的代码里,我们可以看到,审核文章功能细分后,使用模态框查询了文章的详情,并在模态框的详情中可以对文章做是否通过的审核,使用Ajax完成了对文章是否热点的修改,以及表单查询某类文章
现在做第二个功能,就是对用户的管理,根据代码,我们需要后天跳转到user界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>title>
head>
<body>
<div class="form-group form-inline">
<div class="form-group">
<label for="title">用户名:label>
<input id="title"
class="form-control" type="text" name="username"
value="${user.username }">
div>
<div class="form-group form-inline ml-2">
用户状态:
<div class="form-check">
<label class="form-check-label" for="check1">正常label>
div>
<div class="form-check">
<label class="form-check-label" for="check2">禁用label>
div>
div>
<div class="ml-2">
<button class="btn btn-info" onclick="query()">查询button>
div>
div>
<table class="table table-bordered table-hover text-center">
<tr>
<td>序号td>
<td>用户名td>
<td>昵称td>
<td>注册日期td>
<td>生日td>
<td>状态td>
tr>
<c:forEach items="${info.list}" var="user" varStatus="index">
<tr>
<td>${index.count }td>
<td>${user.username }td>
<td>${user.nickname }td>
<td><fmt:formatDate value="${user.created }"
pattern="yyyy-MM-dd HH:mm:ss" />td>
<td><fmt:formatDate value="${user.birthday }"
pattern="yyyy-MM-dd" />td>
<td>
<c:if test="${user.locked==0}">
<button class="btn btn-info btn-sm" type="button" onclick="update(${user.id},this)">正常button>
c:if>
<c:if test="${user.locked==1}">
<button class="btn btn-danger btn-sm" type="button" onclick="update(${user.id},this)">禁用button>
c:if>td>
tr>
c:forEach>
<tr>
<td colspan="10"><jsp:include
page="/WEB-INF/view/common/bookstappages.jsp">jsp:include>td>
tr>
table>
body>
<script type="text/javascript">
//修改用户
//locked:1 禁用,locked:0 正常
function update(id,obj){
//如果按钮的值为否则应该传递1,否则就是 0
var locked = $.trim($(obj).text())=='正常'?1:0;
$.post("/admin/user/update.do",{id:id,locked:locked},function(flag){
if(flag){
//改变按钮的内容
locked==1?$(obj).text("禁用"):$(obj).text("正常");
//改变颜色
$(obj).attr("class",$(obj).text()=="禁用"?"btn btn-danger btn-sm":"btn btn-info btn-sm");
}
})
}
//查询
function query(){
var username =$("[name='username']").val();//姓名
var locked= $("[name='locked']:checked").val();//用户状态
//在中间区域加载分页
$("#center").load("/admin/users.do?username="+username+"&locked="+locked);
}
function goPage(page) {
var username =$("[name='username']").val();//姓名
var locked= $("[name='locked']:checked").val();//用户状态
//在中间区域加载分页
$("#center").load("/admin/users.do?page=" + page+"&username="+username+"&locked="+locked);
}
script>
html>
运行项目看效果,我们可以发现,在用户管理中,我们做的没有审核文章复杂,只是做了查询和对用户账号的停用

随后是查询军事文功能,根据代码后台跳转前台的section页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insert title heretitle>
<link href="/resource/css/bootstrap.min.css" rel="stylesheet">
<script type="text/javascript" src="/resource/js/jquery-3.2.1.js">script>
<script type="text/javascript" src="/resource/js/bootstrap.min.js">script>
head>
<body>
<form action="">
文章标题:<input type="text" name="title" value="${article.title }">
<input type="button" onclick="selects()" value="查询" name="title" class="btn btn-info btn-sm">
form>
<div id="sections">
div>
<script type="text/javascript">
function selects() {
$("#sections").load("/admin/sections.do?title="+$("[name='title']").val());
}
script>
body>
html>
同时准备展示文章的界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<table class="table table-bordered table-hover text-center">
<tr>
<td>序号td>
<td>文章标题td>
<td>所属栏目td>
<td>作者td>
<td>发布时间td>
<td>是否热门td>
<td>操作td>
tr>
<c:forEach items="${info.list}" var="article" varStatus="index">
<tr>
<td>${index.count }td>
<td><div class="ex">${article.title }div>td>
<td>军事td>
<td>${article.user.username }td>
<td><fmt:formatDate value="${article.created }"
pattern="yyyy-MM-dd HH:mm:ss" />
td>
<td>
<c:if test="${article.hot==0}">
否
c:if>
<c:if test="${article.hot==1}">
是
c:if>
td>
<td><button class="btn btn-link btn-sm"
onclick="detail(${article.id})" data-toggle="modal"
data-target="#exampleModalLong" >详情button>
td>
tr>
c:forEach>
<tr>
<td colspan="10"><jsp:include
page="/WEB-INF/view/common/bookstappages.jsp">jsp:include>td>
tr>
table>
<div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle"><span id="mtitle">span> h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×span>
button>
div>
<div class="modal-body" id="content">
div>
<div class="modal-footer">
<span id="msg" class="text-danger">span>
<button type="button" class="btn btn-success" onclick="check(1)">通过button>
<button type="button" class="btn btn-warning" onclick="check(-1)">驳回button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Closebutton>
div>
div>
div>
div>
<script type="text/javascript">
//分页
function goPage(pageNum) {
var title =$("[name='title']").val();//标题
//在中间区域加载分页
$("#sections").load("/admin/sections.do?pageNum=" + pageNum+"&title="+title);
}
//文章详情
function detail(id){
articleId=id;//为全局变量赋值 文章ID
//先清空
$("#mtitle").empty();
$("#content").empty();
//根据文章id查询文章内容
$.get("/admin/article.do",{id:id},function(article){
$("#mtitle").append(article.title);
$("#content").append(article.content);
})
}
script>
body>
html>
这个查询军事文的功能成名称上大家可能感觉有些违和,可以去看一下Dao层它操作的主体是一张单独的表,只是它的数据来源于主要的文章表而已,当时把这个小功能从审核中分出来,一是为了告诉大家load这种页面展示方式比较主流,甚至是vue的主页面默认底层也是这种逻辑,二是给大家提供一个简单的架子,大家可以先用这个功能扩展试试手,言归正传,我们看效果

详情页中按键功能留给大家开发扩展
最后就是本CMS-Demo 1.0版本最后一个小功能添加军事文,后台跳转加载添加页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<form action="/admin/toAdd.do">
文章标题<input type="text" name="title" ><br>
<textarea rows="10" cols="10" name="content">textarea>
<input type="submit" value="添加">
form>
body>
html>
最后一个功能确实,作者承认从头到脚做的很敷衍,但是也正好留给大家做扩展。

最后这个功能我要说明一下,我忘了当时咋考虑的,但是它的运行逻辑就是你不能添加一个没有的文章到军事文中,因为底层是先查询了你要添加的文章标签的ID,然后把这对关系和内容存储到了军事文的表中,而且查询哪里我给大家留了一个很明显的坑,所以最后这个功能问题还很大,大家可以自己改一改
本项目目前以上传github :https://github.com/wangyang159/cmsdemo