手把手教你设计一个CSDN系统
Posted 程序员springmeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你设计一个CSDN系统相关的知识,希望对你有一定的参考价值。
在CSDN发一个CSDN系统是什么体验?
大家都知道CSDN 有一个下载的模块,就是用户上传资源然后管理员会进行审核,上传资源的用户可以赚钱还可以赚积分。
那么个人可不可以开发这样的系统呢?
完全可以!
小孟前面就就可开发了一个,而且处理很详细的教程。具体的介绍如下所示:
一,技术简介
该项目非常详细的讲解了springboot,可以用于面试、毕设、学习等。
最新版的springboot2.0框架;
前端框架采用流行的Layui;
redis高性能缓存框架,存放热门数据,常用数据;
thymeleaf模版引擎;
shiro安全框架;
javamail集成,找回密码用到;
数据库连接池使用的是阿里巴巴的Druid;
全文检索lucene;
QQ第三方登录。
二,系统演示
系统不管是界面还是功能都非常的nice,如果想看详细的教程或者演示,也有对系统的本系统的学习
https://www.bilibili.com/video/BV1jJ41197BJ?p=110&vd_source=e64f225fc5daf048d2687502cb23bb3b
三,核心代码展示
/**
* 小孟V:jishulearn
*/
@RestController
@RequestMapping(value = "/article")
public class ArticleController
@Autowired
private ArcTypeService arcTypeService;
@Autowired
private ArticleService articleService;
@Autowired
private ArticleIndex articleIndex;
/**
* 按资源类型分页查询资源列表
* @param type
* @param currentPage
* @return
*/
@RequestMapping("/type/currentPage")
public ModelAndView type(@PathVariable(value = "type",required = false) String type, @PathVariable(value = "currentPage",required = false)Integer currentPage)
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
//类型的html代码
List arcTypleList = arcTypeService.listAll(Sort.Direction.ASC,"sort");
mav.addObject("arcTypeStr", HTMLUtil.getArcTypeStr(type,arcTypleList));
//资源列表
Map<String,Object> map = articleService.list(type,currentPage, Consts.PAGE_SIZE);
mav.addObject("articleList",map.get("data"));
//分页html代码
mav.addObject("pageStr",HTMLUtil.getPagation("/article/"+type,Integer.parseInt(String.valueOf(map.get("count"))),currentPage,"该分类还没有数据..."));
return mav;
/**
* 关键字分词搜索
*/
@RequestMapping("/search")
public ModelAndView search(String keywords,@RequestParam(value = "page",required = false) Integer page) throws ParseException, InvalidTokenOffsetsException, org.apache.lucene.queryparser.classic.ParseException, IOException
if(page==null)
page = 1;
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
//类型的html代码
List arcTypleList = arcTypeService.listAll(Sort.Direction.ASC,"sort");
mav.addObject("arcTypeStr", HTMLUtil.getArcTypeStr("all",arcTypleList));
//资源列表
List<Article> articleList = articleIndex.search(keywords);
Integer toIndex = articleList.size()>=page*Consts.PAGE_SIZE?page*Consts.PAGE_SIZE:articleList.size();
mav.addObject("articleList",articleList.subList((page-1)*Consts.PAGE_SIZE,toIndex));
mav.addObject("keywords",keywords);
//分页html代码
int totalPage = articleList.size()%Consts.PAGE_SIZE==0?articleList.size()/Consts.PAGE_SIZE:articleList.size()/Consts.PAGE_SIZE+1;
String targetUrl = "/article/search?keywords="+keywords;
String msg = "没有关键字是 \\"<font style=\\"border: 0px;color:red;font-weight:bold;padding-left: 3px; padding-right: 3px;\\" >" +keywords + "</font>\\" 的相关资源,请联系站长!";
mav.addObject("pageStr",HTMLUtil.getPagation2(targetUrl,totalPage,page,msg));
return mav;
/**
* 资源详情
*/
@RequestMapping("/detail/articleId")
public ModelAndView detail(@PathVariable(value = "articleId",required = false) String articleId) throws IOException, org.apache.lucene.queryparser.classic.ParseException
ModelAndView mav = new ModelAndView();
String replace = articleId.replace(".html","");
articleService.updateClick(Integer.parseInt(replace));
Article article = articleService.getById(Integer.parseInt(replace));
if(article.getState()!=2)
return null;
mav.addObject("article",article);
//类型的html代码
List arcTypleList = arcTypeService.listAll(Sort.Direction.ASC,"sort");
mav.addObject("arcTypeStr", HTMLUtil.getArcTypeStr(article.getArcType().getArcTypeId().toString(),arcTypleList));
//通过lucene分词查找相似资源
List<Article> articleList = articleIndex.searchNoHighLighter(article.getName().replace("视频","").replace("教程","")
.replace("下载","").replace("PDF",""));
if(articleList!=null&&articleList.size()>0)
mav.addObject("similarityArticleList",articleList);
mav.setViewName("detail");
return mav;
/**
* 判断资源是否免费
*/
@ResponseBody
@RequestMapping("/isFree")
public boolean isFree(Integer articleId)
Article article = articleService.getById(articleId);
return article.isFree();
/**
* 小孟V:jishulearn
*/
@Controller
@RequestMapping(value = "/comment")
public class CommentController
@Autowired
private CommentService commentService;
/**
* 前端提交保存评论信息
* @param comment
* @param session
* @return
*/
@ResponseBody
@PostMapping("/add")
public Map<String,Object> add(Comment comment, HttpSession session)
Map<String,Object> map = new HashMap<>();
comment.setContent(StringUtil.esc(comment.getContent()));
comment.setCommentDate(new Date());
comment.setState(0);
comment.setUser((User)session.getAttribute(Consts.CURRENT_USER));
commentService.save(comment);
map.put("success",true);
return map;
/**
* 分页查询某个资源的评论信息
*/
@ResponseBody
@RequestMapping(value = "/list")
public Map<String,Object> list(Comment s_comment, @RequestParam(value = "page",required = false)Integer page)
s_comment.setState(1);
Page<Comment> commentPage = commentService.list(s_comment,page,5, Sort.Direction.DESC,"commentDate");
Map<String,Object> map = new HashMap<>();
map.put("data", HTMLUtil.getCommentPageStr(commentPage.getContent())); //评论的HTML代码
map.put("total",commentPage.getTotalPages()); //总页数
return map;
/**
* 根路径及其他请求处理
*/
@Controller
public class IndexController
@Autowired
private ArcTypeService arcTypeService;
@Autowired
private ArticleService articleService;
@Autowired
private UserService userService;
@Autowired
private MessageService messageService;
@Value("$imgFilePath")
private String imgFilePath; //图片上传路径
/**
* 首页
*/
@RequestMapping("/")
public ModelAndView index()
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
//类型的html代码
List arcTypleList = arcTypeService.listAll(Sort.Direction.ASC,"sort");
mav.addObject("arcTypeStr", HTMLUtil.getArcTypeStr("all",arcTypleList));
//资源列表
Map<String,Object> map = articleService.list("all",1, Consts.PAGE_SIZE);
mav.addObject("articleList",map.get("data"));
//分页html代码
mav.addObject("pageStr",HTMLUtil.getPagation("/article/all",Integer.parseInt(String.valueOf(map.get("count"))),1,"该分类还没有数据..."));
return mav;
/**
* QQ登录回调
*/
@RequestMapping("/connect")
public String qqCallback(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws QQConnectException
response.setContentType("text/html;charset=utf-8");
AccessToken accessTokenObj = new Oauth().getAccessTokenByRequest(request);
String accessToken = null;
String openId = null;
String state = request.getParameter("state");
String session_state = (String) session.getAttribute("qq_connect_state");
if(StringUtil.isEmpty(session_state)||!session_state.equals(state))
System.out.println("非法请求");
return "redirect:/";
accessToken = accessTokenObj.getAccessToken();
if(StringUtil.isEmpty(accessToken))
System.out.println("没有获取到响应参数");
return "redirect:/";
session.setAttribute("accessToken",accessToken);
OpenID openIDObj = new OpenID(accessToken);
openId = openIDObj.getUserOpenID();
UserInfo qzoneUserInfo = new UserInfo(accessToken,openId);
UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
if(userInfoBean==null||userInfoBean.getRet()!=0||StringUtil.isNotEmpty(userInfoBean.getMsg()))
System.out.println("没有对应的qq信息");
return "redirect:/";
//获取用户成功
User currentUser = (User)session.getAttribute(Consts.CURRENT_USER);
if(currentUser!=null&&StringUtil.isNotEmpty(currentUser.getUserName())&&StringUtil.isNotEmpty(currentUser.getEmail())&&StringUtil.isEmpty(currentUser.getOpenId()))
currentUser.setOpenId(openId);
userService.save(currentUser);
session.setAttribute(Consts.CURRENT_USER,currentUser);
return "redirect:/";
User user = userService.findByOpenId(openId);
if(user==null) //该用户是第一次登录,先注册
user = new User();
user.setOpenId(openId);
user.setNickname(userInfoBean.getNickname());
String imgName = DateUtil.getCurrentDateStr()+".jpg";
downloadPicture(userInfoBean.getAvatar().getAvatarURL100(),imgFilePath+imgName);
user.setHeadPortrait(imgName);
user.setSex(userInfoBean.getGender());
user.setPassword(CryptographyUtil.md5("123456",CryptographyUtil.SALT));
user.setRegistrationDate(new Date());
user.setLatelyLoginTime(new Date());
//userService.save(user);
session.setAttribute(Consts.CURRENT_USER,user);
else //已经注册过,更新用户信息,直接将信息存入session 然后跳转
if(!user.isOff()) //非封号状态
user.setNickname(userInfoBean.getNickname());
user.妈妈再也不用担心爬虫被封号了!手把手教你搭建Cookies池