├── .gitignore ├── .idea ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jarRepositories.xml ├── misc.xml ├── uiDesigner.xml ├── vcs.xml ├── webContexts.xml └── workspace.xml ├── README.md ├── pom.xml ├── src └── main │ ├── java │ └── com │ │ └── jsj │ │ ├── bean │ │ ├── Comment.java │ │ ├── CommentUser.java │ │ ├── Community.java │ │ ├── Invitation.java │ │ ├── InvitationUser.java │ │ ├── InvitationUserCommunity.java │ │ └── User.java │ │ ├── controller │ │ ├── CommentController.java │ │ ├── CommunityController.java │ │ ├── InvitationController.java │ │ └── UserController.java │ │ ├── converter │ │ └── DateConverter.java │ │ ├── mapper │ │ ├── BaseMapper.java │ │ ├── CommentMapper.java │ │ ├── CommentMapper.xml │ │ ├── CommunityMapper.java │ │ ├── CommunityMapper.xml │ │ ├── InvitationMapper.java │ │ ├── InvitationMapper.xml │ │ ├── UserMapper.java │ │ └── UserMapper.xml │ │ └── service │ │ ├── CommentService.java │ │ ├── CommunityService.java │ │ ├── Impl │ │ ├── CommentServiceImpl.java │ │ ├── CommunityServiceImpl.java │ │ ├── InvitationServiceImpl.java │ │ └── UserServiceImpl.java │ │ ├── InvitationService.java │ │ └── UserService.java │ ├── resources │ ├── SpringMvc.xml │ ├── db.properties │ ├── log4j.properties │ ├── mybatis-config.xml │ ├── spring.xml │ └── ssm_community.sql │ └── webapp │ ├── WEB-INF │ ├── view │ │ ├── comment.jsp │ │ ├── community.jsp │ │ ├── error │ │ │ ├── 404.jsp │ │ │ ├── 405.jsp │ │ │ └── 500.jsp │ │ ├── header.jsp │ │ ├── index.jsp │ │ ├── invitation.jsp │ │ ├── login.jsp │ │ ├── register.jsp │ │ ├── search.jsp │ │ └── user │ │ │ └── index.jsp │ └── web.xml │ └── static │ ├── bootstrap │ ├── css │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── js │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── css │ ├── header.css │ ├── invitation.css │ ├── login.css │ ├── style.css │ └── userIndex.css │ ├── js │ ├── header.js │ ├── jquery.min.js │ └── userIndex.js │ └── wangEditor │ ├── fonts │ └── w-e-icon.woff │ ├── wangEditor.min.css │ ├── wangEditor.min.js │ └── wangEditor.min.js.map └── ssm_community.iml /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /src/test -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/webContexts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于ssm框架实现的简单社区平台 2 | 本项目基于ssm框架实现的社区论坛网站,一定程度上参考了百度贴吧,采用[wangEditor富文本](http://www.wangeditor.com/)实现的发帖、评论功能。本项目前端基于[Bootstrap](https://v4.bootcss.com/)UI框架,对页面做了移动端的适配。本项目暂无后台管理系统。 3 | 4 | ## 项目环境 5 | jdk:1.8 6 | maven:3.6 7 | 数据库环境:MySQL8 + c3p0连接池 8 | 集成开发环境:Idea 2019 9 | web容器:Tomcat 9 10 | 11 | ## 起步 12 | 首先,我们需要使用maven搭建ssm框架环境。 13 | 关于搭建ssm框架环境请参考我的博客:[Spring+SpringMvc+Mybatis框架整合](https://www.cnblogs.com/LeoCoding/p/11571816.html) 14 | ,以及我的另一个项目[ssm入门案例](https://github.com/Lionel340/ssm) 15 | 16 | ## 项目结构 17 | ├── README.md 18 | ├── pom.xml 19 | └── src 20 | └── main 21 | ├── java 22 | │ └── com 23 | │ └── jsj 24 | │ ├── bean -- JavaBean实体类 25 | │ ├── controller -- SpringMVC-WEB层控制器 26 | │ ├── converter -- 数据类型转换器 27 | │ ├── mapper -- Mybatis接口和映射文件。本项目采用了mybatis的接口开发,所以接口和映射文件放在同一目录下,并且名称相同。 28 | │ └── service -- service业务层 29 | ├── resources 30 | │ ├── db.properties -- 数据源配置文件 31 | │ ├── log4j.properties -- 日志配置文件 32 | │ ├── spring.xml -- spring整合mybatis的配置文件 33 | │ ├── SpringMvc.xml -- springmvc的配置文件 34 | │ ├── mybatis-config.xml -- mybatis的配置文件 35 | │ └── ssm_community.sql -- 项目数据库创建和表创建的SQL语句 36 | └── webapp 37 | ├── static 38 | │ ├── bootstrap -- bootstrap依赖文件 39 | │ ├── css -- 样式文件 40 | │ ├── js -- javascript脚本文件 41 | │ └── wangEditor -- wangEditor富文本依赖文件 42 | └── WEB-INF 43 | ├── web.xml -- web部署文件 44 | └── view -- 视图jsp文件 45 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.jsj 8 | ssm_community 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | ssm_community Maven Webapp 13 | 14 | http://www.example.com 15 | 16 | 17 | UTF-8 18 | 1.7 19 | 1.7 20 | 5.2.0.RELEASE 21 | 22 | 1.7.25 23 | 1.2.17 24 | 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | 4.13.1 32 | test 33 | 34 | 35 | 36 | log4j 37 | log4j 38 | ${log4j.version} 39 | 40 | 41 | org.slf4j 42 | slf4j-api 43 | ${slf4j.version} 44 | 45 | 46 | org.slf4j 47 | slf4j-log4j12 48 | ${slf4j.version} 49 | 50 | 51 | 52 | org.springframework 53 | spring-webmvc 54 | ${spring.version} 55 | 56 | 57 | 58 | org.springframework 59 | spring-jdbc 60 | ${spring.version} 61 | 62 | 63 | 64 | mysql 65 | mysql-connector-java 66 | 8.0.16 67 | runtime 68 | 69 | 70 | 71 | com.mchange 72 | c3p0 73 | 0.9.5.4 74 | 75 | 76 | 77 | org.mybatis 78 | mybatis 79 | 3.4.6 80 | 81 | 82 | org.mybatis 83 | mybatis-spring 84 | 1.3.2 85 | 86 | 87 | 88 | com.github.pagehelper 89 | pagehelper 90 | 5.1.10 91 | 92 | 93 | 94 | javax.servlet 95 | javax.servlet-api 96 | 3.1.0 97 | 98 | 99 | 100 | javax.servlet 101 | jstl 102 | 1.2 103 | 104 | 105 | 106 | com.alibaba 107 | fastjson 108 | 1.2.58 109 | 110 | 111 | 112 | com.fasterxml.jackson.core 113 | jackson-databind 114 | 2.10.0 115 | 116 | 117 | com.fasterxml.jackson.core 118 | jackson-core 119 | 2.10.0 120 | 121 | 122 | 123 | 124 | 125 | community 126 | 127 | 128 | org.apache.maven.plugins 129 | maven-compiler-plugin 130 | 131 | 8 132 | 8 133 | 134 | 135 | 136 | 137 | 138 | src/main/java 139 | 140 | **/*.properties 141 | **/*.xml 142 | 143 | 144 | 145 | src/main/resources 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/Comment.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | import java.util.Date; 4 | 5 | public class Comment { 6 | 7 | private Integer id; 8 | 9 | private Integer invitationId; 10 | 11 | private Integer userId; 12 | 13 | private Integer cinId; 14 | 15 | private Integer cforId; 16 | 17 | private Date time; 18 | 19 | private String content; 20 | 21 | public Integer getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Integer id) { 26 | this.id = id; 27 | } 28 | 29 | public Integer getInvitationId() { 30 | return invitationId; 31 | } 32 | 33 | public void setInvitationId(Integer invitationId) { 34 | this.invitationId = invitationId; 35 | } 36 | 37 | public Integer getUserId() { 38 | return userId; 39 | } 40 | 41 | public void setUserId(Integer userId) { 42 | this.userId = userId; 43 | } 44 | 45 | public Integer getCinId() { 46 | return cinId; 47 | } 48 | 49 | public void setCinId(Integer cinId) { 50 | this.cinId = cinId; 51 | } 52 | 53 | public Integer getCforId() { 54 | return cforId; 55 | } 56 | 57 | public void setCforId(Integer cforId) { 58 | this.cforId = cforId; 59 | } 60 | 61 | public Date getTime() { 62 | return time; 63 | } 64 | 65 | public void setTime(Date time) { 66 | this.time = time; 67 | } 68 | 69 | public String getContent() { 70 | return content; 71 | } 72 | 73 | public void setContent(String content) { 74 | this.content = content; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/CommentUser.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | /** 4 | * 评论包含用户信息 5 | */ 6 | public class CommentUser extends Comment { 7 | 8 | private String username; 9 | 10 | private String userAvatar; 11 | 12 | private int cforUserId; 13 | 14 | private String cforUsername; 15 | 16 | public String getUsername() { 17 | return username; 18 | } 19 | 20 | public void setUsername(String username) { 21 | this.username = username; 22 | } 23 | 24 | public String getUserAvatar() { 25 | return userAvatar; 26 | } 27 | 28 | public void setUserAvatar(String userAvatar) { 29 | this.userAvatar = userAvatar; 30 | } 31 | 32 | public int getCforUserId() { 33 | return cforUserId; 34 | } 35 | 36 | public void setCforUserId(int cforUserId) { 37 | this.cforUserId = cforUserId; 38 | } 39 | 40 | public String getCforUsername() { 41 | return cforUsername; 42 | } 43 | 44 | public void setCforUsername(String cforUsername) { 45 | this.cforUsername = cforUsername; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/Community.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | public class Community { 4 | 5 | private Integer id; 6 | 7 | private String name; 8 | 9 | private String introduction; 10 | 11 | private String logo; 12 | 13 | public Integer getId() { 14 | return id; 15 | } 16 | 17 | public void setId(Integer id) { 18 | this.id = id; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public String getIntroduction() { 30 | return introduction; 31 | } 32 | 33 | public void setIntroduction(String introduction) { 34 | this.introduction = introduction; 35 | } 36 | 37 | public String getLogo() { 38 | return logo; 39 | } 40 | 41 | public void setLogo(String logo) { 42 | this.logo = logo; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/Invitation.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | import java.util.Date; 4 | 5 | public class Invitation { 6 | 7 | private Integer id; 8 | 9 | private Integer communityId; 10 | 11 | private Integer userId; 12 | 13 | private String title; 14 | 15 | private Date time; 16 | 17 | private String content; 18 | 19 | public Integer getId() { 20 | return id; 21 | } 22 | 23 | public void setId(Integer id) { 24 | this.id = id; 25 | } 26 | 27 | public Integer getCommunityId() { 28 | return communityId; 29 | } 30 | 31 | public void setCommunityId(Integer communityId) { 32 | this.communityId = communityId; 33 | } 34 | 35 | public Integer getUserId() { 36 | return userId; 37 | } 38 | 39 | public void setUserId(Integer userId) { 40 | this.userId = userId; 41 | } 42 | 43 | public String getTitle() { 44 | return title; 45 | } 46 | 47 | public void setTitle(String title) { 48 | this.title = title; 49 | } 50 | 51 | public Date getTime() { 52 | return time; 53 | } 54 | 55 | public void setTime(Date time) { 56 | this.time = time; 57 | } 58 | 59 | public String getContent() { 60 | return content; 61 | } 62 | 63 | public void setContent(String content) { 64 | this.content = content; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/InvitationUser.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | /** 4 | * 帖子包含用户信息 5 | */ 6 | public class InvitationUser extends Invitation { 7 | 8 | private String username; 9 | 10 | private String userAvatar; 11 | 12 | public String getUsername() { 13 | return username; 14 | } 15 | 16 | public void setUsername(String username) { 17 | this.username = username; 18 | } 19 | 20 | public String getUserAvatar() { 21 | return userAvatar; 22 | } 23 | 24 | public void setUserAvatar(String userAvatar) { 25 | this.userAvatar = userAvatar; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/InvitationUserCommunity.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | public class InvitationUserCommunity extends InvitationUser { 4 | 5 | private Community community; 6 | 7 | public Community getCommunity() { 8 | return community; 9 | } 10 | 11 | public void setCommunity(Community community) { 12 | this.community = community; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/bean/User.java: -------------------------------------------------------------------------------- 1 | package com.jsj.bean; 2 | 3 | import java.util.Date; 4 | 5 | public class User { 6 | 7 | private Integer id; 8 | 9 | private String username; 10 | 11 | private String password; 12 | 13 | private Date birthday; 14 | 15 | private String email; 16 | 17 | private String telNumber; 18 | 19 | private String photoUrl; 20 | 21 | private String avatar; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public String getUsername() { 32 | return username; 33 | } 34 | 35 | public void setUsername(String username) { 36 | this.username = username; 37 | } 38 | 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | public void setPassword(String password) { 44 | this.password = password; 45 | } 46 | 47 | public Date getBirthday() { 48 | return birthday; 49 | } 50 | 51 | public void setBirthday(Date birthday) { 52 | this.birthday = birthday; 53 | } 54 | 55 | public String getEmail() { 56 | return email; 57 | } 58 | 59 | public void setEmail(String email) { 60 | this.email = email; 61 | } 62 | 63 | public String getTelNumber() { 64 | return telNumber; 65 | } 66 | 67 | public void setTelNumber(String telNumber) { 68 | this.telNumber = telNumber; 69 | } 70 | 71 | public String getPhotoUrl() { 72 | return photoUrl; 73 | } 74 | 75 | public void setPhotoUrl(String photoUrl) { 76 | this.photoUrl = photoUrl; 77 | } 78 | 79 | public String getAvatar() { 80 | return avatar; 81 | } 82 | 83 | public void setAvatar(String avatar) { 84 | this.avatar = avatar; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/controller/CommentController.java: -------------------------------------------------------------------------------- 1 | package com.jsj.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.jsj.bean.Comment; 5 | import com.jsj.service.CommentService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | 14 | @Controller 15 | public class CommentController { 16 | 17 | @Autowired 18 | private CommentService commentService; 19 | 20 | /** 21 | * 评论区 22 | */ 23 | @RequestMapping(method = RequestMethod.POST, value = "/getComments") 24 | public String getCommentUsers(Model model, int cinId, 25 | @RequestParam(required = false,defaultValue = "1") int pageIndex, 26 | @RequestParam(required = false,defaultValue = "5") int pageSize){ 27 | model.addAttribute("comments",commentService.getCommentUserByCinId(cinId,pageIndex,pageSize)); 28 | model.addAttribute("cinId",cinId); 29 | return "comment"; 30 | } 31 | 32 | @RequestMapping(method = RequestMethod.POST,value = "/publishComment") 33 | @ResponseBody 34 | public String publishFirstComment(int invitationUserId,Comment comment){ 35 | return JSON.toJSONString(commentService.publishComment(invitationUserId,comment)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/controller/CommunityController.java: -------------------------------------------------------------------------------- 1 | package com.jsj.controller; 2 | 3 | import com.jsj.bean.Community; 4 | import com.jsj.service.CommunityService; 5 | import com.jsj.service.InvitationService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RequestMethod; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | 14 | @Controller 15 | public class CommunityController { 16 | 17 | @Autowired 18 | private CommunityService communityService; 19 | 20 | @Autowired 21 | private InvitationService invitationService; 22 | 23 | @RequestMapping(method = RequestMethod.GET,value ="/") 24 | public String index(Model model){ 25 | model.addAttribute("topCommunity", communityService.getTopCommunity()); 26 | model.addAttribute("topInvitation", invitationService.getTopInvitation()); 27 | return "index"; 28 | } 29 | 30 | @RequestMapping(method = RequestMethod.GET,value = "/community/{id}") 31 | public String toCommunity(Model model,@PathVariable("id")Integer communityId, 32 | @RequestParam(required = false,defaultValue = "1") int pageIndex, 33 | @RequestParam(required = false,defaultValue = "10") int pageSize){ 34 | Community community = communityService.getCommunityById(communityId); 35 | if (community == null){ 36 | return "error/404"; 37 | }else { 38 | model.addAttribute("invitationPage",invitationService.getInvitationPage(communityId,pageIndex, pageSize)); 39 | model.addAttribute("community", community); 40 | return "community"; 41 | } 42 | } 43 | 44 | /** 45 | * 搜索社区 46 | */ 47 | @RequestMapping(method = RequestMethod.GET,value = "/search") 48 | public String searchCommunity(Model model,String name){ 49 | model.addAttribute("communities", communityService.getCommunities(name)); 50 | return "search"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/controller/InvitationController.java: -------------------------------------------------------------------------------- 1 | package com.jsj.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.jsj.bean.Invitation; 5 | import com.jsj.bean.InvitationUser; 6 | import com.jsj.service.CommentService; 7 | import com.jsj.service.CommunityService; 8 | import com.jsj.service.InvitationService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.ui.Model; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | @Controller 15 | public class InvitationController { 16 | 17 | @Autowired 18 | private InvitationService invitationService; 19 | 20 | @Autowired 21 | private CommunityService communityService; 22 | 23 | @Autowired 24 | private CommentService commentService; 25 | 26 | @RequestMapping(method = RequestMethod.GET,value = "/invitation/{id}") 27 | public String toInvitation(Model model, @PathVariable("id")int invitationId, 28 | @RequestParam(required = false,defaultValue = "1") Integer pageIndex, 29 | @RequestParam(required = false,defaultValue = "10") Integer pageSize){ 30 | InvitationUser invitationUser = invitationService.getInvitationUserById(invitationId); 31 | if (invitationUser == null){ 32 | return "error/404"; 33 | }else { 34 | model.addAttribute("community",communityService.getCommunityById(invitationUser.getCommunityId())); 35 | model.addAttribute("invitation",invitationUser); 36 | model.addAttribute("comments", commentService.getCommentUser(invitationId,pageIndex,pageSize)); 37 | return "invitation"; 38 | } 39 | } 40 | 41 | @RequestMapping(method = RequestMethod.POST, value = "/publishInvitation") 42 | @ResponseBody 43 | public String string(Invitation invitation){ 44 | return JSON.toJSONString(invitationService.publishInvitation(invitation)); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.jsj.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.github.pagehelper.PageInfo; 5 | import com.jsj.bean.User; 6 | import com.jsj.service.UserService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.servlet.http.Cookie; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @Controller 20 | public class UserController { 21 | 22 | @Autowired 23 | private UserService userService; 24 | 25 | // 默认头像 26 | private final String defaultAvatar = "data:image/png;base64,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"; 27 | 28 | /** 29 | * 跳转到登录页面 30 | */ 31 | @RequestMapping(method = RequestMethod.GET,value = "/login") 32 | public String toLogin(HttpServletRequest request, Model model){ 33 | Cookie [] cookies = request.getCookies(); 34 | for (Cookie cookie : cookies) { 35 | if (cookie.getName().equals("rememberUsername")){ 36 | model.addAttribute(cookie.getName(), cookie.getValue()); 37 | } 38 | if (cookie.getName().equals("rememberPassword")){ 39 | model.addAttribute(cookie.getName(), cookie.getValue()); 40 | } 41 | } 42 | return "login"; 43 | } 44 | 45 | /** 46 | * 跳转到用户注册页面 47 | */ 48 | @RequestMapping(method = RequestMethod.GET,value = "/register") 49 | public String toRegister(){ 50 | return "register"; 51 | } 52 | 53 | /** 54 | * 登录 55 | */ 56 | @RequestMapping(method = RequestMethod.POST,value = "/login.do") 57 | @ResponseBody 58 | public String login(String username, String password, String remember, 59 | HttpServletRequest request,HttpServletResponse response) { 60 | Map map = userService.login(username, password); 61 | if ((boolean)map.get("success")){ 62 | // 保存cookie 63 | if (remember!=null&&remember.equals("on")){ 64 | Cookie usernameCookie = new Cookie("rememberUsername",username); 65 | Cookie passwordCookie = new Cookie("rememberPassword", password); 66 | response.addCookie(usernameCookie); 67 | response.addCookie(passwordCookie); 68 | } 69 | request.getSession().setAttribute("userStatus", true); 70 | request.getSession().setAttribute("username", map.get("username")); 71 | request.getSession().setAttribute("userId", map.get("userId")); 72 | request.getSession().setAttribute("noticeCount",map.get("noticeCount")); 73 | } 74 | return JSON.toJSONString(map); 75 | } 76 | 77 | /** 78 | * 注册 79 | */ 80 | @RequestMapping(method = RequestMethod.POST, value = "/register.do") 81 | @ResponseBody 82 | public String register(User user){ 83 | user.setAvatar(this.defaultAvatar); 84 | return JSON.toJSONString(userService.register(user)); 85 | } 86 | 87 | /** 88 | * 注销 89 | */ 90 | @RequestMapping(method = RequestMethod.GET, value ="logout") 91 | public String logout(HttpServletRequest request) { 92 | request.getSession().removeAttribute("userStatus"); 93 | request.getSession().removeAttribute("username"); 94 | request.getSession().removeAttribute("userId"); 95 | return "redirect:/"; 96 | } 97 | 98 | /** 99 | * 默认用户中心 100 | */ 101 | @GetMapping("/user/{id}") 102 | public String userIndex(Model model, @PathVariable int id){ 103 | model.addAttribute("userMap",userService.userIndex(id)); 104 | model.addAttribute("dynamicActive","active"); 105 | return "/user/index"; 106 | } 107 | 108 | /** 109 | * 通知中心 110 | */ 111 | @GetMapping("/user/notices/{id}") 112 | public String notice(Model model, HttpServletRequest request, @PathVariable int id){ 113 | model.addAttribute("userMap",userService.userIndex(id)); 114 | model.addAttribute("noticeActive","active"); 115 | // 修改通知状态 116 | if (userService.removeNotice(id)>0){ 117 | request.getSession().removeAttribute("noticeCount"); 118 | } 119 | return "/user/index"; 120 | } 121 | 122 | /** 123 | * 修改密码,退出登录状态 124 | */ 125 | @PostMapping("/user/update") 126 | @ResponseBody 127 | public String update(User user,HttpServletRequest request){ 128 | Map result = userService.update(user); 129 | request.getSession().removeAttribute("userStatus"); 130 | request.getSession().removeAttribute("username"); 131 | request.getSession().removeAttribute("userId"); 132 | return JSON.toJSONString(result); 133 | } 134 | 135 | /** 136 | * 请求个人动态 137 | */ 138 | @GetMapping("/user/dynamics/{id}/pageIndex/{pageIndex}/pageSize/{pageSize}") 139 | @ResponseBody 140 | public PageInfo> dynamics(@PathVariable int id, @PathVariable int pageIndex, @PathVariable int pageSize){ 141 | return userService.dynamics(id,pageIndex,pageSize); 142 | } 143 | 144 | /**s 145 | * 请求用户发帖 146 | */ 147 | @GetMapping("/user/invitations/{id}/pageIndex/{pageIndex}/pageSize/{pageSize}") 148 | @ResponseBody 149 | public PageInfo> invitations(@PathVariable int id, @PathVariable int pageIndex, @PathVariable int pageSize){ 150 | return userService.invitations(id, pageIndex, pageSize); 151 | } 152 | 153 | /** 154 | * 请求用户通知 155 | */ 156 | @GetMapping("/user/notices/{id}/pageIndex/{pageIndex}/pageSize/{pageSize}") 157 | @ResponseBody 158 | public PageInfo> notices(@PathVariable int id, @PathVariable int pageIndex, @PathVariable int pageSize){ 159 | return userService.notices(id, pageIndex, pageSize); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/converter/DateConverter.java: -------------------------------------------------------------------------------- 1 | package com.jsj.converter; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Date; 6 | 7 | import org.springframework.core.convert.converter.Converter; 8 | 9 | /** 10 | * String->Date 日期转换器 11 | */ 12 | public class DateConverter implements Converter{ 13 | 14 | //日期格式 15 | private String pattern; 16 | 17 | public void setPattern(String pattern) { 18 | this.pattern = pattern; 19 | } 20 | 21 | public Date convert(String source) { 22 | SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); 23 | try { 24 | return dateFormat.parse(source); 25 | } catch (ParseException e) { 26 | e.printStackTrace(); 27 | } 28 | return null; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/BaseMapper.java: -------------------------------------------------------------------------------- 1 | package com.jsj.mapper; 2 | 3 | public interface BaseMapper { 4 | 5 | default T getById(Integer id){ 6 | return null; 7 | } 8 | 9 | default int insert(T entity){ 10 | return -1; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/CommentMapper.java: -------------------------------------------------------------------------------- 1 | package com.jsj.mapper; 2 | 3 | import com.jsj.bean.Comment; 4 | import com.jsj.bean.CommentUser; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface CommentMapper extends BaseMapper { 10 | 11 | List getCommentsByInvitationId(int invitationId); 12 | 13 | List getCommentByCinId(int cinId); 14 | 15 | int insert(Comment comment); 16 | 17 | int notice(@Param("recipientId") int recipientId, @Param("commentId") int commentId); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/CommentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | SELECT 26 | comment.*, 27 | user.`username`, 28 | user.`avatar` 29 | FROM 30 | comment 31 | INNER JOIN user 32 | ON user.`id` = comment.`user_id` 33 | AND invitation_id = #{invitationId} 34 | AND cin_id IS NULL 35 | 36 | 37 | 38 | 39 | SELECT 40 | c1.*, 41 | cu.username AS username, 42 | fu.id AS cforUserId, 43 | fu.username AS cforUsername 44 | FROM 45 | COMMENT c1 46 | INNER JOIN `user` cu ON cu.id = c1.user_id 47 | INNER JOIN `user` fu ON fu.id = (SELECT c2.user_id FROM `comment` c2 WHERE c2.id = c1.cfor_id) 48 | AND c1.`cin_id` = #{cin_id} 49 | 50 | 51 | 52 | INSERT INTO COMMENT ( 53 | invitation_id, 54 | user_id, 55 | 56 | cin_id, 57 | 58 | 59 | cfor_id, 60 | 61 | time, 62 | content 63 | ) 64 | VALUES( 65 | #{invitationId}, 66 | #{userId}, 67 | 68 | #{cinId}, 69 | 70 | 71 | #{cforId}, 72 | 73 | #{time}, 74 | #{content} 75 | ) 76 | 77 | 78 | 79 | INSERT INTO notice(recipient_id,comment_id) 80 | VALUES(#{recipientId},#{commentId}) 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/CommunityMapper.java: -------------------------------------------------------------------------------- 1 | package com.jsj.mapper; 2 | 3 | import com.jsj.bean.Community; 4 | 5 | import java.util.List; 6 | 7 | public interface CommunityMapper extends BaseMapper { 8 | 9 | List getTopCommunity(); 10 | 11 | Community getById(Integer id); 12 | 13 | List getCommunityLikeName(String name); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/CommunityMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | SELECT 10 | community.*, 11 | COUNT(invitation.`community_id`) 12 | FROM 13 | community 14 | INNER JOIN invitation 15 | ON community.`id` = invitation.`community_id` 16 | -- AND date_sub(curdate(), interval 7 day) <= date(invitation.time) 17 | GROUP BY invitation.`community_id` 18 | ORDER BY COUNT(invitation.`community_id`) DESC 19 | LIMIT 3 20 | 21 | 22 | 23 | SELECT * FROM community 24 | WHERE id = #{id} 25 | 26 | 27 | 28 | SELECT * FROM community 29 | WHERE NAME LIKE '%${value}%' 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/InvitationMapper.java: -------------------------------------------------------------------------------- 1 | package com.jsj.mapper; 2 | 3 | import com.jsj.bean.InvitationUser; 4 | import com.jsj.bean.InvitationUserCommunity; 5 | import com.jsj.bean.Invitation; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public interface InvitationMapper extends BaseMapper { 11 | 12 | List getTopInvitation(); 13 | 14 | InvitationUser getInvitationUserById(int invitationId); 15 | 16 | List getInvitationUsersByCommunityId(int communityId); 17 | 18 | int insert(Invitation invitation); 19 | 20 | Map getInvitationCommunity(int id); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/InvitationMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | SELECT 27 | invitation.*, 28 | community.`name`, 29 | COUNT(comment.`invitation_id`) 30 | FROM 31 | invitation, 32 | comment, 33 | community 34 | WHERE invitation.`id` = comment.`invitation_id` 35 | AND invitation.`community_id` = community.`id` 36 | -- AND date_sub(curdate(), interval 7 day) <= date(comment.time) 37 | GROUP BY comment.`invitation_id` 38 | ORDER BY COUNT(comment.`invitation_id`) DESC 39 | LIMIT 10 40 | 41 | 42 | 43 | SELECT 44 | invitation.*, 45 | user.`username`, 46 | user.`avatar` AS userAvatar 47 | FROM 48 | invitation 49 | INNER JOIN user 50 | ON user.`id` = invitation.`user_id` 51 | AND invitation.`id` = #{invitationId} 52 | 53 | 54 | 55 | SELECT 56 | invitation.*, 57 | user.`username` 58 | FROM 59 | invitation 60 | INNER JOIN user 61 | ON user.`id` = invitation.`user_id` 62 | AND invitation.`community_id` = #{communityId} 63 | ORDER BY TIME DESC 64 | 65 | 66 | 67 | INSERT INTO invitation(community_id,user_id,title,time,content) 68 | VALUES(#{communityId},#{userId},#{title},#{time},#{content}) 69 | 70 | 71 | 72 | SELECT 73 | invitation.title AS invitation, 74 | community.`name` AS community 75 | FROM 76 | invitation 77 | INNER JOIN community ON community.id = invitation.community_id 78 | AND invitation.id = #{id} 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.jsj.mapper; 2 | 3 | import com.jsj.bean.Community; 4 | import com.jsj.bean.User; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public interface UserMapper extends BaseMapper { 11 | 12 | User getUserByPassword(@Param("username") String username, @Param("password") String password); 13 | 14 | User getById(Integer id); 15 | 16 | User getUserByCommentId(Integer commentId); 17 | 18 | List communitiesByUserId(int userId); 19 | 20 | List> commentDynamicsByUserId(int userId); 21 | 22 | List> invitationsByUserId(int userId); 23 | 24 | int getNoticeCount(int userId); 25 | 26 | List> getNotices(int userId); 27 | 28 | int insert(User user); 29 | 30 | int update(User user); 31 | 32 | int removeNotice(int userId); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | SELECT * FROM user WHERE username = #{username} AND password = #{password} 9 | 10 | 11 | 12 | SELECT * FROM user WHERE id = #{id} 13 | 14 | 15 | 16 | SELECT 17 | user.`username` 18 | FROM 19 | COMMENT 20 | INNER JOIN USER 21 | ON comment.`user_id` = user.`id` 22 | AND comment.`id` = #{commentId} 23 | 24 | 25 | 26 | 27 | SELECT 28 | log.community_id AS id, 29 | community.`name` 30 | FROM 31 | `browse_log` AS log 32 | INNER JOIN community ON community.id = log.community_id 33 | WHERE 34 | log.user_id = #{userId} 35 | AND log.type = 0 36 | GROUP BY 37 | log.community_id 38 | ORDER BY 39 | COUNT( log.user_id ) DESC 40 | LIMIT 4 41 | 42 | 43 | 44 | SELECT 45 | community.`name` AS communityName, 46 | community.id AS communityId, 47 | invitation.title AS invitation, 48 | invitation.id AS invitationId, 49 | `comment`.content, 50 | `comment`.time 51 | FROM 52 | `comment` 53 | INNER JOIN invitation ON `comment`.invitation_id = invitation.id 54 | INNER JOIN community ON invitation.community_id = community.id 55 | WHERE 56 | `comment`.user_id = #{userId} 57 | ORDER BY `comment`.time DESC 58 | 59 | 60 | 61 | SELECT 62 | invitation.id AS invitationId, 63 | invitation.title AS invitationTitle, 64 | invitation.time, 65 | community.id AS communityId, 66 | community.`name` AS communityName 67 | FROM 68 | invitation 69 | INNER JOIN community ON community.id = invitation.community_id 70 | WHERE user_id = #{userId} 71 | ORDER BY invitation.time DESC 72 | 73 | 74 | 75 | SELECT 76 | COUNT(1) 77 | FROM 78 | notice 79 | INNER JOIN `comment` ON `comment`.id = notice.comment_id 80 | AND notice.`status` = 0 81 | AND notice.recipient_id <> `comment`.user_id 82 | AND notice.recipient_id = #{userId} 83 | 84 | 85 | 86 | SELECT 87 | `comment`.id,`comment`.user_id,`comment`.content,`comment`.time,`comment`.invitation_id 88 | FROM 89 | notice INNER JOIN`comment` 90 | ON `comment`.id = notice.comment_id 91 | AND notice.recipient_id <> `comment`.user_id 92 | AND notice.recipient_id = #{userId} 93 | 94 | 95 | 96 | INSERT INTO user(username,password,birthday,email,tel_number,avatar) 97 | VALUES(#{username},#{password},#{birthday},#{email},#{telNumber},#{avatar}) 98 | 99 | 100 | 101 | UPDATE user 102 | 103 | 104 | username = #{username}, 105 | 106 | 107 | password = #{password}, 108 | 109 | 110 | birthday = #{birthday}, 111 | 112 | 113 | email = #{email}, 114 | 115 | 116 | tel_number = #{telNumber}, 117 | 118 | 119 | avatar = #{avatar}, 120 | 121 | 122 | WHERE id = #{id} 123 | 124 | 125 | 126 | UPDATE notice 127 | 128 | `status` = 1 129 | 130 | WHERE 131 | recipient_id = #{userId} 132 | AND `status` = 0 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/CommentService.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.jsj.bean.Comment; 5 | import com.jsj.bean.CommentUser; 6 | 7 | import java.util.Map; 8 | 9 | public interface CommentService { 10 | 11 | PageInfo getCommentUserByCinId(int cinId, int pageIndex, int pageSize); 12 | 13 | PageInfo getCommentUser(int InvitationId, int pageIndex, int pageSize); 14 | 15 | Map publishComment(int invitationUserId,Comment comment); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/CommunityService.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service; 2 | 3 | import com.jsj.bean.Community; 4 | 5 | import java.util.List; 6 | 7 | public interface CommunityService { 8 | 9 | List getTopCommunity(); 10 | 11 | Community getCommunityById(int communityId); 12 | 13 | List getCommunities(String name); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/Impl/CommentServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service.Impl; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.jsj.bean.Comment; 6 | import com.jsj.bean.CommentUser; 7 | import com.jsj.mapper.CommentMapper; 8 | import com.jsj.service.CommentService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | import java.util.Date; 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | @Service 19 | public class CommentServiceImpl implements CommentService { 20 | 21 | @Autowired 22 | private CommentMapper commentMapper; 23 | 24 | @Override 25 | public PageInfo getCommentUserByCinId(int cinId, int pageIndex, int pageSize) { 26 | PageHelper.startPage(pageIndex,pageSize); 27 | List commentUsers = commentMapper.getCommentByCinId(cinId); 28 | return new PageInfo<>(commentUsers); 29 | } 30 | 31 | @Override 32 | public PageInfo getCommentUser(int invitationId,int pageIndex,int pageSize) { 33 | PageHelper.startPage(pageIndex,pageSize); 34 | List commentUsers = commentMapper.getCommentsByInvitationId(invitationId); 35 | return new PageInfo<>(commentUsers); 36 | } 37 | 38 | @Override 39 | @Transactional 40 | public Map publishComment(int invitationUserId,Comment comment) { 41 | comment.setTime(new Date()); 42 | Map map = new HashMap<>(); 43 | if (commentMapper.insert(comment)>0){ 44 | commentMapper.notice(invitationUserId,comment.getId()); 45 | map.put("success",true); 46 | map.put("message","评论成功"); 47 | }else { 48 | map.put("success",false); 49 | map.put("message","评论失败"); 50 | } 51 | return map; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/Impl/CommunityServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service.Impl; 2 | 3 | import com.jsj.bean.Community; 4 | import com.jsj.mapper.CommunityMapper; 5 | import com.jsj.service.CommunityService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class CommunityServiceImpl implements CommunityService { 13 | 14 | @Autowired 15 | private CommunityMapper communityMapper; 16 | 17 | @Override 18 | public List getTopCommunity() { 19 | return communityMapper.getTopCommunity(); 20 | } 21 | 22 | @Override 23 | public Community getCommunityById(int communityId) { 24 | return communityMapper.getById(communityId); 25 | } 26 | 27 | @Override 28 | public List getCommunities(String name) { 29 | return communityMapper.getCommunityLikeName(name); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/Impl/InvitationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service.Impl; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.jsj.bean.Invitation; 6 | import com.jsj.bean.InvitationUser; 7 | import com.jsj.bean.InvitationUserCommunity; 8 | import com.jsj.mapper.InvitationMapper; 9 | import com.jsj.service.InvitationService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import java.util.Date; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @Service 20 | public class InvitationServiceImpl implements InvitationService { 21 | 22 | @Autowired 23 | private InvitationMapper invitationMapper; 24 | 25 | @Override 26 | public List getTopInvitation() { 27 | return invitationMapper.getTopInvitation(); 28 | } 29 | 30 | @Override 31 | public InvitationUser getInvitationUserById(int id) { 32 | return invitationMapper.getInvitationUserById(id); 33 | } 34 | 35 | @Override 36 | public PageInfo getInvitationPage(int communityId, int pageIndex, int pageSize) { 37 | PageHelper.startPage(pageIndex, pageSize); 38 | List invitationUsers = invitationMapper.getInvitationUsersByCommunityId(communityId); 39 | return new PageInfo <>(invitationUsers); 40 | } 41 | 42 | 43 | @Override 44 | @Transactional 45 | public Map publishInvitation(Invitation invitation) { 46 | invitation.setTime(new Date()); 47 | Map map = new HashMap<>(); 48 | if (invitationMapper.insert(invitation)>0){ 49 | map.put("success",true); 50 | map.put("message","发表成功"); 51 | }else { 52 | map.put("success",false); 53 | map.put("message","发表失败"); 54 | } 55 | return map; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/Impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service.Impl; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.jsj.bean.Community; 6 | import com.jsj.bean.User; 7 | import com.jsj.mapper.InvitationMapper; 8 | import com.jsj.mapper.UserMapper; 9 | import com.jsj.service.UserService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | @Service 19 | @Transactional 20 | public class UserServiceImpl implements UserService { 21 | 22 | @Autowired 23 | private UserMapper userMapper; 24 | @Autowired 25 | private InvitationMapper invitationMapper; 26 | 27 | @Override 28 | public Map login(String username, String password) { 29 | Map map = new HashMap<>(); 30 | User user = userMapper.getUserByPassword(username, password); 31 | if (user!=null){ 32 | map.put("success",true); 33 | map.put("username",user.getUsername()); 34 | map.put("userId", user.getId()); 35 | map.put("message","登录成功"); 36 | map.put("noticeCount",userMapper.getNoticeCount(user.getId())); 37 | }else { 38 | map.put("success",false); 39 | map.put("message","用户名或密码错误"); 40 | } 41 | return map; 42 | } 43 | 44 | @Override 45 | @Transactional 46 | public Map register(User user) { 47 | Map map = new HashMap<>(); 48 | if (userMapper.insert(user)>0){ 49 | map.put("success",true); 50 | map.put("message","注册成功"); 51 | }else { 52 | map.put("success",false); 53 | map.put("message","注册失败"); 54 | } 55 | return map; 56 | } 57 | 58 | @Override 59 | @Transactional 60 | public Map update(User user) { 61 | Map map = new HashMap<>(); 62 | if (userMapper.update(user)>0){ 63 | map.put("success",true); 64 | map.put("message","修改成功"); 65 | }else { 66 | map.put("success",false); 67 | map.put("message","修改失败"); 68 | } 69 | return map; 70 | } 71 | 72 | @Override 73 | public Map userIndex(int userId) { 74 | Map userMap = new HashMap<>(); 75 | User user = userMapper.getById(userId); 76 | List communities = userMapper.communitiesByUserId(userId); 77 | userMap.put("communities",communities); 78 | userMap.put("user",user); 79 | return userMap; 80 | } 81 | 82 | @Override 83 | public PageInfo> dynamics(int userId, int pageIndex, int pageSize) { 84 | PageHelper.startPage(pageIndex, pageSize); 85 | List> dynamics = userMapper.commentDynamicsByUserId(userId); 86 | return new PageInfo<>(dynamics); 87 | } 88 | 89 | @Override 90 | public PageInfo> invitations(int userId, int pageIndex, int pageSize) { 91 | PageHelper.startPage(pageIndex,pageSize); 92 | List> invitations = userMapper.invitationsByUserId(userId); 93 | return new PageInfo<>(invitations); 94 | } 95 | 96 | @Override 97 | public PageInfo> notices(int userId, int pageIndex, int pageSize) { 98 | PageHelper.startPage(pageIndex,pageSize); 99 | List> notices = userMapper.getNotices(userId); 100 | for (Map notice:notices) { 101 | notice.put("username",userMapper.getById((Integer) notice.get("user_id")).getUsername()); 102 | Map map = invitationMapper.getInvitationCommunity((Integer) notice.get("invitation_id")); 103 | notice.put("invitation",map.get("invitation")); 104 | notice.put("community",map.get("community")); 105 | } 106 | return new PageInfo<>(notices); 107 | } 108 | 109 | @Override 110 | @Transactional 111 | public int removeNotice(int userId) { 112 | return userMapper.removeNotice(userId); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/InvitationService.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.jsj.bean.Invitation; 5 | import com.jsj.bean.InvitationUser; 6 | import com.jsj.bean.InvitationUserCommunity; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public interface InvitationService { 12 | 13 | List getTopInvitation(); 14 | 15 | InvitationUser getInvitationUserById(int id); 16 | 17 | PageInfo getInvitationPage(int communityId,int pageIndex,int pageSize); 18 | 19 | Map publishInvitation(Invitation invitation); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/jsj/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.jsj.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.jsj.bean.User; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public interface UserService { 10 | 11 | Map login(String username, String password); 12 | 13 | Map register(User user); 14 | 15 | Map update(User user); 16 | 17 | Map userIndex(int userId); 18 | 19 | PageInfo> dynamics(int userId, int pageIndex, int pageSize); 20 | 21 | PageInfo> invitations(int userId, int pageIndex, int pageSize); 22 | 23 | PageInfo> notices(int userId, int pageIndex, int pageSize); 24 | 25 | int removeNotice(int userId); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/SpringMvc.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | text/html;charset=UTF-8 22 | text/plain;charset=UTF-8 23 | application/json;charset=UTF-8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/main/resources/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driver=com.mysql.cj.jdbc.Driver 2 | mysql.url=jdbc:mysql://localhost:3306/ssm_community?characterEncoding=UTF-8&serverTimezone=UTC 3 | mysql.username=root 4 | mysql.password=root 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # MyBatis logging configuration... 4 | log4j.logger.org.mybatis.example.BlogMapper=TRACE 5 | # Console output... 6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n -------------------------------------------------------------------------------- /src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | reasonable=true 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/comment.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | 5 | 6 | 7 | 8 | 9 | ${comment.username}: 10 | 11 | 回复${comment.cforUsername} : 12 | 13 | ${comment.content} 14 | 15 | 16 | 17 | 18 | 回复 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | « 32 | Previous 33 | 34 | 35 | 36 | 37 | 38 | 39 | « 40 | Previous 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ${index} 50 | 51 | 52 | ${index} 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | » 62 | Next 63 | 64 | 65 | 66 | 67 | 68 | 69 | » 70 | Next 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/community.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | 5 | 6 | 7 | 8 | ${community.name}社区 9 | 10 | 11 | 12 | 13 | 14 | <%@include file="header.jsp"%> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ${community.name}社区 23 | 24 | 25 | 26 | 暂无简介 27 | ${community.introduction} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ${invitationUser.title} 40 | 41 | 42 | 43 | 44 | ${invitationUser.username} 45 | 46 | 47 | 48 | 49 | <%-- 分页条 --%> 50 | 51 | 52 | 53 | 54 | 55 | 56 | « 57 | Previous 58 | 59 | 60 | 61 | 62 | 63 | 64 | « 65 | Previous 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | ${index} 75 | 76 | 77 | ${index} 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | » 87 | Next 88 | 89 | 90 | 91 | 92 | 93 | 94 | » 95 | Next 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 发表新帖 104 | 105 | 106 | 107 | 108 | 发表 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/error/404.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 你要找的页面不存在 6 | 7 | 8 | 404 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/error/405.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 您打开的方式不对 6 | 7 | 8 | 您打开的方式不对 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/error/500.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 系统异常 6 | 7 | 8 | 系统异常,请刷新页面重试 9 | 10 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/header.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8"%> 2 | 3 | 4 | 首页 5 | 6 | 7 | 8 | 9 | 10 | 11 | 搜索 12 | 13 | 14 | 15 | 16 | 17 | ${sessionScope.username} 20 | 21 | 个人中心 22 | 23 | 收到回复 24 | 25 | ${sessionScope.noticeCount} 26 | 27 | 28 | 注销 29 | 30 | 31 | 32 | 33 | 34 | 登录 35 | 36 | 37 | 注册 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | 5 | 6 | 7 | 8 | 论坛首页 9 | 10 | 11 | 12 | 13 | 14 | <%@include file="header.jsp"%> 15 | 16 | 17 | 18 | 19 | 热门社区 20 | 21 | 22 | 23 | 24 | 25 | ${community.name}社区 26 | 27 | 28 | 29 | 暂无简介 30 | 31 | 32 | ${community.introduction} 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 热门帖子 41 | 42 | 43 | 44 | 45 | 46 | ${invitation.community.name}社区 47 | 48 | 49 | 50 | ${invitation.title} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/invitation.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | 5 | 6 | 7 | 8 | ${invitation.title} 9 | 10 | 11 | 12 | 13 | 14 | 15 | <%@include file="header.jsp"%> 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ${community.name}社区 24 | 25 | 26 | 27 | 暂无简介 28 | ${community.introduction} 29 | 30 | 31 | 32 | 33 | 34 | ${invitation.title} 35 | 36 | 37 | <%--用户信息--%> 38 | 39 | 楼主 40 | 41 | 42 | 43 | 44 | ${invitation.username} 45 | 46 | 47 | 48 | ${invitation.content} 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ${index.index+1}楼 58 | 59 | 60 | 61 | 62 | ${commentUser.username} 63 | 64 | 65 | 66 | ${commentUser.content} 67 | 68 | 69 | 回复 71 | 72 | 73 | 74 | 75 | 76 | <%--楼中评论区--%> 77 | 78 | 79 | 80 | 81 | 82 | 83 | <%--分页条--%> 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | « 92 | Previous 93 | 94 | 95 | 96 | 97 | 98 | 99 | « 100 | Previous 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | ${index} 110 | 111 | 112 | ${index} 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | » 122 | Next 123 | 124 | 125 | 126 | 127 | 128 | 129 | » 130 | Next 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 发表评论 139 | 140 | 141 | 142 | 发表 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 269 | 270 | 271 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | 登录 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 登录 15 | 16 | 17 | 昵称: 18 | 19 | 20 | 21 | 密码: 22 | 23 | 24 | 25 | 26 | 记住我 27 | 28 | 29 | 登录 30 | 还没有账号,去注册 31 | 32 | 33 | 34 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/register.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | 3 | 4 | 5 | 6 | 注册 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 注册 15 | 16 | 17 | 18 | * 19 | 用户名/昵称: 20 | 21 | 22 | 23 | 24 | * 25 | 密码: 26 | 27 | 28 | 29 | 30 | * 31 | 再次输入密码: 32 | 33 | 34 | 35 | 36 | * 37 | 出生日期: 38 | 39 | 40 | 41 | 42 | * 43 | email: 44 | 45 | 46 | 47 | 48 | * 49 | 联系电话: 50 | 51 | 52 | 53 | 注册 54 | 已有账号,去登录 55 | 56 | 57 | 58 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/search.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | 6 | 7 | 社区首页 8 | 9 | 10 | 11 | 12 | 13 | <%@include file="header.jsp"%> 14 | 15 | 16 | 搜索结果:共${communities.size()}条 17 | 18 | 19 | 20 | 21 | 22 | ${community.name}社区 23 | 24 | 25 | 26 | 暂无简介 27 | 28 | 29 | ${community.introduction} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/view/user/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" %> 2 | <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 4 | 5 | 6 | 用户中心 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <%@include file="../header.jsp"%> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ${userMap.user.username} 24 | 25 | 生日: 26 | 27 | 28 | 29 | 30 | 31 | 修改密码 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 修改密码 42 | 43 | × 44 | 45 | 46 | 47 | 48 | 49 | 密码 50 | 51 | 52 | 53 | 再次输入密码 54 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | 65 | 66 | 67 | 常逛的社区 68 | 69 | 70 | 71 | ${community.name} 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 动态 82 | 83 | 84 | 帖子 85 | 86 | 87 | 88 | 通知 89 | 90 | 91 | 92 | 93 | 94 | 95 | <%-- 个人动态页面 --%> 96 | 97 | 98 | 99 | Loading... 100 | 101 | 102 | 103 | 104 | <%-- 帖子 --%> 105 | 106 | 107 | 108 | Loading... 109 | 110 | 111 | 112 | 113 | 114 | <%-- 通知 --%> 115 | 116 | 117 | 118 | Loading... 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 405 10 | /WEB-INF/view/error/405.jsp 11 | 12 | 13 | 14 | 404 15 | /WEB-INF/view/error/404.jsp 16 | 17 | 18 | 19 | 500 20 | /WEB-INF/view/error/500.jsp 21 | 22 | 23 | 24 | 25 | CharacterEncoding 26 | org.springframework.web.filter.CharacterEncodingFilter 27 | 28 | encoding 29 | UTF-8 30 | 31 | 32 | 33 | CharacterEncoding 34 | 35 | /* 36 | 37 | 38 | 39 | 40 | org.springframework.web.context.ContextLoaderListener 41 | 42 | 43 | 44 | contextConfigLocation 45 | classpath:spring.xml 46 | 47 | 48 | 49 | 50 | springMvc 51 | org.springframework.web.servlet.DispatcherServlet 52 | 53 | 54 | contextConfigLocation 55 | classpath:SpringMvc.xml 56 | 57 | 58 | 59 | 60 | springMvc 61 | / 62 | 63 | 64 | 65 | 66 | default 67 | *.js 68 | *.css 69 | /static/** 70 | 71 | 72 | -------------------------------------------------------------------------------- /src/main/webapp/static/bootstrap/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /src/main/webapp/static/bootstrap/css/bootstrap-reboot.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../scss/bootstrap-reboot.scss","../../scss/_reboot.scss","dist/css/bootstrap-reboot.css","../../scss/vendor/_rfs.scss","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"AAAA;;;;;;ACkBA,ECTA,QADA,SDaE,WAAA,WAGF,KACE,YAAA,WACA,YAAA,KACA,yBAAA,KACA,4BAAA,YAMF,QAAA,MAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,IAAA,QACE,QAAA,MAUF,KACE,OAAA,EACA,YAAA,aAAA,CAAA,kBAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,KAAA,CAAA,WAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,gBAAA,CAAA,iBAAA,CAAA,mBEgFI,UAAA,KF9EJ,YAAA,IACA,YAAA,IACA,MAAA,QACA,WAAA,KACA,iBAAA,KGlBF,sBH2BE,QAAA,YASF,GACE,WAAA,YACA,OAAA,EACA,SAAA,QAaF,GAAA,GAAA,GAAA,GAAA,GAAA,GACE,WAAA,EACA,cAAA,MAOF,EACE,WAAA,EACA,cAAA,KC1CF,0BDqDA,YAEE,gBAAA,UACA,wBAAA,UAAA,OAAA,gBAAA,UAAA,OACA,OAAA,KACA,cAAA,EACA,iCAAA,KAAA,yBAAA,KAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QC/CF,GDkDA,GCnDA,GDsDE,WAAA,EACA,cAAA,KAGF,MClDA,MACA,MAFA,MDuDE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAGF,ECnDA,ODqDE,YAAA,OAGF,MEpFI,UAAA,IF6FJ,ICxDA,ID0DE,SAAA,SE/FE,UAAA,IFiGF,YAAA,EACA,eAAA,SAGF,IAAM,OAAA,OACN,IAAM,IAAA,MAON,EACE,MAAA,QACA,gBAAA,KACA,iBAAA,YI5KA,QJ+KE,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KIxLA,oCAAA,oCJ2LE,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EC1DJ,KACA,IDkEA,ICjEA,KDqEE,YAAA,cAAA,CAAA,KAAA,CAAA,MAAA,CAAA,QAAA,CAAA,iBAAA,CAAA,aAAA,CAAA,UErJE,UAAA,IFyJJ,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAQF,OAEE,OAAA,EAAA,EAAA,KAQF,IACE,eAAA,OACA,aAAA,KAGF,IAGE,SAAA,OACA,eAAA,OAQF,MACE,gBAAA,SAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAGE,WAAA,QAQF,MAEE,QAAA,aACA,cAAA,MAMF,OAEE,cAAA,EAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBCrGF,ODwGA,MCtGA,SADA,OAEA,SD0GE,OAAA,EACA,YAAA,QEtPE,UAAA,QFwPF,YAAA,QAGF,OCxGA,MD0GE,SAAA,QAGF,OCxGA,OD0GE,eAAA,KAMF,OACE,UAAA,OCxGF,cACA,aACA,cD6GA,OAIE,mBAAA,OC5GF,6BACA,4BACA,6BD+GE,sBAKI,OAAA,QC/GN,gCACA,+BACA,gCDmHA,yBAIE,QAAA,EACA,aAAA,KClHF,qBDqHA,kBAEE,WAAA,WACA,QAAA,EAIF,iBCrHA,2BACA,kBAFA,iBD+HE,mBAAA,QAGF,SACE,SAAA,KAEA,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAKF,OACE,QAAA,MACA,MAAA,KACA,UAAA,KACA,QAAA,EACA,cAAA,MElSI,UAAA,OFoSJ,YAAA,QACA,MAAA,QACA,YAAA,OAGF,SACE,eAAA,SGpIF,yCFGA,yCDuIE,OAAA,KGrIF,cH6IE,eAAA,KACA,mBAAA,KGzIF,yCHiJE,mBAAA,KAQF,6BACE,KAAA,QACA,mBAAA,OAOF,OACE,QAAA,aAGF,QACE,QAAA,UACA,OAAA,QAGF,SACE,QAAA,KGtJF,SH4JE,QAAA","sourcesContent":["/*!\n * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -webkit-tap-highlight-color: rgba($black, 0); // 5\n}\n\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\n// TODO: remove in v5\n// stylelint-disable-next-line selector-list-comma-newline-after\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n @include font-size($font-size-base);\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, ``-`` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable-next-line selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on ``s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `` alignment by inheriting from the ``, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: $label-margin-bottom;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n // stylelint-disable-next-line property-blacklist\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// Remove the inheritance of word-wrap in Safari.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24990\nselect {\n word-wrap: normal;\n}\n\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\n[type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Opinionated: add \"hand\" cursor to non-disabled button elements.\n@if $enable-pointer-cursor-for-buttons {\n button,\n [type=\"button\"],\n [type=\"reset\"],\n [type=\"submit\"] {\n &:not(:disabled) {\n cursor: pointer;\n }\n }\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. ``s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n @include font-size(1.5rem);\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","/*!\n * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\narticle, aside, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg {\n overflow: hidden;\n vertical-align: middle;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 0.5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nselect {\n word-wrap: normal;\n}\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton:not(:disabled),\n[type=\"button\"]:not(:disabled),\n[type=\"reset\"]:not(:disabled),\n[type=\"submit\"]:not(:disabled) {\n cursor: pointer;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} -------------------------------------------------------------------------------- /src/main/webapp/static/css/header.css: -------------------------------------------------------------------------------- 1 | header a:hover{ 2 | color: white; 3 | } 4 | body{ 5 | padding-top: 56px; 6 | } 7 | @media (max-width: 992px) { 8 | .offcanvas-collapse { 9 | position: fixed; 10 | top: 56px; 11 | bottom: 0; 12 | left: 100%; 13 | width: 55%; 14 | padding-right: 1rem; 15 | padding-left: 1rem; 16 | overflow-y: auto; 17 | visibility: hidden; 18 | background-color: #343a40; 19 | transition: visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; 20 | transition: transform .3s ease-in-out, visibility .3s ease-in-out; 21 | transition: transform .3s ease-in-out, visibility .3s ease-in-out, -webkit-transform .3s ease-in-out; 22 | } 23 | .offcanvas-collapse.open { 24 | visibility: visible; 25 | -webkit-transform: translateX(-100%); 26 | transform: translateX(-100%); 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/webapp/static/css/invitation.css: -------------------------------------------------------------------------------- 1 | .userInfo{ 2 | overflow: initial; 3 | } 4 | /*PC*/ 5 | @media (min-width: 768px) { 6 | .userInfo{ 7 | width: 100px; 8 | flex-direction: column; 9 | margin-left: 1rem; 10 | padding-bottom: 1rem; 11 | padding-top: 1rem; 12 | } 13 | .userInfo span,small{ 14 | text-align: center; 15 | } 16 | .userInfo img{ 17 | width: 84px; 18 | height: 84px; 19 | margin: 10px auto; 20 | } 21 | .userInfo .username{ 22 | margin-bottom: 50px; 23 | } 24 | .comment_content{ 25 | min-height: 150px; 26 | } 27 | } 28 | /*Mobile*/ 29 | @media (max-width: 768px) { 30 | .userInfo{ 31 | background-color: white; 32 | flex-direction: row; 33 | } 34 | .userInfo span,small{ 35 | text-align: left; 36 | line-height: 36px; 37 | } 38 | .userInfo img{ 39 | width: 36px; 40 | height: 36px; 41 | margin: 0 5px; 42 | border-radius: 35%; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/webapp/static/css/login.css: -------------------------------------------------------------------------------- 1 | body{ 2 | padding-top: 50px; 3 | background-color: #f5f5f5; 4 | } 5 | form{ 6 | max-width: 330px; 7 | padding: 15px; 8 | margin: auto; 9 | } 10 | .form-group { 11 | position: relative; 12 | margin-bottom: 1rem; 13 | } -------------------------------------------------------------------------------- /src/main/webapp/static/css/style.css: -------------------------------------------------------------------------------- 1 | .bg-gray-dark{ 2 | background: #848eb5; 3 | } 4 | ul,li{ 5 | list-style: none; 6 | } 7 | a{ 8 | color: inherit; 9 | } 10 | a:hover{ 11 | text-decoration: none; 12 | } 13 | .time{ 14 | font-size: 12px; 15 | } 16 | #contentEidtor .w-e-toolbar{ 17 | overflow: auto; 18 | } -------------------------------------------------------------------------------- /src/main/webapp/static/css/userIndex.css: -------------------------------------------------------------------------------- 1 | /*PC*/ 2 | @media (min-width: 768px) { 3 | .avatar img{ 4 | margin: 0 1rem; 5 | width: 150px; 6 | height: 150px; 7 | position: relative; 8 | top: -60px; 9 | } 10 | .oftenBrowseCommunities{ 11 | margin: -55px 0 0 20px; 12 | } 13 | } 14 | /*Mobile*/ 15 | @media (max-width: 768px) { 16 | .avatar img{ 17 | margin: 5px; 18 | width: 60px; 19 | height: 60px; 20 | } 21 | .oftenBrowseCommunities h6{ 22 | font-size: 14px; 23 | } 24 | .main .nav-item{ 25 | text-align: center; 26 | flex: 1 1 auto!important; 27 | } 28 | } 29 | svg{ 30 | position: relative; 31 | top: 5px; 32 | } -------------------------------------------------------------------------------- /src/main/webapp/static/js/header.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | 'use strict' 3 | $('[data-toggle="offcanvas"]').on('click', function () { 4 | $('.offcanvas-collapse').toggleClass('open') 5 | }) 6 | }) 7 | -------------------------------------------------------------------------------- /src/main/webapp/static/js/userIndex.js: -------------------------------------------------------------------------------- 1 | function getScrollTop(){ 2 | let scrollTop 3 | let bodyScrollTop = 0 4 | let documentScrollTop = 0 5 | if(document.body){ 6 | bodyScrollTop = document.body.scrollTop 7 | } 8 | if(document.documentElement){ 9 | documentScrollTop = document.documentElement.scrollTop 10 | } 11 | scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop 12 | return scrollTop 13 | } 14 | function getScrollHeight(){ 15 | let scrollHeight 16 | let bodyScrollHeight = 0 17 | let documentScrollHeight = 0 18 | if(document.body){ 19 | bodyScrollHeight = document.body.scrollHeight 20 | } 21 | if(document.documentElement){ 22 | documentScrollHeight = document.documentElement.scrollHeight 23 | } 24 | scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight 25 | return scrollHeight 26 | } 27 | function getWindowHeight(){ 28 | let windowHeight 29 | if(document.compatMode === "CSS1Compat"){ 30 | windowHeight = document.documentElement.clientHeight 31 | }else{ 32 | windowHeight = document.body.clientHeight 33 | } 34 | return windowHeight 35 | } 36 | window.onscroll = function () { 37 | // 页面滚动到底部 38 | if(getScrollHeight() - (getScrollTop() + getWindowHeight()) < 1){ 39 | if (tabType === "dynamic"){ 40 | lazyLoadDynamics() 41 | }else if (tabType === "invitation"){ 42 | lazyLoadInvitations() 43 | }else if (tabType === "notice"){ 44 | lazyLoadNotices() 45 | } 46 | } 47 | } 48 | 49 | /** 50 | * tabContent解决方案: 51 | * 初始化方法 52 | * 用于:切换Tab、点击Tab、页面初始化 53 | * 逻辑:设置tab变量 -> 清空列表 -> 请求接口获取数据 —> 拼接html渲染 -> 判断隐藏加载图标 54 | * 懒加载方法 55 | * 页面滚动底部触发 —> 请求接口获取数据 —> 拼接html渲染 -> 设置isFull标识符(判断隐藏加载图标) 56 | */ 57 | 58 | // 全局标识符 59 | let tabType = "" 60 | let dynamicIsFull = false 61 | let invitationIsFull = false 62 | let noticeIsFull = false 63 | // 页码与单页显示数 64 | let dynamicPageIndex = 1 65 | let invitationPageIndex = 1 66 | let noticesPageIndex = 1 67 | let pageSize = 10 68 | 69 | // 初始化个人动态 70 | function dynamics() { 71 | tabType = "dynamic" 72 | // 清空列表 73 | dynamicPageIndex = 1 74 | $("#dynamics").empty() 75 | loadDynamics() 76 | dynamicIsFull = false 77 | } 78 | 79 | // 懒加载个人动态 80 | function lazyLoadDynamics() { 81 | if (!dynamicIsFull){ 82 | loadDynamics() 83 | } 84 | } 85 | 86 | // 初始化invitationContent 87 | function invitations() { 88 | tabType = "invitation" 89 | // 清空列表 90 | invitationPageIndex = 1 91 | $("#invitations").empty() 92 | loadInvitations() 93 | invitationIsFull = false 94 | } 95 | 96 | // 懒加载invitationContent 97 | function lazyLoadInvitations() { 98 | if (!invitationIsFull){ 99 | loadInvitations() 100 | } 101 | } 102 | 103 | // 初始化noticeContent 104 | function notices() { 105 | tabType = "notice" 106 | // 清空列表 107 | noticesPageIndex = 1 108 | $("#notices").empty() 109 | loadNotices() 110 | noticeIsFull = false 111 | } 112 | 113 | // 懒加载noticeContent 114 | function lazyLoadNotices() { 115 | if (!noticeIsFull){ 116 | loadNotices() 117 | } 118 | } 119 | 120 | // 时间格式处理 121 | function dateFormat(fmt, date) { 122 | let newDate = new Date(date) 123 | let ret; 124 | const opt = { 125 | "Y+": newDate.getFullYear().toString(), // 年 126 | "m+": (newDate.getMonth() + 1).toString(), // 月 127 | "d+": newDate.getDate().toString(), // 日 128 | "H+": newDate.getHours().toString(), // 时 129 | "M+": newDate.getMinutes().toString(), // 分 130 | "S+": newDate.getSeconds().toString() // 秒 131 | }; 132 | for (let k in opt) { 133 | ret = new RegExp("(" + k + ")").exec(fmt); 134 | if (ret) { 135 | fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) 136 | } 137 | } 138 | return fmt; 139 | } -------------------------------------------------------------------------------- /src/main/webapp/static/wangEditor/fonts/w-e-icon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeoJ340/ssm_community/afc716e715ac9f3899f5af3dca8c8768536ec7dd/src/main/webapp/static/wangEditor/fonts/w-e-icon.woff -------------------------------------------------------------------------------- /src/main/webapp/static/wangEditor/wangEditor.min.css: -------------------------------------------------------------------------------- 1 | .w-e-text-container .w-e-panel-container .w-e-panel-tab-content button:focus,.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input:focus,.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea:focus,.w-e-text:focus{outline:0}.w-e-menu-panel,.w-e-menu-panel *,.w-e-text-container,.w-e-text-container *,.w-e-toolbar,.w-e-toolbar *{padding:0;margin:0;box-sizing:border-box}.w-e-clear-fix:after{content:"";display:table;clear:both}.w-e-toolbar .w-e-droplist{position:absolute;left:0;top:0;background-color:#fff;border:1px solid #f1f1f1;border-right-color:#ccc;border-bottom-color:#ccc}.w-e-toolbar .w-e-droplist ul.w-e-block li.w-e-item:hover,.w-e-toolbar .w-e-droplist ul.w-e-list li.w-e-item:hover{background-color:#f1f1f1}.w-e-toolbar .w-e-droplist .w-e-dp-title{text-align:center;color:#999;line-height:2;border-bottom:1px solid #f1f1f1;font-size:13px}.w-e-toolbar .w-e-droplist ul.w-e-list{list-style:none;line-height:1}.w-e-toolbar .w-e-droplist ul.w-e-list li.w-e-item{color:#333;padding:5px 0}.w-e-toolbar .w-e-droplist ul.w-e-block{list-style:none;text-align:left;padding:5px}.w-e-toolbar .w-e-droplist ul.w-e-block li.w-e-item{display:inline-block;padding:3px 5px}@font-face{font-family:w-e-icon;src:url(data:application/x-font-woff;charset=utf-8;base64,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) format('truetype');font-weight:400;font-style:normal}[class*=" w-e-icon-"],[class^=w-e-icon-]{font-family:w-e-icon!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-e-icon-close:before{content:"\f00d"}.w-e-icon-upload2:before{content:"\e9c6"}.w-e-icon-trash-o:before{content:"\f014"}.w-e-icon-header:before{content:"\f1dc"}.w-e-icon-pencil2:before{content:"\e906"}.w-e-icon-paint-brush:before{content:"\f1fc"}.w-e-icon-image:before{content:"\e90d"}.w-e-icon-play:before{content:"\e912"}.w-e-icon-location:before{content:"\e947"}.w-e-icon-undo:before{content:"\e965"}.w-e-icon-redo:before{content:"\e966"}.w-e-icon-quotes-left:before{content:"\e977"}.w-e-icon-list-numbered:before{content:"\e9b9"}.w-e-icon-list2:before{content:"\e9bb"}.w-e-icon-link:before{content:"\e9cb"}.w-e-icon-happy:before{content:"\e9df"}.w-e-icon-bold:before{content:"\ea62"}.w-e-icon-underline:before{content:"\ea63"}.w-e-icon-italic:before{content:"\ea64"}.w-e-icon-strikethrough:before{content:"\ea65"}.w-e-icon-table2:before{content:"\ea71"}.w-e-icon-paragraph-left:before{content:"\ea77"}.w-e-icon-paragraph-center:before{content:"\ea78"}.w-e-icon-paragraph-right:before{content:"\ea79"}.w-e-icon-terminal:before{content:"\f120"}.w-e-icon-page-break:before{content:"\ea68"}.w-e-icon-cancel-circle:before{content:"\ea0d"}.w-e-icon-font:before{content:"\ea5c"}.w-e-icon-text-heigh:before{content:"\ea5f"}.w-e-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;padding:0 5px}.w-e-toolbar .w-e-menu{position:relative;text-align:center;padding:5px 10px;cursor:pointer}.w-e-toolbar .w-e-menu i{color:#999}.w-e-toolbar .w-e-menu:hover i{color:#333}.w-e-toolbar .w-e-active i,.w-e-toolbar .w-e-active:hover i{color:#1e88e5}.w-e-text-container .w-e-panel-container{position:absolute;top:0;left:50%;border:1px solid #ccc;border-top:0;box-shadow:1px 1px 2px #ccc;color:#333;background-color:#fff}.w-e-text-container .w-e-panel-container .w-e-panel-close{position:absolute;right:0;top:0;padding:5px;margin:2px 5px 0 0;cursor:pointer;color:#999}.w-e-text-container .w-e-panel-container .w-e-panel-close:hover{color:#333}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title{list-style:none;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:14px;margin:2px 10px 0;border-bottom:1px solid #f1f1f1}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title .w-e-item{padding:3px 5px;color:#999;cursor:pointer;margin:0 3px;position:relative;top:1px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-title .w-e-active{color:#333;border-bottom:1px solid #333;cursor:default;font-weight:700}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content{padding:10px 15px;font-size:16px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea{width:100%;border:1px solid #ccc;padding:5px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content textarea:focus{border-color:#1e88e5}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text]{border:none;border-bottom:1px solid #ccc;font-size:14px;height:20px;color:#333;text-align:left}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text].small{width:30px;text-align:center}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text].block{display:block;width:100%;margin:10px 0}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content input[type=text]:focus{border-bottom:2px solid #1e88e5}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button{font-size:14px;color:#1e88e5;border:none;padding:5px 10px;background-color:#fff;cursor:pointer;border-radius:3px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.left{float:left;margin-right:10px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.right{float:right;margin-left:10px}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.gray{color:#999}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button.red{color:#c24f4a}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container button:hover{background-color:#f1f1f1}.w-e-text-container .w-e-panel-container .w-e-panel-tab-content .w-e-button-container:after{content:"";display:table;clear:both}.w-e-text-container .w-e-panel-container .w-e-emoticon-container .w-e-item{cursor:pointer;font-size:18px;padding:0 3px;display:inline-block}.w-e-text-container .w-e-panel-container .w-e-up-img-container{text-align:center}.w-e-text-container .w-e-panel-container .w-e-up-img-container .w-e-up-btn{display:inline-block;color:#999;cursor:pointer;font-size:60px;line-height:1}.w-e-text-container .w-e-panel-container .w-e-up-img-container .w-e-up-btn:hover{color:#333}.w-e-text-container{position:relative}.w-e-text-container .w-e-progress{position:absolute;background-color:#1e88e5;bottom:0;left:0;height:1px}.w-e-text{padding:0 10px;overflow-y:scroll}.w-e-text h1,.w-e-text h2,.w-e-text h3,.w-e-text h4,.w-e-text h5,.w-e-text p,.w-e-text pre,.w-e-text table{margin:10px 0;line-height:1.5}.w-e-text ol,.w-e-text ul{margin:10px 0 10px 20px}.w-e-text blockquote{display:block;border-left:8px solid #d0e5f2;padding:5px 10px;margin:10px 0;line-height:1.4;font-size:100%;background-color:#f1f1f1}.w-e-text code{display:inline-block;background-color:#f1f1f1;border-radius:3px;padding:3px 5px;margin:0 3px}.w-e-text pre code{display:block}.w-e-text table{border-top:1px solid #ccc;border-left:1px solid #ccc}.w-e-text table td,.w-e-text table th{border-bottom:1px solid #ccc;border-right:1px solid #ccc;padding:3px 5px}.w-e-text table th{border-bottom:2px solid #ccc;text-align:center}.w-e-text img{cursor:pointer}.w-e-text img:hover{box-shadow:0 0 5px #333} -------------------------------------------------------------------------------- /ssm_community.iml: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------
24 | 25 | ${community.name}社区 26 | 27 | 28 | 29 | 暂无简介 30 | 31 | 32 | ${community.introduction} 33 | 34 | 35 |
21 | 22 | ${community.name}社区 23 | 24 | 25 | 26 | 暂无简介 27 | 28 | 29 | ${community.introduction} 30 | 31 | 32 |
`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Remove the bottom border in Firefox 39-.\n// 5. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-original-title] { // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 4\n text-decoration-skip-ink: none; // 5\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n\nsmall {\n @include font-size(80%); // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n @include font-size(75%);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-monospace;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg {\n // Workaround for the SVG overflow bug in IE10/11 is still required.\n // See https://github.com/twbs/bootstrap/issues/26878\n overflow: hidden;\n vertical-align: middle;\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $table-caption-color;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `