随着社会发展速度的愈来愈快,以及社会压力变化的越来越快速,致使很多人采取各种不同的方法进行解压。大多数人的稀释压力的方法,是捧一本书籍,心情地让自己沉浸在情节里面,以短暂的愉悦让自己得以释怀。晒书小说阅读网是典型的信息发布网站,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的数据库。而对于后者则要求应用程序功能完备,易使用等特点。
论文主要围绕小说阅读网站的设计与实现展开研究,遵循软件工程设计流程,在需求分析的基础上,明确了小说阅读网站的各项功能。利用springboot、 mybatis等技术,设计实现了一个基于B/S模式的小说阅读网站,可完成管理员管理数据,作者发布小说,用户阅读小说的功能,并对该小说阅读网站的各个功能模块进行测试。所设计的用户操作界面布局合理、交互友好。
该网站的使用可以使管理人员更加有效地掌握用户的各类信息数据,保证了用户数据的及时性和准确性,直接解决了用户数量大、 人员情况复杂与流动性大的管理难题,提升了小说阅读效率。
关键字: 小说阅读;B/S模式;springboot;mysql
【708】基于springboot小说阅读网站源码和论文
With the rapid development of society and the rapid change of social pressure, many people take different methods to decompress. The way most people dilute their pressure is to hold a book, immerse themselves in the plot in a mood, and let themselves be relieved with a short pleasure. As a typical information publishing website, the development of the website mainly includes the establishment and maintenance of the background database and the development of front-end applications. For the former, it is required to establish a database with strong data consistency and integrity and good data security. For the latter, the application program should be complete and easy to use.
The thesis mainly focuses on the design and implementation of novel reading website, follows the software engineering design process, and clarifies the functions of novel reading website on the basis of demand analysis. Using spring boot, mybatis and other technologies, a novel reading website based on B/S mode is designed and implemented, which can complete the functions of administrator managing data, author publishing novels, and user reading novels, and test each functional module of the novel reading website. The user interface designed is reasonable in layout and friendly in interaction.
The use of this website can enable managers to more effectively master various types of user information data, ensure the timeliness and accuracy of user data, directly solve the management problems of large number of users, complex personnel situation and large mobility, and improve the efficiency of novel reading.
Key words: novel reading; B/S mode; springboot; mysql
1 绪论
1.1 课题背景
在每天以亿数的新生网页中,没有纯正的书籍阅读的网站;在繁杂纷乱的网络资讯中,没能找到真正适合学生阅读书籍的网站。这是一个很尴尬的场面,而今,这种局面将会被打破了。较那些内容杂乱不堪的网站,晒书小说阅读网立足书籍信息更新,向用户提供最好最新的书籍。网站没有花里胡哨的功能,以内容取胜,以知识见长。
网络阅读是一种有别于传统纸张阅读的新型阅读方式,此种阅读方式的兴起、发展有赖于互联网的发展。网络阅读的特别是无纸张限制、无携带保存障碍、方便、节约资源。图书保存于网络,一点即可阅读,不用案头堆积如山,耗费巨大木材资源。
我们有一种错觉,似乎在印刷时期的所有人都在阅读并得到了启蒙。其实,真正通过阅读获得启蒙的人,占人口的比例很小。我的童年,除了原始的游戏和听老人讲故事,对外界几乎浑然不知,在大城市生活尚如此贫乏,更不要说农村了;而现在的孩子,从出生起眼睛就盯着电视和电脑屏幕,差异太大了!电视是迄今为止最为广泛的传媒,它使得世界人口的多数,特别是那些不识字的人和没有阅读习惯的人有了了解外部世界和娱乐的去处,这是传播史上的伟大进步。在这个意义上,无论我们怎样谴责电视,批评网络,它们有史以来最为完善地实现了人类声像的同步传播,开阔了社会最大多数人的眼界。互联网给我们带来了生活、工作、学习方式的大变革,并且这种变革将伴随着我们的终身。孙中山曾说过:“世界潮流,浩浩荡荡,顺之者昌,逆之者亡。”未来信息世界的竞技,是一场无硝烟的战争,计算机和 Internet 技术的教育已成为各国教育的制高点,网络阅读则是让我们获取和拥有高科技秘密武器的钥匙。无论教师、家长还是学生,都应有进入互联网、用好互联网,终身学习的观念。如今,站在新世纪的门槛,我们的网络阅读教育教学承担着神圣的使命,面临着巨大的挑战,应受到全社会的关注和支持大众传播正在演变为个体化的双向交流,网络的“屏幕阅读”正在以各种形式改变着个体的阅读方式。
2017 年 4 月,加拿大在互联网络上举办了一个"全国小说"的写作活动。参加活动的作家一共有 12 位,代表加拿大全国 12 个省区的作家。12 位知名作家在 12 个小时内完 成了一篇集体创作的小说。小说的主题是"跨国故事"(Cross Country Story)。
美国著名作家约翰·厄普代克与另外44名作家一起在网上合作完成了题为"故事由谋杀开始"的小说。这次网络小说写作活动由著名的网上书店亚马逊公司主持。网络小说又一次风靡一时。 据统计,目前国内上网的约 1000 万网民中,21 岁到 35 岁的占 80%。网络文学兴 起的背后是 70 年代乃至 80 年代出生的青年作家、青年文学爱好者的迅速成长。有人甚
至将网络文学形容为"时代新文化运动的先声",网络文学的兴起能够"吹响新文明的号 角"。
国内的网络书屋大致是在 1997 后出现的,网易等公司提供的免费空间,为初期书站的发展提供了物质基础。初期的网络书站主要以转载为主,版权意识薄弱。部分网站是通过将武侠、言情等实体书扫描到网上来充实网站内容,而更多的网站则是直接从别的站转载。在这种大环境下,黄金书屋利用先发优势牢牢占据了网络书站老大的位置。号称“上网读书不识黄金书屋,再称网虫也枉然”。
幻剑书盟和起点中文争霸为代表的 vip 制度形成时期。2013 年 5 月,起点中文网第二版问世并投入使用。2013 年 6 月,幻剑组建北京幻剑书盟科技发展有限公司,开始商业化的探索与转型。标志着vip 制度形成。第四、网络小说商业化运作和起点中文一统天下时期(2014~现在)。在 2014 年 10 月盛大收购起点中文网后,盛大就利用其铺设到全国和各种渠道,让众多喜欢看书并有付费能力的读者成了起点 Vip 会员。短短 3 个月间,读者群的增加使得大量作者涌入,使起点中文网拥有了业内90%的作者资源和读者资源。 由此可见,无论是国内还是国外,网络小说都被大家所喜爱并追崇。网上阅读的小说网站的点击量也越来越大。所以,小说网站的发展前景是美好而光明的。
package com.controller;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;
import com.entity.YuangongEntity;
import com.entity.view.YuangongView;
import com.service.YuangongService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MD5Util;
import com.utils.MPUtil;
import com.utils.CommonUtil;
/**
* 员工
* 后端接口
* @author
* @email
* @date 2021-04-27 11:11:19
*/
@RestController
@RequestMapping("/yuangong")
public class YuangongController {
@Autowired
private YuangongService yuangongService;
@Autowired
private TokenService tokenService;
/**
* 登录
*/
@IgnoreAuth
@RequestMapping(value = "/login")
public R login(String username, String password, String captcha, HttpServletRequest request) {
YuangongEntity user = yuangongService.selectOne(new EntityWrapper<YuangongEntity>().eq("gonghao", username));
if(user==null || !user.getMima().equals(password)) {
return R.error("账号或密码不正确");
}
String token = tokenService.generateToken(user.getId(), username,"yuangong", "员工" );
return R.ok().put("token", token);
}
/**
* 注册
*/
@IgnoreAuth
@RequestMapping("/register")
public R register(@RequestBody YuangongEntity yuangong){
//ValidatorUtils.validateEntity(yuangong);
YuangongEntity user = yuangongService.selectOne(new EntityWrapper<YuangongEntity>().eq("gonghao", yuangong.getGonghao()));
if(user!=null) {
return R.error("注册用户已存在");
}
Long uId = new Date().getTime();
yuangong.setId(uId);
yuangongService.insert(yuangong);
return R.ok();
}
/**
* 退出
*/
@RequestMapping("/logout")
public R logout(HttpServletRequest request) {
request.getSession().invalidate();
return R.ok("退出成功");
}
/**
* 获取用户的session用户信息
*/
@RequestMapping("/session")
public R getCurrUser(HttpServletRequest request){
Long id = (Long)request.getSession().getAttribute("userId");
YuangongEntity user = yuangongService.selectById(id);
return R.ok().put("data", user);
}
/**
* 密码重置
*/
@IgnoreAuth
@RequestMapping(value = "/resetPass")
public R resetPass(String username, HttpServletRequest request){
YuangongEntity user = yuangongService.selectOne(new EntityWrapper<YuangongEntity>().eq("gonghao", username));
if(user==null) {
return R.error("账号不存在");
}
user.setMima("123456");
yuangongService.updateById(user);
return R.ok("密码已重置为:123456");
}
/**
* 后端列表
*/
@RequestMapping("/page")
public R page(@RequestParam Map<String, Object> params,YuangongEntity yuangong,
HttpServletRequest request){
EntityWrapper<YuangongEntity> ew = new EntityWrapper<YuangongEntity>();
PageUtils page = yuangongService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, yuangong), params), params));
return R.ok().put("data", page);
}
/**
* 前端列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params,YuangongEntity yuangong,
HttpServletRequest request){
EntityWrapper<YuangongEntity> ew = new EntityWrapper<YuangongEntity>();
PageUtils page = yuangongService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, yuangong), params), params));
return R.ok().put("data", page);
}
/**
* 列表
*/
@RequestMapping("/lists")
public R list( YuangongEntity yuangong){
EntityWrapper<YuangongEntity> ew = new EntityWrapper<YuangongEntity>();
ew.allEq(MPUtil.allEQMapPre( yuangong, "yuangong"));
return R.ok().put("data", yuangongService.selectListView(ew));
}
/**
* 查询
*/
@RequestMapping("/query")
public R query(YuangongEntity yuangong){
EntityWrapper< YuangongEntity> ew = new EntityWrapper< YuangongEntity>();
ew.allEq(MPUtil.allEQMapPre( yuangong, "yuangong"));
YuangongView yuangongView = yuangongService.selectView(ew);
return R.ok("查询员工成功").put("data", yuangongView);
}
/**
* 后端详情
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id){
YuangongEntity yuangong = yuangongService.selectById(id);
return R.ok().put("data", yuangong);
}
/**
* 前端详情
*/
@RequestMapping("/detail/{id}")
public R detail(@PathVariable("id") Long id){
YuangongEntity yuangong = yuangongService.selectById(id);
return R.ok().put("data", yuangong);
}
/**
* 后端保存
*/
@RequestMapping("/save")
public R save(@RequestBody YuangongEntity yuangong, HttpServletRequest request){
yuangong.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
//ValidatorUtils.validateEntity(yuangong);
YuangongEntity user = yuangongService.selectOne(new EntityWrapper<YuangongEntity>().eq("gonghao", yuangong.getGonghao()));
if(user!=null) {
return R.error("用户已存在");
}
yuangong.setId(new Date().getTime());
yuangongService.insert(yuangong);
return R.ok();
}
/**
* 前端保存
*/
@RequestMapping("/add")
public R add(@RequestBody YuangongEntity yuangong, HttpServletRequest request){
yuangong.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
//ValidatorUtils.validateEntity(yuangong);
YuangongEntity user = yuangongService.selectOne(new EntityWrapper<YuangongEntity>().eq("gonghao", yuangong.getGonghao()));
if(user!=null) {
return R.error("用户已存在");
}
yuangong.setId(new Date().getTime());
yuangongService.insert(yuangong);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody YuangongEntity yuangong, HttpServletRequest request){
//ValidatorUtils.validateEntity(yuangong);
yuangongService.updateById(yuangong);//全部更新
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
yuangongService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
/**
* 提醒接口
*/
@RequestMapping("/remind/{columnName}/{type}")
public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request,
@PathVariable("type") String type,@RequestParam Map<String, Object> map) {
map.put("column", columnName);
map.put("type", type);
if(type.equals("2")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
Date remindStartDate = null;
Date remindEndDate = null;
if(map.get("remindstart")!=null) {
Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
c.setTime(new Date());
c.add(Calendar.DAY_OF_MONTH,remindStart);
remindStartDate = c.getTime();
map.put("remindstart", sdf.format(remindStartDate));
}
if(map.get("remindend")!=null) {
Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
c.setTime(new Date());
c.add(Calendar.DAY_OF_MONTH,remindEnd);
remindEndDate = c.getTime();
map.put("remindend", sdf.format(remindEndDate));
}
}
Wrapper<YuangongEntity> wrapper = new EntityWrapper<YuangongEntity>();
if(map.get("remindstart")!=null) {
wrapper.ge(columnName, map.get("remindstart"));
}
if(map.get("remindend")!=null) {
wrapper.le(columnName, map.get("remindend"));
}
int count = yuangongService.selectCount(wrapper);
return R.ok().put("count", count);
}
}
package com.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pojo.*;
import com.pojo.result.Result;
import com.pojo.result.ResultPage;
import com.service.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* <p>
* 积分物品表 前端控制器
* </p>
*
* @since 2022-09-06
*/
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
private BookService bookService;
@Autowired
private CategoryService categoryService;
@Autowired
private CommentService commentService;
@Autowired
private UserService userService;
@Autowired
private MarkService markService;
//添加书籍
@PostMapping("/add")
public Result add(Book book) {
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
//验证表单信息
if (bookService.getOne(new LambdaQueryWrapper<Book>().eq(Book::getName, book.getName())) != null) {
return Result.failure("已有相同名称的书籍,请重新命名");
} else {
book.setUserId(currentUser.getId());
book.setCreateDate(new Date());
book.setAuthor(currentUser.getName());
return Result.decide(bookService.save(book));
}
}
//删除书籍
@PostMapping("/delete")
public Result delete(@RequestParam(value = "id") String id) {
return Result.decide(bookService.removeById(id));
}
//修改书籍
@PostMapping("/update")
public Result update(Book book) {
Book currentBook = bookService.getById(book.getId());
//验证表单信息
if (bookService.getOne(new LambdaQueryWrapper<Book>().eq(Book::getName, book.getName())) != null
&& !book.getName().equals(currentBook.getName())) {
return Result.failure("已有相同名称的商品,请重新命名");
} else {
return Result.decide(bookService.updateById(book));
}
}
//根据id获取书籍
@PostMapping("/getOne")
public Result getOne(@RequestParam(value = "id") String id) {
return Result.success(bookService.getById(id));
}
//条件分页获取
@RequestMapping("/getAll")
public ResultPage getAll(@RequestParam(value = "userName", required = false) String userName,
@RequestParam(value = "bookName", required = false) String bookName,
@RequestParam(value = "categoryId", required = false) String categoryId,
@RequestParam(value = "page") Integer page,
@RequestParam(value = "limit") Integer limit) {
//分页条件
PageHelper.startPage(page, limit);
//获取当前用户信息
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
List<Book> ls = bookService.getAll(userName, bookName, categoryId, currentUser.getRoleId() == 0 ? null : currentUser.getId());
PageInfo<Book> pageInfo = new PageInfo<>(ls, limit);
return new ResultPage(0, (int) pageInfo.getTotal(), pageInfo.getList());
}
//首页点击榜数据展示
@RequestMapping("/listClickRank")
public Result listClickRank(String num) {
LambdaQueryWrapper<Book> query = new LambdaQueryWrapper<>();
query.eq(Book::getStatus, 1)
.orderByDesc(Book::getHits)
.last("limit " + num);
return Result.success(bookService.list(query));
}
//展示书籍详情
@RequestMapping("/getBookDetail/{bookId}")
public ModelAndView getBookDetail(@PathVariable String bookId) {
ModelAndView mv = new ModelAndView();
//作品信息
Book book = bookService.getById(bookId);
try {
//点击量+1
LambdaUpdateWrapper<Book> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(Book::getHits, book.getHits() + 1)
.eq(Book::getId, bookId);
bookService.update(updateWrapper);
} catch (Exception e) {
e.printStackTrace();
}
Category category = categoryService.getOne(book.getCategoryId());
book.setCategoryName(category.getName());
mv.addObject("book", book);
//评论信息
LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(Comment::getBookId, bookId);
List<Comment> commentList = commentService.list(queryWrapper);
for (Comment comment : commentList) {
User user = userService.getById(comment.getUserId());
comment.setUserName(user == null ? "历史用户" : user.getName());
}
mv.addObject("commentList", commentList);
//评分
mv.addObject("mark", markService.selectAvg(bookId));
mv.setViewName("/index/bookDetail.html");
return mv;
}
//全部作品页面
@RequestMapping("/bookList")
public ModelAndView bookList() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/index/bookList.html");
return mv;
}
//条件分页获取分类
@RequestMapping("/searchByPage")
public Result searchByPage(@RequestParam(value = "keyword", required = false) String keyWord,
@RequestParam(value = "catId", required = false) String categoryId,
@RequestParam(value = "curr") Integer page,
@RequestParam(value = "limit") Integer limit) {
//分页条件
PageHelper.startPage(page, limit);
//获取当前用户信息
User currentUser = (User) SecurityUtils.getSubject().getPrincipal();
List<Book> ls = bookService.getAllIndex(keyWord, categoryId);
PageInfo<Book> pageInfo = new PageInfo<>(ls, limit);
return Result.success(pageInfo);
}
//排行榜页面
@RequestMapping("/bookRankPage")
public ModelAndView bookRankPage() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/index/bookRank.html");
return mv;
}
//排行榜数据展示
@RequestMapping("/bookRankList")
public Result bookRankList(String type) {
List<Book> ls = null;
LambdaQueryWrapper<Book> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Book::getStatus, 1)
.last("limit 30");
if ("0".equals(type)) {
//点击榜
queryWrapper.orderByDesc(Book::getHits);
ls = bookService.list(queryWrapper);
for (Book book : ls) {
Category category = categoryService.getOne(book.getCategoryId());
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
book.setCategoryName(category.getName());
}
} else if ("1".equals(type)){
//收藏榜
queryWrapper.orderByDesc(Book::getCollectNum);
ls = bookService.list(queryWrapper);
for (Book book : ls) {
Category category = categoryService.getOne(book.getCategoryId());
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
book.setCategoryName(category.getName());
}
} else {
//评分榜
ls = bookService.list(queryWrapper);
for (Book book : ls) {
//分类
Category category = categoryService.getOne(book.getCategoryId());
book.setCategoryName(category.getName());
//评分
Double mark = markService.selectAvg(book.getId());
BigDecimal b = new BigDecimal(mark);
book.setMark(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
}
Collections.sort(ls, (a, b) -> {
return b.getMark().compareTo(a.getMark());
});
}
return Result.success(ls);
}
//作家榜,根据作家的作品的收藏总数排序
@RequestMapping("/authorRankList")
public Result authorRankList() {
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(User::getStatus, 1)
.eq(User::getRoleId, 1)
.last("limit 30");
List<User> ls = userService.list(queryWrapper);
for (User user : ls) {
Integer collectNum = bookService.getCollectNum(user.getId());
user.setAllCollectNums(collectNum == null ? 0 : collectNum);
}
Collections.sort(ls, (a, b)->{
return b.getAllCollectNums() - a.getAllCollectNums();
});
return Result.success(ls);
}
}
文章评论