CMS:内容管理系统
2022-07-28 14:14:58
256
{{single.collect_count}}

CMS内容管理系统

1. 简介:

内容管理系统(content management system,CMS)是一种位于WEB 前端(Web 服务器)和后端办公系统或流程(内容创作、编辑)之间的软件系统。内容的创作人员、编辑人员、发布人员使用内容管理系统来提交、修改、审批、发布内容。这里指的“内容”可能包括文件、表格、图片、数据库中的数据甚至视频等一切你想要发布到Internet、Intranet以及Extranet网站的信息。

2. 需求分析

(1) 官网中的内容或信息的显示和不显示来自于后台管理系统
(2) 开发一个后台管理系统来管理官网的信息

3. 项目架构

(1) B/S架构的项目

浏览器和服务器架构模式

(2) 前台:官网信息维护

① 文章显示
② 轮播图显示
③ 开班信息
④ 问题反馈

***文章管理-->前台代码:*****1、分页信息展示**(1). 使用GridManager表格插件。document.querySelector('#table-demo-ajaxPageCode').GM({gridManagerName: 'demo-ajaxPageCode', //表中的名称ajaxData: '/system/article/findAll', //请求路径ajaxType: 'POST', //请求方式sizeData: [5,10,15,20], //每页展示的数据量pageSize: 5, //每页展示多少数据currentPageKey: 'localPage', //重命名页数(原名:cPage )pageSizeKey: 'pageSize', //重命名每页数据个数(原名: pSize)height: '100%', //高度,数据个数展示完supportAjaxPage: true, //是否分页//supportAdjust: false,supportDrag: false, //列是否可移动,false不可移动columnData: [{key: 'title', align: 'center', //文本居中text: '文章标题'},{key: 'type',align: 'center',text: '文章类型',template: function(cell, row, index, key){//cell :当前key对应的值(key是什么类型,cell就是什么类型)//row :一行的信息//index :下标//key :key后面跟的Stringreturn cell.name;}},{key: 'url',align: 'center',text: 'url'},{key: 'clickCount',align: 'center',text: '点击量'},{key: 'content',align: 'center',text: '文章内容'},{key: 'createDate',align: 'center',text: '创建时间'},{key: 'enable',align: 'center',text: '是否启用',template: function(cell, row, index, key){return cell?"启用":"禁用";}},{key: 'id',align: 'center',text: '操作 <a id="addById" href="javascript:;">添加</a>',template: function(cell, row, index, key){//row对象转换成json字符串格式var rows = *JSON.stringify*(row);return '<a data-id='+cell+' style="color:red" href="javascript:;">删除</a> '+"<a data-obj='"+rows+"' style='color:blue' href='javascript:;'>修改</a>";}}]});**2、高级查询**(1). 使用jquery、GridManager插件//绑定查询事件$("#queryButton").on("click", function(){//将表单中的信息转换成json串var datas = $('#queryForm').serializeObject();//将表单中的信息与localPage、pagesize分页信息一起发送至后台GridManager.setQuery('demo-ajaxPageCode', datas);})**3、添加文章**//添加,事件委托添加点击事件$("body").on("click", "#addId", function(){//清空隐藏域$("#hid").val("");//清空表单缓存$("#saveForm")[0].reset();// 清空富文本编辑器(百度查)var ue = UE.getEditor('container');$(document).ready(function () {ue.ready(function () {ue.setContent('');//赋值给UEditor});});//弹出模态框$("#saveModel").modal("show")})**4、修改文章信息**//修改更能,事件委托添加点击事件$("body").on("click", "a[data-obj]", function(){//alert("123")//清空缓存$("#saveForm")[0].reset();//清空隐藏域$("#hid").val("");//得到当前行数据var objs = $(this).data("obj");//数据回显模态框$("#saveModel").setForm(objs);// 清空富文本编辑器(百度查)var ue = UE.getEditor('container');$(document).ready(function () {ue.ready(function () {ue.setContent('');//赋值给UEditor});});//弹出模态框$("#saveModel").modal("show")})**5、修改、删除保存数据**//保存数据。添加点击事件$("#saveButton").on("click", function(){//发送请求$.ajax({type: "post",url: "/system/article/save",//发送表单信息serialize(),有文件上传则不能用data: $("#saveForm").serialize(),//dataType: "json",success: function(msg){if (msg.result) {//关闭模态框$("#saveModel").modal("hide")//刷新页面,true刷新后跳到第一页GridManager.refreshGrid("demo-ajaxPageCode", true);}else {alert(msg.error)}}})})**6、删除**//删除功能,事件委托$("body").on("click", "a[data-id]", function(){//获取idvar id = $(this).data("id");//弹出确认删除模态框$("#delModal").modal("show")//确认前,解绑点击事件$("#delModelButton").off("")//绑定确认事件$("#delModelButton").on("click", function(){//alert(id)//发送请求$.ajax({type: "post",url: "/system/article/del",data: {"id":id},//dataType: "json",success: function(msg){if (msg.result) {//关闭模态框$("#delModal").modal("hide")//刷新页面GridManager.refreshGrid("demo-ajaxPageCode", true);} else {alert(msg.error)}}}) })})

(3) 后台:管理系统

拥有模块:
1、文章管理
2、轮播图管理
3、开班信息
4、问题反馈
5、用户登录登出

模块功能:

***文章管理-->后台:*****1、信息展示**(1). 创建类BaseQuery,封装分页数据Beanpublic class BaseQuery {private Integer localPage;private Integer pageSize;//sql中limit分页查询中的第一个数public Integer getBean(){return (this.localPage - 1) * this.pageSize;}...}**2、高级查询**(1). 新建类ArticleQuery,添加高级查询字段信息,继承BaseQuery**3、封装后台返回数据Bean**(1). 新建类PageBean<T>,将totals(数据总条数)与data(所有的数据)封装起来public class BaseQuery<T> {//数据总条数private Integer totals = 0;//分页数据private List<T> data = new ArrayList<T>();...}**4、封装页面数据操作结果**(1). 新建类AjaxResultpublic class AjaxResult {//布尔类型,默认为trueprivate Boolean result = true;private String error;...}**5、页面静态化技术(FreeMarker)**public class FreeMarkerUtil {/** * @Description:(封装FreeMarker) * @param:@param path 默认加载路径,生成的文件存放的位置(xxx.ftl模板文件也存放在这里) * @param:@param name 模板文件名 * @param:@param data 准备的数据(map/实体对象) * @param:@param suffix 需要生成文件的后缀 * @param:@return* @return:String * @author:ly * @date:xx * @version:V1.0 */public static String createFreemarker(String path, String name, Object data, String suffix){FileWriter out = null;String url = null;try {// 1.导入freemarker.jar// 2.获取模板(Template)对象// 获取Configuration对象 -- 为了获取模板对象Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);// 设置默认加载路径File file = new File(path);configuration.setDirectoryForTemplateLoading(file);// 设置默认编码configuration.setDefaultEncoding("UTF-8");// 获取模板Template template = configuration.getTemplate(name);// 3.准备数据(data)// map// java实体对象// 4.template.process()生成静态资源// 按照时间轴,生成文件名+后缀的url = System.currentTimeMillis() + suffix;// 准备文件路径与文件名File file2 = new File(file, url);// 文件写出流out = new FileWriter(file2);// 生成静态文件template.process(data, out);// 返回文件名urlreturn url;// 5.创建xxx.ftl模板// 模板中使用el表达式获取数据. el表达式: ${obj}} catch (Exception e) {e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}return url;}}

调用FreeMarkerUtil
在这里插入图片描述
功能模块:轮播图管理、开班信息、问题反馈

与文章管理模块相比,轮播图管理、开班信息多加了文件上传功能文件上传文件上传三要素:1、form表单的提交方式必须是post请求2、form表单上必须要设置一个enctype="multipart/form-data"3、input表单中必须有复杂表单项 -> type="file"代码:@Overridepublic void save(MultipartFile photo, Slide slide, HttpServletRequest req) throws Exception {//3.1获取路径,String realPath = req.getServletContext().getRealPath("/static/upload/");//判断是否有文件if (photo != null) {//2、输入流InputStream input = photo.getInputStream();//3.1.1创建路径File file = new File(realPath);if (!file.exists()) {//文件路径不存在//创建路径file.mkdirs();}//3.2拿到文件后缀String filename = photo.getOriginalFilename();String suffix = filename.substring(filename.lastIndexOf("."));//3.3时间轴生成文件名String name = System.currentTimeMillis() + suffix;//3.4文件写入的路径File file2 = new File(realPath, name);//3、输出流FileOutputStream output = new FileOutputStream(file2);//1、核心代码IOUtils.copy(input, output);//4、关流output.close();input.close();//5、写入slide对象//路径写入slideslide.setPath("/static/upload/" + name);//文件名写入slideslide.setName(name);}//判断添加还是修改if (slide.getId() == null) {//添加if (photo != null) {mapper.add(slide);}} else {//修改操作Slide slideOne = mapper.findOne(slide.getId());if (photo != null) {//删除文件夹中原来的文件//得到名字String name = slideOne.getName();File file = new File(realPath + name);if (file.exists()) {file.delete();}//执行修改mapper.update(slide);} else {//只修改权限//执行修改mapper.update(slide);}}}添加功能对应的sql语句 <!-- void add(Slide slide); 添加--><insert id="add">insert into t_slide(name, path, createDate, enable) values(#{name}, #{path}, #{createDate}, #{enable})</insert>修改功能对应得到sql语句<!-- void update(Slide slide); 修改--><update id="update">update t_slide set <if test="name != null">name=#{name},</if><if test="path != null">path=#{path},</if>createDate=#{createDate}, enable=#{enable} where id=#{id}</update>

功能模块:问题反馈

与文件上传功能相比,问题反馈由前台上传,后台可添加恢复记录与删除,其余功能与实用技术相同

功能模块:用户登录登出

1、使用拦截器2、保存登录信息使用cookie3、登录后,刷新页面用户信息依然存在:使用session拦截器java代码:@Overridepublic boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2) throws Exception {//获取sessionHttpSession session = req.getSession();//获取session中的userObject user = session.getAttribute("USER_IN_SESSION");//判断是否有user,没有user就表示,走的其它路径,则重定向到登录路径if (user == null) {//重定向到登录路径resp.sendRedirect("/system/login");//拦截return false;}//有user,则是登录路径return true;}Spring-MVC.xml配置:<!--配置拦截器组 --><mvc:interceptors><!-- 拦截器 --><mvc:interceptor><!-- 要拦截的配置,该配置必须写在不拦截的上面,/*拦截一级请求,/**拦截多级请求 --><mvc:mapping path="/system/**"/><!-- 只拦截后台路径 --><!-- 设置不拦截的配置 --><mvc:exclude-mapping path="/system/login"/><!-- 放行登录路径 --><mvc:exclude-mapping path="/system/feedback/save"/><!-- 问题反馈路径 --><!-- 配置拦截器 (拦截自己写的拦截器类:Interceptor.Xxx)--><bean class="cn.itsource.interceptor.LoginInterceptor" /></mvc:interceptor></mvc:interceptors>Cookie与Session使用,进行登录判断与保存user登录信息1、Controller层@RequestMapping(value="/login", method=RequestMethod.POST)@ResponseBodypublic AjaxResult login(String remember, String username, String password, HttpServletRequest req,HttpServletResponse resp, HttpSession session){try {User user = service.findLogin(username, password);//将user写入session中session.setAttribute("USER_IN_SESSION", user);//判断remember是否为null,为null则表示没有选中“记住我”if (remember != null) {//选中"记住我"//创建cookieCookie c1 = new Cookie("username", username);Cookie c2 = new Cookie("password", password);//设置生命周期c1.setMaxAge(7*27*3600);c2.setMaxAge(7*27*3600);//设置路径为根路径,c1.setPath("/");c2.setPath("/");//传入浏览器resp.addCookie(c1);resp.addCookie(c2);} else {//没有remember,表示没有选中"记住我",则需要获取Cookie,再清除里面的数据//获取Cookie,因为别人有可能使用Cookie传输了数据Cookie[] cookies = req.getCookies();//遍历for (Cookie cookie : cookies) {//如果getName的值为username,或者password,则清除if ("username".equals(cookie.getName()) || "password".equals(cookie.getName())) {//清除Cookiecookie.setMaxAge(0);//设置路径为根路径,清除根路径下所有的cookiecookie.setPath("/");//传入浏览器resp.addCookie(cookie);}}}return new AjaxResult();} catch (Exception e) {e.printStackTrace();//e.getMessage()打印返回的错误信息return new AjaxResult(false, e.getMessage());}}2、Service层@Overridepublic User findLogin(String username, String password) throws Exception {//查到一条userUser user = mapper.findByName(username);//判断是否查到if (user == null) {//自定义异常信息throw new Exception("用户不存在");} else{//判断密码是否相等if (password.equals(user.getPassword())) {return user;} else {//自定义异常信息throw new Exception("密码错误");}}}

4. 技术选型

(1)开发工具:idea(2)数据库:Mysql(3)后端框架:SSM(4)前端框架:jQuery(使用$)、Bootstrap(模态框)、GridManager表格插件①. jstl(页面取值<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>) + el(后台传值Map<String, Object> map,页面取值${ })【同步】②. jquery拼接【异步】(ajax)③. gridManager【异步】
回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}