网络知识 娱乐 手把手教你设计一个CSDN系统

手把手教你设计一个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 = "没有关键字是 "" +keywords + "" 的相关资源,请联系站长!";
        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.setSex(userInfoBean.getGender());
                user.setLatelyLoginTime(new Date());
                userService.save(user);
                Subject subject = SecurityUtils.getSubject(