SSM框架之期刊在线投稿系统

背景

本人大二java实训期间第一次做的一个比较完整(有登录、注册以及后台管理界面)的小型学生信息管理系统,大概花了2周左右的时间,功能也就是最基础的增删改查,用的是最基础的java-swing组件。大三开了一门jsp程序设计的课程,由于老师讲的比较枯燥,按照ppt一个个的知识点讲述实在是无聊,于是我自己花了50块钱在网上买了一个jsp+servlet+mysql的项目。我从头到尾跟着视频敲了一遍加上要理解以及解决期间遇到的bug大概花了3、4周的时间。后面自己用jsp设计了一个简单的系统参加学校比赛获得了三等奖。不过眼看快要毕业了如果只会jsp肯定是很难找到到工作的,于是在学习网站上又找了一个ssm框架的项开始自学,又花了一个月的时间,然后自己做了一个期刊在线投稿系统,由于还是初学,所以花了大概一个半月的时间从需求到设计再到实现。

一、 相关技术简介

技术路线
1.前端
easyui(界面设计)+ajax(发送请求数据)
2.后端
spring(容器) + springmvc(处理请求) + mybatis(数据库框架)
相关环境
1.编译、运行工具
jdk1.8
2.数据库
mysql8.0
3.服务器
tomcat8.5
相关工具
1.代码编辑工具
eclipse
2.数据库可视化管理工具
navicat

二、系统功能介绍

系统有三个角色,作者、专家、编辑,业务流程:作者投稿 -> 专家审核 -> 编辑复审 - >稿件发布。
作者模块
1.稿件信息管理
(1)作者如果没有注册过先进行注册、注册成功后跳转到登录界面
(2)作者登录后进入系统,可在线投递稿件、投递成功后稿件变为待审核状态
(3)可以查询各种状态的稿件信息、以及作者投递的所有稿件列表
2.个人信息管理
作者可以对个人信息进行查看、修改操作
专家模块
1.稿件信息管理
(1)专家登录后(账号、密码由管理员提供)进入管理系统,可以下载编辑分配的稿件进行审核,审核通过后稿件状态变为已通过,审核未通过状态变为未通过。
(2)专家可以查看编辑分配的稿件列表
2.个人信息管理
专家可以对个人信息进行查看、修改操作
编辑模块
1.稿件信息管理
(1)编辑可以在线分配稿件给专家进行审核
(2)编辑可以复审专家已审核通过的稿件
(3)编辑可以查看所有用户投递过来的稿件
2.稿件类别管理
编辑可以添加、修改、删除稿件类别(如果此稿件类别含有稿件则不允许删除操作)
3.用户信息管理
编辑可以查看作者、专家基本信息
4.个人信息管理
编辑可以对个人信息进行查看、修改操作

三、系统实现

由于三个模块代码实现差不多以下显示作者模块
作者实体

@Component
public class User {
	private int id;
	private String username;
	private String password;
	private String author_name;
	private String sex;
	private String phone_number;
	private String address;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getAuthor_name() {
		return author_name;
	}
	public void setAuthor_name(String author_name) {
		this.author_name = author_name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getPhone_number() {
		return phone_number;
	}
	public void setPhone_number(String phone_number) {
		this.phone_number = phone_number;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
}

作者控制器

@RequestMapping("/author")
@Controller
public class AuthorController {
	@Autowired
	private AuthorService authorService;
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserService userService;
	@Autowired
	private EditorService editorService;
	@RequestMapping(value="/index",method=RequestMethod.GET)
	public ModelAndView index(ModelAndView model,HttpServletRequest request) {
		int id = (Integer) request.getSession().getAttribute("id");
		User user = authorService.queryOwnInfo(id);
		model.addObject("user",user);
		model.setViewName("author/index");
		return model;
	}
/**
 * 跳转到添加稿件页面
 */
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public ModelAndView add(ModelAndView model) {
		Map<String,Object> queryMap = new HashMap();
		List<Nav> list = editorService.findNavList(queryMap);
		model.addObject("dataList",list);
		model.setViewName("author/addManuscript");
		return model;
	}
	/**
	 * 处理用户上传稿件请求
	 * @return
	 */
	@RequestMapping(value="/upload_file",method=RequestMethod.POST)
	@ResponseBody
	public Map<String,String> upload(Manuscript manuscript,MultipartFile manuscript_file,HttpServletRequest request,
			HttpServletResponse response
			) throws IOException{
		Map<String,String> ret = new HashMap<String,String>();
		if(StringUtils.isEmpty(manuscript.getAuthor_name())) {
			ret.put("type","error");
			ret.put("msg","作者姓名不能为空!");
			return ret;
		}
		String author_name = request.getSession().getAttribute("author_name").toString();
		if(!manuscript.getAuthor_name().equals(author_name)) {
			ret.put("type","error");
			ret.put("msg","请输入正确的姓名!");
			return ret;
		}
		if(StringUtils.isEmpty(manuscript.getTitle())) {
			ret.put("type","error");
			ret.put("msg","稿件标题不能为空!");
			return ret;
		}
		if(StringUtils.isEmpty(manuscript.getSummary())) {
			ret.put("type","error");
			ret.put("msg","稿件摘要不能为空!");
			return ret;
		}
		if(manuscript_file==null) {
			ret.put("type","error");
			ret.put("msg","文件没有选择");
			return ret;
		}
		if(manuscript_file.getSize() > 10485760){
			//文件没有选择
			ret.put("type", "error");
			ret.put("msg", "文件大小超过10M!");
			return ret;
		}
		String suffix = manuscript_file.getOriginalFilename().substring(manuscript_file.getOriginalFilename().lastIndexOf(".")+1,manuscript_file.getOriginalFilename().length());
		if(!"docx,doc,pdf".contains(suffix)) {
			ret.put("type","error");
			ret.put("msg","文件格式不正确!");
			return ret;
		}
		String savePath = request.getServletContext().getRealPath("/")+"\\upload\\";
		File savePathFile = new File(savePath);
		if(!savePathFile.exists()) {
			savePathFile.mkdir();
		}
		String fileName = new Date().getTime()+"."+suffix;
		ret.put("src",request.getServletContext().getContextPath() + "/upload/" + fileName);
		manuscript_file.transferTo(new File(savePath+fileName));
		manuscript.setFilePath(ret.get("src"));
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String format = sf.format(new Date());
		manuscript.setSubmit_time(format);
		manuscript.setId((Integer)request.getSession().getAttribute("id"));
		manuscript.setState("待审核");
		if(authorService.add(manuscript)<=0) {
			ret.put("type","error");
			ret.put("msg","稿件添加失败!");
			return ret;
		}
		ret.put("type", "success");
		ret.put("msg", "文件上传成功!");
		return ret;
	}
	/**
	 * 跳转到查询稿件的页面
	 */
	@RequestMapping(value="/queryManuscript",method=RequestMethod.GET)
	public ModelAndView queryManuscript(ModelAndView model) {
		model.setViewName("author/queryManuscript");
		return model;
	}
	/**
	 * 显示稿件数据列表
	 * @param manuscript
	 * @param manuscript_file
	 * @param request
	 * @param
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value="/get_list",method=RequestMethod.POST)
	@ResponseBody
		public Map<String,Object> getList(
				@RequestParam(value="state",required=true,defaultValue="") String state,
				Page page,
				HttpServletRequest request,HttpServletResponse response
				){
		Map<String,Object> ret = new HashMap<String,Object>();
		Map<String,Object> queryMap = new HashMap<String,Object>();
		System.out.print(state);
			page.setOffset();
			queryMap.put("offset",page.getOffset());
			queryMap.put("pageSize",page.getRows());
			queryMap.put("state","%"+state+"%");
			int id = (Integer) request.getSession().getAttribute("id");
			queryMap.put("id",id);
			List<Manuscript> list = authorService.findListById(queryMap);
			ret.put("rows",list);
			ret.put("total",authorService.getTotal(queryMap));
			return ret;
		}
	/**
	 * 跳转到查询个人信息的页面
	 */
	@RequestMapping(value="/queryOwnInfo",method=RequestMethod.GET)
	public ModelAndView queryOwnInfo(ModelAndView model) {
		model.setViewName("author/queryOwnInfo");
		return model;
	}
	/**
	 * 处理用户查询个人信息请求
	 * @param author_name
	 * @param title
	 * @param page
	 * @return
	 */
	@RequestMapping(value="/getOwnInfo",method=RequestMethod.POST)
	@ResponseBody
		public Map<String,Object> getOwnInfo(
				HttpServletRequest request,HttpServletResponse response
				){
		Map<String,Object> ret = new HashMap<String,Object>();
			int id = (Integer) request.getSession().getAttribute("id");
			User user = authorService.queryOwnInfo(id);
			List<User> list = new ArrayList();
			list.add(user);
			ret.put("rows",list);
			ret.put("total",1);
			return ret;
		}
	/**
	 * 跳转到修改个人信息的页面
	 */
	@RequestMapping(value="/editOwnInfo",method=RequestMethod.GET)
	public ModelAndView editOwnInfo(ModelAndView model) {
		model.setViewName("author/editOwnInfo");
		return model;
	}
	@RequestMapping(value="/editOwnInfo",method=RequestMethod.POST)
	@ResponseBody
	public Map<String,String> register(User user){
		Map<String,String> ret = new HashMap<String,String>();
		if(StringUtils.isEmpty(user.getUsername())) {
			ret.put("type","error");
			ret.put("msg","用户名不能为空!");
			return ret;
		}
		if(StringUtils.isEmpty(user.getPassword())) {
			ret.put("type","error");
			ret.put("msg","密码不能为空!");
			return ret;
		}
		if(StringUtils.isEmpty(user.getAuthor_name())) {
			ret.put("type","error");
			ret.put("msg","姓名不能为空!");
			return ret;
		}
		if(StringUtils.isEmpty(user.getPhone_number())) {
			ret.put("type","error");
			ret.put("msg","电话号码不能为空!");
			return ret;
		}
		if(user.getPhone_number().length()!=11) {
			ret.put("type","error");
			ret.put("msg","电话号码应为11位!");
			return ret;
		}
		/**
		 * 验证手机号码的正确性
		 */
		String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
		Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(user.getPhone_number());
        boolean isMatch = m.matches();
        if (!isMatch) {
        	ret.put("type","error");
			ret.put("msg","请输入正确的手机号");
			return ret;
        }
		if(StringUtils.isEmpty(user.getAddress())) {
			ret.put("type","error");
			ret.put("msg","居住地址不能为空!");
			return ret;
		}
		if(authorService.editOwnInfo(user) <= 0) {
			ret.put("type","error");
			ret.put("msg","修改失败!");
			return ret;
		}
		ret.put("type","success");
		ret.put("msg","修改成功!");
		return ret;
	}
}

这里返回给前端的数据类型是Json,需要在方法上加上@ResponseBody注解,方法返回类型使用map类型,当然也可以自定义一个返回类,在实际项目开发中控制器是不允许有这么多代码的,控制器方法一般只有一、二行代码调用service层将入参传给service即可,因为处理业务就是service做的事情,现在由于都使用前后端分离模式开发,后端只需要提供接口供前端调用即可,有几个接口,控制器就有几个方法。
作者-service

@Service
public interface AuthorService {
	public int add(Manuscript manuscript);
	public int getTotal(Map<String,Object> queryMap);
	public User queryOwnInfo(int id);
	public int editOwnInfo(User user);
	public List<Manuscript> findListById(Map<String,Object> queryMap);
}

作者实现类impl

@Service
public class AuthorServiceImpl implements AuthorService{
	@Autowired
	private AuthorDao authorDao;
	public int add(Manuscript manuscript) {
		// TODO Auto-generated method stub
		return authorDao.add(manuscript);
	}
	public int getTotal(Map<String, Object> queryMap) {
		// TODO Auto-generated method stub
		return authorDao.getTotal(queryMap);
	}
	public User queryOwnInfo(int id) {
		// TODO Auto-generated method stub
		return authorDao.queryOwnInfo(id);
	}
	public int editOwnInfo(User user) {
		// TODO Auto-generated method stub
		return authorDao.editOwnInfo(user);
	}
	public List<Manuscript> findListById(Map<String, Object> queryMap) {
		// TODO Auto-generated method stub
		return authorDao.findListById(queryMap);
	}
}

作者dao

@Repository
public interface AuthorDao {
	public int add(Manuscript munscript);
	public int getTotal(Map<String,Object> queryMap);
	public User queryOwnInfo(int id);
	public int editOwnInfo(User user);
	public List<Manuscript> findListById(Map<String,Object> queryMap);
}

作者mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.onlineSubmit.dao.AuthorDao">
 	<update id="add" parameterType="Manuscript">
 		insert into manuscript(manuscript_id,id,author_name,title,summary,submit_time,filePath,state,nav_id) values(null,#{id},#{author_name},#{title},#{summary},#{submit_time},#{filePath},#{state},#{nav_id})
 	</update>
 	<update id="editOwnInfo" parameterType="User">
  		update user set username = #{username},password = #{password},author_name = #{author_name},sex = #{sex},phone_number = #{phone_number},address=#{address} where id = #{id}
  	</update>
 	<select id="findList" parameterType="Map" resultType="Manuscript">
  		select * from manuscript where author_name like #{author_name} and title like #{title} limit #{offset},#{pageSize}
  	</select>
  	<select id="getTotal" parameterType="Map" resultType="Integer">
  		select count(*) from manuscript where id=#{id} and state like #{state}
  	</select>
  	<select id="queryOwnInfo" parameterType="Integer" resultType="User">
  		select * from user where id = #{id} 
  	</select>
  	<select id="findListById" parameterType="Map" resultType="Manuscript">
  		select * from manuscript where id = #{id} and state like #{state} limit #{offset},#{pageSize}
  	</select>
</mapper>

四、系统运行界面

登录界面
在这里插入图片描述
注册界面
在这里插入图片描述
稿件上传
在这里插入图片描述
稿件列表
在这里插入图片描述
稿件分配
在这里插入图片描述
在线审核
在这里插入图片描述

补充说明

不足之处
本系统需求阶段没有做充分,导致系统实现后与实际还是存在较大差异,仍然存在很多缺陷,比如:
1.系统只设定了一个专家,但实际应该有多个
2.专家审核时,没有设计文本框让专家输入意见(之后会加上这块需求)
3.重复代码过多,没有进行优化
4.控制层做了业务层的事情,系统耦合度提高,不好维护

2021-03-29 对系统部分功能的修改以及补充说明

1.系统现在可以设定多位专家,编辑可以将稿件分配给指定专家
2.增设管理员模块,可以对用户信息(系统所有用户)进行增删改查操作,也可以切换用户权限
3.专家、编辑审核稿件时,可以输入自己的意见,编辑可以查看专家的审稿记录
4.作者可以对稿件信息进行修改,然后重新上传
5.表结构变动,删除专家、编辑实体表,用户表增加user_type字段,以区分用户类别。

对应功能运行截图

管理员模块
在这里插入图片描述
切换用户权限
在这里插入图片描述
稿件分配给指定专家
在这里插入图片描述
专家审稿记录列表
在这里插入图片描述
稿件审核
在这里插入图片描述

关于2020-05-02对系统功能的改动

1.添加了主编模块,审稿流程调整为:
作者上传稿件 -> 专家审核 -> 编辑复审 -> 主编终审 ->稿件发布
2. 主编模块包含查询所有状态的稿件;对编辑审核通过的稿件进行终审。主编对自己信息的查看与修改操作。

主编查询稿件:在这里插入图片描述
终审操作与专家、编辑类似。

主编唯一性逻辑:
在这里插入图片描述
在这里插入图片描述

2022-06-20 对系统做的一些更新(这可能是最后一版,后面不打算更新了)

总的来说,做了以下几点更新:
1.界面样式做了一些优化,比之前好看一点,包括背景图片、图标样式、文字样式…
2.添加了稿件发布模块,游客可以不用登录即可访问系统已发布稿件,也可以给喜欢的稿件进行点赞
系统部分运行截图:
登录界面:
在这里插入图片描述
稿件发布界面:
在这里插入图片描述
文章详情页面:
在这里插入图片描述
作者模块:
在这里插入图片描述
个人信息:
在这里插入图片描述
专家审稿记录:
在这里插入图片描述
修改审稿意见:
在这里插入图片描述
编辑模块:
在这里插入图片描述
限于篇幅运行截图,就不再贴截图了。

其他

1.需要用来做毕设或者课设参考的可以联系我(QQ:1172820051)
2.数据库脚本文件附在文件夹中,如运行失败,可以尝试使用命令行,从下往上运行即可
3.可以在微信公众号搜索“程序员阿坤”或者扫描下方二维码,加入我的公众号,目前“项目学习小组”正在热更基于springboot+vue的前后端分离的期刊在线投稿系统(技术和功能都做了调整有很多亮点!)公众号会有详细介绍,另外公众号会定时分享学习方法,以及一些工作中的技术干货一起学习交流!
在这里插入图片描述

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿坤...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值