首先新建一个站点
创建之后会在
front-template文件夹下面自动创建gblt的资源
同时在hosts文件中 把域名写好,这样访问域名的时候就会为其分配对应的资源
我们在common包下创建对应的domain,mapper,service,因为后台管理系统和对应的站点都会使用到这些文件,同时xml文件也放在common包下的resources的mybatis文件夹中
在admin包中创建controller用于后台管理系统进行交互
在font包中创建路由controller和directive用于对站点进行交互
并在TagConfig 中队directive进行注册,以便站点的前台页面拿到directive中的标签
所有的站点的切入点都是这个方法
我们首先会访问站点设置中设置的默认首页的网页位置
我们采用form表单的方式去向后台提交数据
这里是向bbs路由类中的登录方法提交的数据
这里通过session的方式,把登录的用户数据存起来
登录成功之后,转跳至 当前站点对应的index资源
index.ftl
在前台页面中有许多freekmark的标签
我们通过这些标签可以获取到数据
我
我们创建了一个分类的标签
需要对标签类在TagConfig中进行注册
这里我们引入了通用的部分
这里面有对应转跳的各种方法
![]()
我们点击转跳到板块的方法,就会携带入参(分类id)进入到论坛路由类中的转跳板块方法
这里我们设置默认拿到的是当前分类下第一个板块的id,直接展示第一个板块下的帖子
同时如果我们点击相应板块 会触发此方法来获取相应板块id
路由类中
前端页面
帖子标签类中
我们可以进入发帖页面进行发帖
帖子路由类中
我们还可以进入帖子,查看帖子回复和回复
login.ftl
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>登录论坛</title> </head> <body> <div style="text-align: center;" > </div> <br/> <form action="/bs/login.whtml" method="post"> 账号:<input name="username"/> 密码:<input name="password" /> <p/> <input type="submit" value="提交"/> </form> <#include "/${realPath}public/footer.ftl"/> </body> </html>
index.ftl
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>论坛</title> </head> <body> <div style="text-align: center;"> <@bbs_classes_list siteId = '13'> <#list tag_list as classes> <div style="float: left; margin-left: 100px;" onclick="toBoard(${classes.id})"> <span> <img src="/${res}image/mailbox.png"/> </span> <span> ${classes.id}</span> <span>类名: ${classes.name}</span> <span>介绍: ${classes.description}</span> <hr/> </div> </#list> </@bbs_classes_list> </div> <#include "/${realPath}public/footer.ftl"/> </body> </html>
bbs.ftl
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>帖子</title> </head> <body> <div style="text-align: center;" > <@bbs_board_list siteId = '13' classId = "${classesId}"> <#list tag_list as board> <div style="float: left; margin-left: 100px;" onclick="toBBS(${board.id},${classesId})"> <span> <img src="/${res}image/mailbox.png"/> </span> <span>版面: ${board.name}</span> <span>版主: ${board.master}</span> <span>公告: ${board.pcard}</span> <hr/> </div> </#list> </@bbs_board_list> </div> <div style="clear:both"> <#if (boardId!=0)> <button onclick="post(${boardId},${classesId})">发帖</button> </#if> </div> <br/> <table border="1" style="clear:both;width: 1910px;"> <tr style="height: 45px"> <th width="382px">标题</th> <th width="955px">内容</th> <th width="191px">发布者</th> <th width="191px">发布时间</th> <th width="191px">最后时间</th> </tr> <@bbs_list siteId = '13' boardId = "${boardId}"> <#list tag_list as bbs> <tr style="height: 50px" onclick="enterPost(${bbs.id})"> <td width="382px" > <#if (bbs.topFlag==1)><img src="/${res}image/top.png"/></#if> <#if (bbs.goodFlag==1)><img src="/${res}image/good.png"/></#if>${bbs.title}</td> <td width="955px" >${bbs.content}</td> <td width="191px" >${bbs.sender}</td> <td width="191px" >${bbs.createTime}</td> <td width="191px" >${bbs.updateTime}</td> </tr> </#list> </@bbs_list> </table> <#include "/${realPath}public/footer.ftl"/> </body> </html>
writePost.ftl
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>发帖</title> </head> <body> <div style="text-align: center;" > </div> <br/> <form action="/bs/savePost/${boardId}/${classesId}.whtml" method="post"> 标题:<input name="title"/> 内容:<textarea name="content" ></textarea> <p/> <input type="submit" value="提交"/> </form> <#include "/${realPath}public/footer.ftl"/> </body> </html>
post.ftl
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>发帖</title> </head> <body> <div style="text-align: center;" > <table border="1" style="clear:both;width: 1910px;"> <tr style="height: 45px"> <th width="20%">帖子标题</th> <th width="70%">帖子内容</th> <th width="10%">发帖人</th> </tr> <@bbs_answer_list siteId = '13' rootId = "${rootId}"> <tr style="height: 50px"> <td width="20%" >${tag_bean.title}</td> <td width="70%" >${tag_bean.content}</td> <td width="10%" >${tag_bean.sender}</td> </tr> </@bbs_answer_list> </table> </div> <div style="text-align: center;" > <table border="1" style="clear:both;width: 1910px;"> <tr style="height: 45px"> <th width="382px">回复标题</th> <th width="955px">回复内容</th> <th width="191px">回复人</th> <th width="191px">回帖时间</th> <th width="191px">最后时间</th> </tr> <@bbs_answer_list siteId = '13' rootId = "${rootId}"> <#list tag_list as answer> <tr style="height: 50px"> <td width="382px" >${answer.title}</td> <td width="955px" >${answer.content}</td> <td width="191px" >${answer.sender}</td> <td width="191px" >${answer.createTime}</td> <td width="191px" >${answer.updateTime}</td> </tr> </#list> </@bbs_answer_list> </table> </div> <br/> <form action="/bs/saveAnswer/${rootId}.whtml" method="post"> 回复标题:<input name="title"/> 回复内容:<textarea name="content" ></textarea> <p/> <input type="submit" value="提交"/> </form> <#include "/${realPath}public/footer.ftl"/> </body> </html>
footer.ftl
<script type="text/javascript"> function toBoard(classesId){ window.location.href = "/bs/toBoard/" + classesId + ".whtml"; } function toBBS(boardId,classesId){ window.location.href = "/bs/toBBS/" + boardId +"/"+classesId+ ".whtml"; } function post(boardId,classesId){ window.location.href = "/bs/post/" + boardId + "/"+classesId+".whtml"; } function enterPost(rootId){ window.location.href = "/bs/enterPost/" + rootId + ".whtml"; } function login(){ window.location.href = "/bs/login.whtml"; } </script>
BbsRouterController
package tech.niua.front.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import tech.niua.admin.bbs.domain.Bbs; import tech.niua.admin.bbs.service.IBbsService; import tech.niua.admin.bbsanswer.domain.BbsAnswer; import tech.niua.admin.bbsanswer.service.IBbsAnswerService; import tech.niua.admin.board.domain.Board; import tech.niua.admin.board.service.IBoardService; import tech.niua.admin.classes.service.IClassesService; import tech.niua.admin.member.domain.Member; import tech.niua.admin.member.service.IMemberService; import tech.niua.admin.site.domain.Site; import tech.niua.common.enums.BusinessType; import tech.niua.front.annotation.View; import tech.niua.front.util.FrontUtils; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.io.File; @Controller @RequestMapping("/bs") @Slf4j public class BbsRouterController { @Autowired private FrontUtils frontUtils; @Autowired private IBbsService bbsService; @Autowired private IClassesService classesService; @Autowired private IBoardService boardService; @Autowired private IBbsAnswerService bbsAnswerService; @Autowired private IMemberService memberService; @Resource private HttpSession httpSession; // private Long classId; @ModelAttribute public void addAttributes(Model model) { String realPath = frontUtils.getRealTemplatePath(); Site site = frontUtils.loadSite(); String staticPath = "static" + File.separator + frontUtils.getRealTemplatePath(); model.addAttribute("res", staticPath); model.addAttribute("realPath", realPath); model.addAttribute("site", site); } /** * 登录部分 * @param model * @param member * @return */ @View(value = "登录", businessType = BusinessType.VIEW) @RequestMapping(value = {"/login.whtml"}) public String login(Model model, Member member) { String password = member.getPassword(); String username = member.getUsername(); QueryWrapper<Member> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("username",username); queryWrapper.eq("password",password); Member realMember = memberService.getOne(queryWrapper); //把登录的用户存到session里 if(realMember==null){ return frontUtils.getRealTemplatePath() + "login"; } httpSession.setAttribute("member",realMember); return frontUtils.getRealTemplatePath() + "index"; } /** * 进入对应分类 查看板块和帖子 * @param model * @param classesId * @return */ @View(value = "进入对应分类", businessType = BusinessType.VIEW) @RequestMapping("/toBoard/{classesId}.whtml") public String toBoard(Model model, @PathVariable("classesId") Long classesId) { model.addAttribute("classesId", classesId); QueryWrapper<Board> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("class_id",classesId); queryWrapper.orderByAsc("id"); queryWrapper.last("limit 1"); //默认拿到当前分类的第一个板块 Board board = boardService.getOne(queryWrapper); if(board != null){ Long boardId = board.getId(); model.addAttribute("boardId", boardId); } //如果板块为空,设置板块id为0(因为没有板块的id为0),供前台页面判断是否有板块数据,在前台用到boardId的地方可以判空 else { int boardId = 0; model.addAttribute("boardId", boardId); } model.addAttribute("classesId", classesId); return frontUtils.getRealTemplatePath() + "bbs"; } /** * 进入栏目 * @param model * @param boardId * @param classesId * @return */ @View(value = "进入栏目", businessType = BusinessType.VIEW) @RequestMapping(value = {"/toBBS/{boardId}/{classesId}.whtml"}) public String toBBS(Model model, @PathVariable("boardId") Long boardId,@PathVariable("classesId") Long classesId) { model.addAttribute("boardId", boardId); model.addAttribute("classesId", classesId); return frontUtils.getRealTemplatePath() + "bbs"; } /** * 去发帖界面 * @param model * @param boardId * @param classesId * @return */ @View(value = "发帖", businessType = BusinessType.VIEW) @RequestMapping(value = {"/post/{boardId}/{classesId}.whtml"}) public String post(Model model, @PathVariable("boardId") Long boardId,@PathVariable("classesId") Long classesId) { model.addAttribute("boardId", boardId); Bbs bbs = new Bbs(); model.addAttribute("bbs",bbs); model.addAttribute("classesId",classesId); return frontUtils.getRealTemplatePath() + "writePost"; } /** * 保存发帖并返回帖子主页 * @param model * @param boardId * @param bbs * @param classesId * @return */ @View(value = "保存发帖", businessType = BusinessType.VIEW) @RequestMapping(value = {"/savePost/{boardId}/{classesId}.whtml"}) public String savePost(Model model, @PathVariable("boardId") Long boardId, Bbs bbs,@PathVariable("classesId") Long classesId) { model.addAttribute("boardId", boardId); Site site = frontUtils.loadSite(); bbs.setSiteId(site.getId()); bbs.setBoardId(boardId); Object object = httpSession.getAttribute("member"); if(object!=null){ Member member = (Member) object; Long userId = member.getId(); bbs.setSenderUserId(userId); bbs.setSender(member.getNickname()); } bbsService.save(bbs); model.addAttribute("classesId", classesId); return frontUtils.getRealTemplatePath() + "bbs"; } /** * 进入回帖界面 * @param model * @param rootId * @return */ @View(value = "回帖", businessType = BusinessType.VIEW) @RequestMapping(value = {"/enterPost/{rootId}.whtml"}) public String enterPost(Model model, @PathVariable("rootId") Long rootId) { model.addAttribute("rootId", rootId); return frontUtils.getRealTemplatePath() + "post"; } /** * 保存回帖并返回帖子界面 * * @param model * @param rootId * @param bbsAnswer * @return */ @View(value = "保存回帖", businessType = BusinessType.VIEW) @RequestMapping(value = {"/saveAnswer/{rootId}.whtml"}) public String saveAnswer(Model model, @PathVariable("rootId") Long rootId, BbsAnswer bbsAnswer) { model.addAttribute("rootId", rootId); Site site = frontUtils.loadSite(); bbsAnswer.setSiteId(site.getId()); bbsAnswer.setRootId(rootId); Object object = httpSession.getAttribute("member"); if(object!=null){ Member member = (Member) object; bbsAnswer.setSenderUserId(member.getId()); bbsAnswer.setSender(member.getNickname()); } bbsAnswerService.save(bbsAnswer); return frontUtils.getRealTemplatePath() + "post"; } }
ClassesDirectivepackage tech.niua.front.directive.bbs; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import freemarker.core.Environment; import freemarker.template.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import tech.niua.admin.classes.domain.Classes; import tech.niua.admin.classes.service.IClassesService; import java.io.IOException; import java.util.List; import java.util.Map; @Component public class ClassesDirective implements TemplateDirectiveModel { public static final String TPL_NAME = "bbs_classes_list"; public static final String SITE_ID = "siteId"; public static final String CLASSES_ID = "id"; @Autowired private IClassesService classesService; /** * 获取分类列表 * @param siteId * @return */ public Object list(Object siteId) { QueryWrapper<Classes> queryWrapper = new QueryWrapper<>(); if (siteId != null) { queryWrapper.eq("site_id", Long.parseLong(siteId.toString())); } queryWrapper.eq("deleted_flag",0); List<Classes> classesList = classesService.list(queryWrapper); return classesList; } /** * @param environment 运行的环境 * @param map 方法参数map 方法名和值 * @param templateModels * @param templateDirectiveBody 输出形式 * @throws TemplateException * @throws IOException */ @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException { Object siteId = map.get(SITE_ID); //Object classesId = map.get(CLASSES_ID); environment.setVariable("tag_list", getModel(list(siteId))); templateDirectiveBody.render(environment.getOut()); } private DefaultObjectWrapper getBuilder() { return new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build(); } private TemplateModel getModel(Object o) throws TemplateModelException { return this.getBuilder().wrap(o); } }
BoardDirectivepackage tech.niua.front.directive.bbs; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import freemarker.core.Environment; import freemarker.template.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import tech.niua.admin.bbs.service.IBbsService; import tech.niua.admin.board.domain.Board; import tech.niua.admin.board.service.IBoardService; import tech.niua.admin.classes.service.IClassesService; import java.io.IOException; import java.util.List; import java.util.Map; @Component public class BoardDirective implements TemplateDirectiveModel { public static final String TPL_NAME = "bbs_board_list"; private static final String CLASS_ID = "classId"; private static final String SITE_ID = "site_id"; @Autowired private IBbsService bbsService; @Autowired private IClassesService classesService; @Autowired private IBoardService boardService; public Object list(Object siteId,Object classId) { QueryWrapper<Board> queryWrapper = new QueryWrapper<>(); if (siteId != null) { queryWrapper.eq("site_id", Long.parseLong(siteId.toString())); } if (classId != null) { queryWrapper.eq("class_id", Long.parseLong(classId.toString())); } queryWrapper.eq("deleted_flag",0); List<Board> boardList = boardService.list(queryWrapper); return boardList; } /** * * @param environment 运行的环境 * @param map 方法参数map 方法名和值 * @param templateModels * @param templateDirectiveBody 输出形式 * @throws TemplateException * @throws IOException */ @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException { Object siteId = map.get(SITE_ID); Object classId = map.get(CLASS_ID); environment.setVariable("tag_list", getModel(list(siteId,classId))); templateDirectiveBody.render(environment.getOut()); } private DefaultObjectWrapper getBuilder() { return new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build(); } private TemplateModel getModel(Object o) throws TemplateModelException { return this.getBuilder().wrap(o); } }
BbsDirectivepackage tech.niua.front.directive.bbs; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import freemarker.core.Environment; import freemarker.template.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import tech.niua.admin.bbs.domain.Bbs; import tech.niua.admin.bbs.service.IBbsService; import tech.niua.admin.classes.service.IClassesService; import java.io.IOException; import java.util.List; import java.util.Map; @Component public class BbsDirective implements TemplateDirectiveModel { public static final String TPL_NAME = "bbs_list"; private static final String BOARD_ID = "boardId"; private static final String SITE_ID = "site_id"; @Autowired private IBbsService bbsService; @Autowired private IClassesService classesService; public Object list(Object siteId,Object boardId) { QueryWrapper<Bbs> queryWrapper = new QueryWrapper<>(); if (siteId != null) { queryWrapper.eq("site_id", Long.parseLong(siteId.toString())); } if (boardId != null) { queryWrapper.eq("board_id", Long.parseLong(boardId.toString())); } queryWrapper.eq("deleted_flag",0); queryWrapper.last( "ORDER BY top_flag DESC, to_top_time DESC, tb_bbs.update_time DESC"); List<Bbs> bbsList = bbsService.list(queryWrapper); return bbsList; } /** * * @param environment 运行的环境 * @param map 方法参数map 方法名和值 * @param templateModels * @param templateDirectiveBody 输出形式 * @throws TemplateException * @throws IOException */ @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException { Object siteId = map.get(SITE_ID); Object boardId = map.get(BOARD_ID); environment.setVariable("tag_list", getModel(list(siteId,boardId))); templateDirectiveBody.render(environment.getOut()); } private DefaultObjectWrapper getBuilder() { return new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build(); } private TemplateModel getModel(Object o) throws TemplateModelException { return this.getBuilder().wrap(o); } }
BbsAnswerDirectivepackage tech.niua.front.directive.bbs; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import freemarker.core.Environment; import freemarker.template.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import tech.niua.admin.bbs.domain.Bbs; import tech.niua.admin.bbs.service.IBbsService; import tech.niua.admin.bbsanswer.domain.BbsAnswer; import tech.niua.admin.bbsanswer.service.IBbsAnswerService; import tech.niua.admin.member.domain.Member; import tech.niua.admin.member.service.IMemberService; import java.io.IOException; import java.util.List; import java.util.Map; @Component public class BbsAnswerDirective implements TemplateDirectiveModel { public static final String TPL_NAME = "bbs_answer_list"; private static final String ROOT_ID="rootId"; private static final String SITE_ID = "site_id"; @Autowired private IBbsAnswerService bbsAnswerService; @Autowired private IBbsService bbsService; @Autowired private IMemberService memberService; public Object list(Object siteId,Object rootId) { QueryWrapper<BbsAnswer> queryWrapper = new QueryWrapper<>(); if (siteId != null) { queryWrapper.eq("site_id", Long.parseLong(siteId.toString())); } if (rootId != null) { queryWrapper.eq("root_id", Long.parseLong(rootId.toString())); } queryWrapper.eq("deleted_flag",0); List<BbsAnswer> bbsAnswerList= bbsAnswerService.list(queryWrapper); return bbsAnswerList; } public Object post(Object siteId,Object rootId) { QueryWrapper<Bbs> queryWrapper = new QueryWrapper<>(); if (siteId != null) { queryWrapper.eq("site_id", Long.parseLong(siteId.toString())); } if (rootId != null) { queryWrapper.eq("id", Long.parseLong(rootId.toString())); } queryWrapper.eq("deleted_flag",0); Bbs bbs = bbsService.getOne(queryWrapper); Long userId = bbs.getSenderUserId(); QueryWrapper<Member> memberQueryWrapper = new QueryWrapper<>(); memberQueryWrapper.eq("id",userId); Member member = memberService.getOne(memberQueryWrapper); bbs.setSender(member.getNickname()); return bbs; } /** * * @param environment 运行的环境 * @param map 方法参数map 方法名和值 * @param templateModels * @param templateDirectiveBody 输出形式 * @throws TemplateException * @throws IOException */ @Override public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException { Object siteId = map.get(SITE_ID); Object rootId = map.get(ROOT_ID); environment.setVariable("tag_list", getModel(list(siteId,rootId))); environment.setVariable("tag_bean", getModel(post(siteId,rootId))); templateDirectiveBody.render(environment.getOut()); } private DefaultObjectWrapper getBuilder() { return new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25).build(); } private TemplateModel getModel(Object o) throws TemplateModelException { return this.getBuilder().wrap(o); } }