• 知识点5--CMS项目个人中心


    目前整套CMS-Demo剩下两个前端模块了,第一个是普通用户的个人中心以及管理员的管理页面,本篇我们来开发普通用户的个人中心

    在首页,我们留了一个登录后的代码

    <c:if test="${sessionScope.user!=null }">
    	<div class="btn-group dropleft">
    		<button type="button" class="btn btn-dark btn-sm dropdown-toggle"
    			data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${sessionScope.user.username }</button>
    		<div class="dropdown-menu">
    			<!-- Dropdown menu links -->
    			<ul>
    				<li><a href="/my/index.do">个人中心</a></li>
    				<li><a href="/passport/logout.do">注销</a></li>
    			</ul>
    		</div>
    	</div>
    </c:if>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这会让我们在登录后点击展示出一个盒子,里面有个人中心选项,跳转的方式也是后台跳,所以我们需要开发一个个人中心的Controller

    package com.wy.controller;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Date;
    import java.util.List;
    import java.util.UUID;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.github.pagehelper.PageInfo;
    import com.wy.bean.Article;
    import com.wy.bean.User;
    import com.wy.service.ArticleService;
    
    @Controller
    @RequestMapping("/my")
    public class MyController {
    	
    	@Resource
    	private ArticleService articleService;
    	
    
    	/**
    	 * 跳转到个人页面
    	 * @return
    	 */
    	@RequestMapping("/index.do")
    	public String index(){
    		
    		return "my/index";
    	}
    	
    	/**
    	 * 跳转我的文章
    	 * @return
    	 */
    	@RequestMapping("/articles.do")
    	public String articles(Article article,@RequestParam(defaultValue="1")Integer pageNum,
    			Model model,HttpSession session){
    		User user=(User) session.getAttribute("user");
    		article.setUserId(user.getId());
    		//文章查询限制
    		article.setDeleted(0);
    		List<Article> selectArticle = articleService.selectArticle(article, pageNum, 3);
    		PageInfo info=new PageInfo<>(selectArticle);
    		model.addAttribute("info", info);
    		return "my/articles";
    	}
    	
    	/**
    	 * 跳转发布文章
    	 * @return
    	 */
    	@RequestMapping("/push.do")
    	public String push(){
    		
    		return "my/fwb";
    	}
    	
    	//上传地址
    	//@Value(value="${pushPath}") 正常情况下应该有个properties的配置 但估计是SSM的问题获取不到这个值了,这里就先写死了
    	private String pushPath = "D:/pic";
    	
    	/**
    	 * 
    	 * @Title: publish 
    	 * @Description: 执行发布
    	 * @param article
    	 * @return
    	 * @return: boolean
    	 */
    	@ResponseBody
    	@PostMapping("/publish.do")
    	public boolean publish(MultipartFile file,  Article article ,HttpSession session) {
    		//判断是否上传了文件
    		if(file!=null &&!file.isEmpty()) {
    		 //文件上传	
    		 String path =pushPath;//文件上传的路径
    		 //获取原始名称 a.jpg
    		 String oldFileName = file.getOriginalFilename();
    		 // 为了防止文件重名.使用uuid产生随机数
    		  String fileName =UUID.randomUUID() +oldFileName.substring(oldFileName.lastIndexOf("."));
    			File f = new File(path,fileName);
    		  try {
    			file.transferTo(f);//把文件写入硬盘
    			article.setPicture(fileName);//数据库存储文件的名称
    		} catch (IllegalStateException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		}
    		User user=(User) session.getAttribute("user");
    		article.setUserId(user.getId());  //文章作者
    		//以下信息也可以放在配置文件中为了方便先写死
    		article.setStatus(0);//待审
    		article.setCreated(new Date());//发布时间
    		article.setHits(0);//点击量
    		article.setHot(0);//非热门
    		article.setDeleted(0);//未删除
    		article.setContentType("0");//普通html文本
    		
    		return articleService.insertArticle(article) >0;
    	}
    	
    	//文章详情
    	@ResponseBody
    	@GetMapping("/article.do")
    	public Article article(Integer id) {
    		return articleService.select(id);
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    随后准备一个前端的页面my/index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    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">
    <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">
    			<div class="col-md-12 bg-warning" style="height: 50px;line-height: 50px">
    				<img alt="" src="/resource/imgs/logo.jpg" class="rounded" style="width: 30px;height: 30px">
    				<span>个人中心span>
    				<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.user.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 list-group bg-light" style="height: 500px">
    				<div class=" text-center pt-4 pl-5 pr-3">
    					<a href="#" data="/my/articles.do" class="list-group-item list-group-item-action active">我的文章a>
    					<a href="#" data="/my/push.do" class="list-group-item list-group-item-action">发布文章a> 
    					<a href="#" class="list-group-item list-group-item-action">我的收藏a>
    					<a href="#" class="list-group-item list-group-item-action">我的评论a> 
    					<a href="#" class="list-group-item list-group-item-action disabled" tabindex="-1" aria-disabled="true">个人设置a>
    				div>
    			div>
    			
    			
    			<div class="col-md-10" id="articles" style="height: 500px">
    				
    				<div style="display: none">
    					<jsp:include page="/resource/kindeditor/jsp/demo.jsp">jsp:include>
    				div>
    			div>
    		div>
    		
    	div>
    	
    	
    	<script type="text/javascript">
    		//默认加载我的文章
    		$("#articles").load("/my/articles.do");
    		//跳转函数
    		$("a").click(function() {
    			//删除原本样式
    			$("a").removeClass("active");
    			$(this).addClass("active");
    			var url=$(this).attr("data");
    			$("#articles").load(url);
    		});
    	script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    到此先运行一下看效果,是否可以进入个人中心
    在这里插入图片描述

    在这里插入图片描述


    可以进入个人中心后,大家不难发现本次Demo目前只做了我的文章、发布文章两个功能,其他功能留给扩展,首先我们要完成默认的我的文章展示页面

    <%@ 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">
    <title>文章列表title>
    head>
    <body>
    	
    	<div class="container">
    		
    		<ul class="list-unstyled">
    			<c:forEach items="${info.list}" var="article">
    				<li class="media">
    					<img style="width: 60px;height: 60px" src="/pic/${article.picture}" class="mr-3 rounded" alt="...">
    					<div class="media-body">
    						<h5 class="mt-0 mb-1">${article.title }h5>
    						<p class="pt-1"><fmt:formatDate value="${article.created }" pattern="yyyy-MM-dd HH:mm:ss"/>
    							
    							<button type="button" class="btn btn-link" data-toggle="modal"
    								data-target="#exampleModalLong" onclick="detail(${article.id })">详情button>
    						p>
    					div>
    				li>
    				<hr>
    			c:forEach>
    		ul>
    	div>
    	<jsp:include page="/WEB-INF/view/common/bookstappages.jsp">jsp:include>
    	
    	<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="title">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">
    					<button type="button" class="btn btn-secondary"
    						data-dismiss="modal">关闭button>
    				div>
    			div>
    		div>
    	div>
    body>
    <script type="text/javascript">
    	//在模态框中显示文章的详情
    	function detail(id){
    		 //先清空院有的值
    		$("#title").empty();
    		$("#content").empty();
    		//查询文档详情
    		$.get("/my/article.do",{id:id},function(article){
    			$("#title").append(article.title);
    			$("#content").append(article.content);
    		})
    	}
    	
    	function goPage(pageNum) {
    		$("#articles").load("/my/articles.do?pageNum="+pageNum);
    	}
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    此时就可完成上图中间展示文章的效果,并且顺带着使用模态框开发了查看功能
    在这里插入图片描述


    现在我们开发第二个小功能发布文章,我们需要完成富文本页面的开发

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%
    request.setCharacterEncoding("UTF-8");
    String htmlData = request.getParameter("content1") != null ? request.getParameter("content1") : "";
    %>
    doctype html>
    <html>
    <head>
    	<meta charset="utf-8" />
    	<title>KindEditor JSPtitle>
    		<link rel="stylesheet" href="/resource/kindeditor/themes/default/default.css" />
    	<link rel="stylesheet" href="/resource/kindeditor/plugins/code/prettify.css" />
    	<script charset="utf-8" src="/resource/kindeditor/kindeditor.js">script>
    	<script charset="utf-8" src="/resource/kindeditor/lang/zh-CN.js">script>
    	<script charset="utf-8" src="/resource/kindeditor/plugins/code/prettify.js">script>
    	<script>
    		KindEditor.ready(function(K) {
    			window.editor1 = K.create('textarea[name="content1"]', {
    				cssPath : '/resource/kindeditor/plugins/code/prettify.css',
    				uploadJson : '/resource/kindeditor/jsp/upload_json.jsp',
    				fileManagerJson : '/resource/kindeditor/jsp/file_manager_json.jsp',
    				allowFileManager : true,
    				afterCreate : function() {
    					var self = this;
    					K.ctrl(document, 13, function() {
    						self.sync();
    						document.forms['example'].submit();
    					});
    					K.ctrl(self.edit.doc, 13, function() {
    						self.sync();
    						document.forms['example'].submit();
    					});
    				}
    			});
    			prettyPrint();
    		});
    	script>
    head>
    <body>
    	<%=htmlData%>
    	<form id="form1">
    		<div class="form-group">
    			<label for="title"> 文章标题:label> 
    			<input id="title" type="text" class="form-control" name="title">
    		div>
    		<div class="form-group form-inline">
    			所属栏目:<select class="form-control" id="channel" name="channelId">
    						<option>请选择option>
    					select> 
    			所属分类:<select class="form-control" id="category" name="categoryId">
    						<option>请选择option>
    					select>
    		div>
    		
    		<div class="form-group">
    		  <input type="file" name="file" class="form-control-file">
    		
    		div>
    		
    		<textarea name="content1" cols="100" rows="8" style="width:700px;height:200px;visibility:hidden;"><%=htmlspecialchars(htmlData)%>textarea>
    		<br />
    		<input class="btn btn-info" type="button" name="button" value="提交内容" onclick="publish()"/>
    	form>
    body>
    <script type="text/javascript">
    	//发布文章
    	function publish(){
    		//form表单中包含文件的。需要使用formData 对象
    		var formData = new FormData($("#form1")[0]);
    		//封装文章内容-带html标签的
    		formData.set("content",editor1.html());
    		
    		$.ajax({
    			type:"post",
    			data:formData,
    			url:"/my/publish.do",
    			processData:false,
    			contentType:false,
    			success:function(flag){
    				if(flag){
    					alert("发布成功!");
    					//发布成功跳转到我的文章页面
    					location.href="/my/index.do"
    				}else{
    					alert("发布失败!");
    				}
    			}
    		});
    	}
    	
    	
    	 $(function(){
    		 //当页面加载时,去查询所有的栏目
    		 $.get("/channel/channels.do",function(list){
    			//遍历栏目
    			for(var i in list){
    				$("#channel").append("+list[i].name+"")
    			}
    		 });
    		 //为栏目添加改变事件
    		 $("#channel").change(function(){
    			 //获取当前的栏目ID 
    			 var channelId =$(this).val();
    			 $("#category").val("");//先清空原有的分类的内容
    			 //根据栏目ID查询分类
    			 $.get("/channel/categorys.do",{channelId:channelId},function(list){
    					//遍历分类
    					for(var i in list){
    						$("#category").append("+list[i].name+"")
    					}
    				 });
    		 })
    	 })
    
    
    script>
    html>
    <%!
    private String htmlspecialchars(String str) {
    	str = str.replaceAll("&", "&");
    	str = str.replaceAll("<", "<");
    	str = str.replaceAll(">", ">");
    	str = str.replaceAll("\"", """);
    	return str;
    }
    %>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126

    上面这个页面大家直接复制就行,大家可以在网上自己查一查kindeditor富文本的教程,总体上就是准备好静态资源--》需要跳转它的页面手动加载一下--》具体使用页面该富文本编辑器有个自带的页面,改一改就行

    大家会发现,在富文本中写了去后台拿栏目数据的代码,所以我们需要开发获取栏目数据的后台接口

    package com.wy.controller;
    
    import java.util.List;
    
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.wy.bean.Category;
    import com.wy.bean.Channel;
    import com.wy.service.ChannelService;
    
    
    /**
     * 
     * @ClassName: ChannelController 
     * @Description: 栏目及分类
     * @author: charles
     * @date: 2020年4月2日 上午10:54:06
     */
    @RequestMapping("/channel")
    @Controller
    public class ChannelController {
    	@Resource
    	private ChannelService channelService;
    	
    	/**
    	 * 
    	 * @Title: channels 
    	 * @Description: 返回所有栏目的json
    	 * @return
    	 * @return: List
    	 */
    	@ResponseBody
    	@RequestMapping("/channels.do")
    	public List<Channel> channels(){
    		return channelService.selects();
    	}
    	/**
    	 * 
    	 * @Title: categorys 
    	 * @Description: 根据栏目查询分类
    	 * @param channelId
    	 * @return
    	 * @return: List
    	 */
    	@ResponseBody
    	@RequestMapping("/categorys.do")
    	public List<Category> categorys(Integer channelId){
    		return channelService.selectsByChannelId(channelId);
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    到此运行项目查看发布文章功能
    在这里插入图片描述
    在这里插入图片描述
    这个时候你要注意,整个业务流有一点没有完成,就是你发布了文章,但此时只有你可以看见,你在首先是看不到这个文章的,这是应为新发布的文章还没有管理员审核,这一点我们下一章开发
    在这里插入图片描述
    本项目目前以上传github :https://github.com/wangyang159/cmsdemo

  • 相关阅读:
    Pytorch API
    解锁高效创新:IPD策略如何重塑产品开发流程
    java包以及权限修饰符
    机器学习总结(一)——回归问题概述
    linux( CentOs)对mysql基本操作和密码修改
    Python位运算符
    Vue实现动态组件
    重学Elasticsearch第6章 : SpringBoot整合RestHighLevelClient
    擎创技术流 | ckman教程(3)CKman源码分析部署集群的主要步骤
    【NodeJs篇】关于path 路径模块的学习和使用
  • 原文地址:https://blog.csdn.net/dudadudadd/article/details/126884080