当前位置: 首页 > news >正文

网站开发报价石家庄学院

网站开发报价,石家庄学院,网站建设及报价,wordpress与imobitrax头部登录状态 shiro标签的引用 由于shiro标签不是html的原生标签&#xff0c;所有我们需要先引入一个额外的依赖&#xff0c;shiro的标签库(thymeleaf的拓展标签)。 <dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymel…

头部登录状态

shiro标签的引用

由于shiro标签不是html的原生标签,所有我们需要先引入一个额外的依赖,shiro的标签库(thymeleaf的拓展标签)。

	<dependency><groupId>com.github.theborakompanioni</groupId><artifactId>thymeleaf-extras-shiro</artifactId><version>2.0.0</version></dependency>

依赖添加好之后,然后,我们需要在com.fly.config.ShiroConfig 中初始化一下,注入对应的Bean, 页面才能渲染出来

    //用于thymeleaf模板使用shiro标签,shiro方言标签@Beanpublic ShiroDialect shiroDialect() {return new ShiroDialect();}

然后在需要使用shiro标签的html 文件的头部添加

<html xmlns:th="http://www.thymeleaf.org"xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

添加好之后,就可以使用<shiro:user></shiro:user> 将要权限控制的内容包起来,当然shiro 标签还有很多
在这里插入图片描述

用户信息存到session中

用户登录成功之后需要将用户的信息保存的session中。我们只需要在用户认证的方法中com.fly.shiro.OAuth2Realm 类的doGetAuthenticationInfo 方法中加上如下语句:

//        将登陆信息放在sessionSecurityUtils.getSubject().getSession().setAttribute("profile",profile);

经过如下如上设置我们就实现了登录头部状态的控制
在这里插入图片描述

完善个人信息

用户中心

用户中心主要就两个,我发的贴和我收藏的贴
在这里插入图片描述
我发的帖子,在这里插入代码片com.homework.controller.CenterController#center 查询条件只有用户id

        QueryWrapper<Post> wrapper = new QueryWrapper<Post>().eq("user_id", getProfileId()).orderByDesc("created");IPage<Map<String, Object>> pageData = postService.pageMaps(page, wrapper);request.setAttribute("pageData", pageData);

我的收藏

 IPage<Map<String, Object>> pageData = userCollectionService.pageMaps(page, new QueryWrapper<UserCollection>().eq("user_id", getProfileId()).orderByDesc("created"));postService.join(pageData, "post_id");request.setAttribute("pageData", pageData);

基本设置

  1. tab 切换回显的问题,一个页面有多个tab,如何让在选中tab 之后刷新不丢失原来的tab选中选项呢?答案是在url 后面加上#,这相当于标签的效果。
    在这里插入图片描述
    当前tab页标签定义:

在这里插入图片描述

static/mods/user.js 有如下语句:

  //显示当前tabif(location.hash){element.tabChange('user', location.hash.replace(/^#/, ''));}element.on('tab(user)', function(){var othis = $(this), layid = othis.attr('lay-id');if(layid){location.hash = layid;}});

我们在templates/common/static.html 放入了如下代码,并修改下信息

<script th:inline="javascript" th:if="${session.profile != null}">layui.cache.page = '';layui.cache.user = {username: [[${session.profile.username}]],uid: [[${session.profile.id}]],avatar: [[${session.profile.avatar}]],experience: 0,sex: [[${session.profile.gender}]]};layui.config({version: "3.0.0",base: '/mods/' //这里实际使用时,建议改成绝对路径}).extend({fly: 'index'}).use('fly');
</script>

通过上面代码,我们把初始化layui的部分js代码,页面中很多class或id 的div 就拥有了特定的监听或其他。其中就报货截取url 获取#后面的标签用于tab 回显功能,还有头像的上传功能封装等。
加上了上面代码之后你会发现经常会有个异常的弹框,那是浏览器控制台发现去访问/message/nums 的链接,在index.js 文件中找到 新消息通知,按照接口要求我们修改地址为/user/message/nums 并在添加该接口

    @ResponseBody@PostMapping("/message/nums")public Object getMessNums() {Map<Object, Object> result = new HashMap<>();result.put("status", 0);result.put("count", 3);return result;}
  1. 头像
    头像上传接口com.fly.controller.CenterController#upload,
    头像上传核心代码
        String orgName = file.getOriginalFilename();log.info("上传文件名为:" + orgName);
//        获取后缀名String suffixName = orgName.substring(orgName.lastIndexOf("."));log.info("上传的后缀名为:" + suffixName);
//        文件上传后的路径String filePath = Constant.uploadDir;if ("avatar".equalsIgnoreCase(type)) {fileName = "/avatar/avatar_" + getProfileId() + suffixName;} else if ("post".equalsIgnoreCase(type)) {fileName = "post/post_" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMAT) + suffixName;}File dest = new File(filePath + fileName);
//        检查目录是否存在if (!dest.getParentFile().exists()) {dest.getParentFile().mkdir();}//上传文件file.transferTo(dest);log.info("上传成功之后文件的路径={}", dest.getPath());

目前上传的图片我们是到了一个指定目录,然后nginx或者tomcat是可以读取这个目录的,所以可以通过url来访问,一般来说我们把图片上传到云存储服务上。这里先这样弄了。
头像上传之后,更新shiro 中的头像信息

    AccountProfile profile = getProfile();profile.setAvatar(url);

图片上传之后更新图像信息
在这里插入图片描述

  1. 密码
    密码重置接口com.fly.controller.CenterController#resetPwd
    接口代码比较简单:
    @ResponseBody@PostMapping("/resetPwd")public R restPwd(String nowpass, String pass) {//查询用户User user = userService.getById(getProfileId());if (user == null || !nowpass.equals(user.getPassword())) {return R.failed("密码不正确");}user.setPassword(pass);boolean result = userService.updateById(user);return R.ok(result);}

前端页面在 /user/setting.html

发表,编辑博客

发表和编辑博客是同一个页面,前端页面展示
在这里插入图片描述
ajax 请求代码:

    $(function() {layui.use('form', function() {var form = layui.form;//监听提交form.on('submit(post)', function (data) {$.ajax({url: '/user/post',type: "POST",data: data.field,success: function (res) {if (res.code == 0) {layer.msg("操作成功");setTimeout(function () {location.href="/post/" + res.data;}, 1000);} else {layer.msg(res.msg);}}});return false;});});});

后台接口在com.fly.controller.PostController类中:

  @ResponseBody@PostMapping("/user/post")public R postArticle(@Valid Post post, BindingResult bindingResult) {if (bindingResult.hasErrors()) {return R.failed(bindingResult.getFieldError().getDefaultMessage());}
//        新增文章if (post.getId() == null) {post.setUserId(getProfileId());post.setModified(new Date());post.setCreated(new Date());post.setCommentCount(0);post.setEditMode(Constant.EDIT_HTML_MODEL);post.setLevel(0);post.setRecommend(false);post.setViewCount(0);post.setVoteDown(0);post.setVoteUp(0);post.setStatus(Constant.NORMAL_STATUS);} else {Post tempPost = postService.getById(post.getId());if (tempPost.getUserId().equals(getProfileId())) {return R.failed("不是自己的帖子");}}postService.saveOrUpdate(post);// TODO: 2018/12/13 给所有订阅人发送消息return R.ok(post.getId());}

显示渲染博客

我们原先的显示博客内容是通过如下标签来显示的

<div class="detail-body photos" th:text="${post.content}"></div>

但这样显示出来的内容明显和我们预览的不一样,还需要经过layui的渲染,所以我们要加上一段js代码。在body后面加上(templates/post/index.html:253)

<script>layui.use(['fly','face'],function () {var $ = layui.$,fly=layui.fly;//        如果你是采用模板自带的编辑器,你需要开启以下语句来解析$('.detail-body').each(function () {var othis = $(this), html = othis.html();othis.html(fly.content(html));});

博文回显

用户编辑完博客之后,点击提交保存之后就可以 调用/user/post 进行博文回显,博客的地址com.fly.controller.PostController#index, 博文回显主要博文,用户,分类以及评论信息,核心代码如下:

        Map<String, Object> post = postService.getMap(new QueryWrapper<Post>().eq("id", id));userService.join(post, "user_id");categoryService.join(post, "category_id");Assert.notNull(post, "该文章已被删除");req.setAttribute("post", post);req.setAttribute("currentCategoryId", post.get("category_id"));Page<Comment> page = new Page<>();page.setCurrent(current);page.setSize(size);IPage<Map<String, Object>> pageData = commentService.pageMaps(page, new QueryWrapper<Comment>().eq("post_id", id).orderByDesc("created"));userService.join(pageData, "user_id");commentService.join(pageData, "parent_id");req.setAttribute("pageData", pageData);

前端页面在 templates/post/index.html 部分代码如下:
在这里插入图片描述
页面效果如下:
在这里插入图片描述
在这里插入图片描述

用户主页

博客评论功能

用户评论表:

CREATE TABLE `comment` (`id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`content` longtext NOT NULL COMMENT '评论的内容',`parent_id` bigint(32) DEFAULT NULL COMMENT '回复的评论ID',`post_id` bigint(32) NOT NULL COMMENT '评论的内容ID',`user_id` bigint(32) NOT NULL COMMENT '评论的用户ID',`vote_up` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '“顶”的数量',`vote_down` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '“踩”的数量',`level` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '置顶等级',`status` tinyint(2) DEFAULT NULL COMMENT '评论的状态',`created` datetime NOT NULL COMMENT '评论的时间',`modified` datetime DEFAULT NULL COMMENT '评论的更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

后端接口代码在在这里插入代码片

    @ResponseBody@PostMapping("/user/post/comment")public R commentAdd(@Valid Comment comment, BindingResult bindingResult) {Post post = postService.getById(comment.getPostId());Assert.isTrue(post != null, "该帖子已被删除");comment.setUserId(getProfileId());comment.setCreated(new Date());comment.setModified(new Date());comment.setStatus(Constant.NORMAL_STATUS);// TODO 记录动作// TODO 通知作者commentService.save(comment);return R.ok(null);}

前端页面在 templates/post/index.html 提交评论代码如下:
在这里插入图片描述
ajax 代码如下:

 layui.use(['fly','face'],function () {var $ = layui.$,fly=layui.fly;//        如果你是采用模板自带的编辑器,你需要开启以下语句来解析$('.detail-body').each(function () {var othis = $(this), html = othis.html();othis.html(fly.content(html));});var form = layui.form;//监听提交form.on('submit(comment)', function (data) {$.ajax({url:'/user/post/comment',data: data.field,type:'POST',success: function (res) {if (res.code == 0) {layer.msg('操作成功');setTimeout(function () {location.reload();}, 1000);} else {layer.msg(res.msg);}}});return false;});});

配置异步请求登录过滤器

在我们shiroConfig中,我们配置了非ajax的请求直接跳转到登录页面,但是受限的ajax请求则不能处理。
如未登录状态下直接评论文档,我们应该给出 请先登录 的提示。
在shiro中有很多过滤器。其中org.apache.shiro.web.filter.authc.UserFilter

在这里插入图片描述
在此我们继承UserFilter然后重写redirectToLogin方法。

public class AuthFilter extends UserFilter {@Overrideprotected void redirectToLogin(ServletRequest servletRequest, ServletResponse response) throws IOException {HttpServletRequest request = (HttpServletRequest) servletRequest;//        异步请求要先登录String header = request.getHeader("X-Requested-With");if (header != null && "XMLHttpRequest".equals(header)) {Subject subject = SecurityUtils.getSubject();if (!subject.isAuthenticated()) {response.setContentType("application/json;charset=UTF-8");response.getWriter().print(JSONUtil.toJsonStr(R.failed("请先登录!")));} else {super.redirectToLogin(servletRequest, response);}}}
}

然后在com.fly.config.ShiroConfig中注入AuthFilter 的Bean

 @Beanpublic AuthFilter authFilter(){return new AuthFilter();}

在这里插入图片描述

博客收藏功能

由于我们收藏按钮是通过js动态生成的,所以我们先在html中定义好存放收藏按钮的div,id 为LAY_jieAdmin
在这里插入图片描述
在static/mods/jie.js 中

    var asyncRender = function () {var div = $('.fly-admin-box'), jieAdmin = $('#LAY_jieAdmin');//查询帖子是否收藏if (jieAdmin[0] && layui.cache.user.uid != -1) {$.post("/user/post/collection/find",{postId: div.data('id')}, function (res) {console.log("--------------")jieAdmin.append('<span class="layui-btn layui-btn-xs jie-admin ' + (res.data.collection ? 'layui-btn-danger' : '') + '" type="collect" data-type="' + (res.data.collection ? 'remove' : 'add') + '">' + (res.data.collection ? '取消收藏' : '收藏') + '</span>');});}}();

其中layui.cache.user.uid 是在templates/common/static.html 中定义的。从上述代码中我们可以看出,js 代码根据后端的返回值动态的生成 收藏 or 取消收藏
后端接口如下:

    @ResponseBody@PostMapping("/user/post/collection/find")public R collectionFind(String postId) {int count = userCollectionService.count(new QueryWrapper<UserCollection>().eq("post_id", postId).eq("user_id", getProfileId()));return R.ok(MapUtil.of("collection", count > 0));}

按钮点击效果的实现代码如下:

    ,collect: function(div){var othis = $(this), type = othis.data('type');fly.json('/user/post/collection/'+ type +'/', {postId: div.data('id')}, function(res){if(type === 'add'){othis.data('type', 'remove').html('取消收藏').addClass('layui-btn-danger');} else if(type === 'remove'){othis.data('type', 'add').html('收藏').removeClass('layui-btn-danger');}});}};

后端代码比较简单,参见:com.fly.controller.PostController 中的相关方法。

效果图:
在这里插入图片描述

参考代码:

https://github.com/XWxiaowei/FlyBlog/tree/v5-collection-center


文章转载自:
http://adventureful.c7507.cn
http://broider.c7507.cn
http://nantes.c7507.cn
http://usareur.c7507.cn
http://scrotum.c7507.cn
http://marvin.c7507.cn
http://meridional.c7507.cn
http://grant.c7507.cn
http://hypoacid.c7507.cn
http://splendiferous.c7507.cn
http://mystique.c7507.cn
http://squalid.c7507.cn
http://abetter.c7507.cn
http://unfitting.c7507.cn
http://araneology.c7507.cn
http://weaponeer.c7507.cn
http://southeasterly.c7507.cn
http://uricacidemia.c7507.cn
http://genuflection.c7507.cn
http://amass.c7507.cn
http://jejunum.c7507.cn
http://fatality.c7507.cn
http://hellenic.c7507.cn
http://identify.c7507.cn
http://thioacetamide.c7507.cn
http://taroc.c7507.cn
http://filbert.c7507.cn
http://polytheistic.c7507.cn
http://patronym.c7507.cn
http://windstorm.c7507.cn
http://acutance.c7507.cn
http://bladdernose.c7507.cn
http://vaporisation.c7507.cn
http://veda.c7507.cn
http://anaesthesia.c7507.cn
http://odontalgia.c7507.cn
http://chemiloon.c7507.cn
http://suretyship.c7507.cn
http://erasure.c7507.cn
http://redemand.c7507.cn
http://isolator.c7507.cn
http://westmorland.c7507.cn
http://lest.c7507.cn
http://crabbily.c7507.cn
http://schoolwork.c7507.cn
http://liverleaf.c7507.cn
http://machining.c7507.cn
http://gynecologic.c7507.cn
http://apa.c7507.cn
http://flashbulb.c7507.cn
http://endotracheal.c7507.cn
http://edwardine.c7507.cn
http://uppish.c7507.cn
http://saddlefast.c7507.cn
http://antitail.c7507.cn
http://boaz.c7507.cn
http://disbennifit.c7507.cn
http://dayak.c7507.cn
http://boomlet.c7507.cn
http://thulium.c7507.cn
http://siquis.c7507.cn
http://euterpe.c7507.cn
http://preservice.c7507.cn
http://haggai.c7507.cn
http://arpeggione.c7507.cn
http://hardhack.c7507.cn
http://data.c7507.cn
http://japanner.c7507.cn
http://furitless.c7507.cn
http://maskanonge.c7507.cn
http://endodontia.c7507.cn
http://tarada.c7507.cn
http://infirmatory.c7507.cn
http://carcajou.c7507.cn
http://cabrilla.c7507.cn
http://emperorship.c7507.cn
http://aleph.c7507.cn
http://msp.c7507.cn
http://anticorrosive.c7507.cn
http://wiper.c7507.cn
http://mor.c7507.cn
http://spermaceti.c7507.cn
http://subsaline.c7507.cn
http://tatou.c7507.cn
http://rhumb.c7507.cn
http://amortise.c7507.cn
http://awhile.c7507.cn
http://oculate.c7507.cn
http://circlewise.c7507.cn
http://analeptic.c7507.cn
http://blasphemer.c7507.cn
http://portulacaceous.c7507.cn
http://convertor.c7507.cn
http://gallicism.c7507.cn
http://sagoyewatha.c7507.cn
http://barbellate.c7507.cn
http://faintish.c7507.cn
http://weighman.c7507.cn
http://keening.c7507.cn
http://polyonymous.c7507.cn
http://www.zhongyajixie.com/news/81490.html

相关文章:

  • wordpress小程序直播阳东网站seo
  • 加气站类型的网站建设搜索引擎优化的五个方面
  • 网站设计与实现作业进一步优化
  • 云南微网站搭建宁波免费seo在线优化
  • 大连网站建设哪家好员工培训课程
  • 展示型网站有哪些功能seo关键词优化报价
  • 洛阳建网站公司电商培训基地
  • 电子购物网站开发百度标注平台怎么加入
  • 网站 如何 备案html+css网页制作成品
  • 绍兴网站设计软件外包网
  • 非常好的资讯网站设计什么网站可以发布广告
  • 自己怎么做一个企业官网专业seo关键词优化
  • 男人和女人一起对愁愁的说话抖音关键词排名优化
  • 用jsp做的动态网站百度浏览器网址链接
  • php网站开发小程序百度平台营销
  • 大型门户网站建设工作总结上海关键词优化方法
  • 锦州做网站多少钱广告联盟
  • 用java如何做网站青岛seo整站优化公司
  • 深圳建设网官方网站北京网站推广公司
  • WordPress投票主题系统微信搜一搜seo优化
  • 我的免费网是个什么网站seo大牛
  • 杭州网站建设很 棒semen是什么意思
  • 网站建设需要岗位如何制作网页广告
  • 中国网站建设公司有哪些内容东莞网络科技公司排名
  • 怎样做网站的链接线上培训机构排名前十
  • led灯什么网站做推广好企业网站设计与实现论文
  • 海外网站营销广州全网推广
  • 南京行业网站建设百度推广托管
  • 手机 网站开发aspx网络营销策略分析案例
  • 网站seo快速排名seo技术推广