diff --git a/README.md b/README.md index 7e34f5f2..88866230 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@
+ [![star](https://gitee.com/veal98/Echo/badge/star.svg?theme=dark)](https://gitee.com/veal98/Echo/stargazers) [![fork](https://gitee.com/veal98/Echo/badge/fork.svg?theme=dark)](https://gitee.com/veal98/Echo/members) [![GitHub stars](https://img.shields.io/github/stars/Veal98/Echo?logo=github)](https://github.com/Veal98/Echo/stargazers) [![GitHub forks](https://img.shields.io/github/forks/Veal98/Echo?logo=github)](https://github.com/Veal98/Echo/network) -[![version](https://img.shields.io/badge/version-1.0-brightgreen)]() +[![version](https://img.shields.io/badge/version-2.0-brightgreen)]() 交流群 配套教程 @@ -22,7 +23,7 @@
-> 项目上线到服务器之后可能会出现各种各样的 BUG,比如 Elasticsearch 服务启动失败导致搜索模块不可用,但是在本地运行是完全没问题的,所以各位小伙伴可以放心下载部署。 +> 云服务器到期了,暂时不准备续费,未上手的小伙伴可以看下面的界面展示了解本项目,所有代码在我本机上都是正常运行的,各位可以参考配套教程自己拉下去部署,并欢迎加群讨论技术问题。 ## 📚 项目简介 @@ -33,22 +34,10 @@ Echo 是一套前后端不分离的开源社区系统,基于目前主流 Java - Gitee:[https://gitee.com/veal98/Echo](https://gitee.com/veal98/Echo)(Gitee 官方推荐项目) - Github:[https://github.com/Veal98/Echo](https://github.com/Veal98/Echo) -**在线体验**:项目已经部署到腾讯云服务器,各位小伙伴们可直接线上体验:[http://1.15.127.74/](http://1.15.127.74/)。已内置三种不同身份的用户: - -> **各位请不要修改这三种内置角色的密码**,默认注册的用户是普通用户,您修改了密码后其他小伙伴就没法体验管理员和版主角色了。若想要测试修改密码功能,可以自己重新注册个用户,注意填写真实邮箱,否则无法接收激活邮件并激活角色。感谢各位的配合 ~ -> -> 另外,为防止**恶意修改密码**行为,若遇上管理员和版主角色登录失败的情况,可以下方扫码关注公众号【飞天小牛肉】回复 `备用角色` 获取**备用登录用户名和密码**。 - -| | username | password | 特殊权限 | -| :------: | :------: | :------: | :----------------: | -| 管理员 | admin | admin | 数据统计、删除帖子 | -| 版主 | master | master | 置顶帖子、加精帖子 | -| 普通用户 | user | user | | - **文档地址**:文档通过 Docsify + Github/Gitee Pages 生成 -- Github Pages:[https://veal98.github.io/Echo](https://veal98.github.io/Echo) - Gitee Pages:[https://veal98.gitee.io/echo](https://veal98.gitee.io/echo) +- Github Pages:[https://veal98.github.io/Echo](https://veal98.github.io/Echo) ## 📖 配套教程 @@ -77,7 +66,7 @@ Echo 是一套前后端不分离的开源社区系统,基于目前主流 Java - [Echo 的发帖操作是怎么做的](https://mp.weixin.qq.com/s/OsCd3Pcl6iq-0znh7PL3lg) - [Echo 的帖子列表与分页是怎么做的](https://mp.weixin.qq.com/s/R5CtsXaS9hIOOePxQZcZhg) - [Echo 的评论是如何显示的](https://mp.weixin.qq.com/s/0avudnypPu3EewzoU3sEwA) -- Echo 的评论发表与回复是怎么做的 +- [Echo 的发布评论是怎么做的](https://mp.weixin.qq.com/s/S5bNpzuZFga2u15ik2t2iQ) - Echo 的私信列表与详情页是怎么做的 - Echo 的发送私信是怎么做的 - Echo 的点赞模块是怎么做的 diff --git a/docs/README.md b/docs/README.md index fcec1197..dccacbf0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,22 +7,10 @@ Echo 是一套前后端不分离的开源社区系统,基于目前主流 Java - Gitee:[https://gitee.com/veal98/Echo](https://gitee.com/veal98/Echo)(Gitee 官方推荐项目) - Github:[https://github.com/Veal98/Echo](https://github.com/Veal98/Echo) -**在线体验**:项目已经部署到腾讯云服务器,各位小伙伴们可直接线上体验:[http://1.15.127.74/](http://1.15.127.74/)。已内置三种不同身份的用户: - -> **各位请不要修改这三种内置角色的密码**,默认注册的用户是普通用户,您修改了密码后其他小伙伴就没法体验管理员和版主角色了。若想要测试修改密码功能,可以自己重新注册个用户,注意填写真实邮箱,否则无法接收激活邮件并激活角色。感谢各位的配合 ~ -> -> 另外,为防止**恶意修改密码**行为,若遇上管理员和版主角色登录失败的情况,可以下方扫码关注公众号【飞天小牛肉】回复 `备用角色` 获取**备用登录用户名和密码**。 - -| | username | password | 特殊权限 | -| :------: | :------: | :------: | :----------------: | -| 管理员 | admin | admin | 数据统计、删除帖子 | -| 版主 | master | master | 置顶帖子、加精帖子 | -| 普通用户 | user | user | | - **文档地址**:文档通过 Docsify + Github/Gitee Pages 生成 -- Github Pages:[https://veal98.github.io/Echo](https://veal98.github.io/Echo) - Gitee Pages:[https://veal98.gitee.io/echo](https://veal98.gitee.io/echo) +- Github Pages:[https://veal98.github.io/Echo](https://veal98.github.io/Echo) ## 📖 配套教程 @@ -51,7 +39,7 @@ Echo 是一套前后端不分离的开源社区系统,基于目前主流 Java - [Echo 的发帖操作是怎么做的](https://mp.weixin.qq.com/s/OsCd3Pcl6iq-0znh7PL3lg) - [Echo 的帖子列表与分页是怎么做的](https://mp.weixin.qq.com/s/R5CtsXaS9hIOOePxQZcZhg) - [Echo 的评论是如何显示的](https://mp.weixin.qq.com/s/0avudnypPu3EewzoU3sEwA) -- Echo 的评论发表与回复是怎么做的 +- [Echo 的发布评论是怎么做的](https://mp.weixin.qq.com/s/S5bNpzuZFga2u15ik2t2iQ) - Echo 的私信列表与详情页是怎么做的 - Echo 的发送私信是怎么做的 - Echo 的点赞模块是怎么做的 diff --git a/docs/_coverpage.md b/docs/_coverpage.md index ffa5692e..dfadd844 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,6 +1,6 @@ ![Logo](https://gitee.com/veal98/images/raw/master/img/20210211175136.png) -# Echo 1.0 +# Echo 2.0 > 🦄 开源社区系统 diff --git a/src/main/java/com/greate/community/config/SecurityConfig.java b/src/main/java/com/greate/community/config/SecurityConfig.java index c17e83bf..e413d477 100644 --- a/src/main/java/com/greate/community/config/SecurityConfig.java +++ b/src/main/java/com/greate/community/config/SecurityConfig.java @@ -45,6 +45,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter implements Comm "/user/setting", "/user/upload", "/discuss/add", + "/discuss/publish", "/comment/add/**", "/letter/**", "/notice/**", @@ -119,5 +120,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter implements Comm // Security 底层会默认拦截 /logout 请求,进行退出处理 // 此处赋予它一个根本不存在的退出路径,使得程序能够执行到我们自己编写的退出代码 http.logout().logoutUrl("/securitylogout"); + + http.headers().frameOptions().sameOrigin(); } } diff --git a/src/main/java/com/greate/community/config/WebMvcConfig.java b/src/main/java/com/greate/community/config/WebMvcConfig.java index c83f9f38..fc270bbe 100644 --- a/src/main/java/com/greate/community/config/WebMvcConfig.java +++ b/src/main/java/com/greate/community/config/WebMvcConfig.java @@ -6,6 +6,7 @@ import com.greate.community.controller.interceptor.MessageInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** @@ -23,17 +24,25 @@ public class WebMvcConfig implements WebMvcConfigurer { @Autowired private DataInterceptor dataInterceptor; + // 对除静态资源外所有路径进行拦截 @Override public void addInterceptors(InterceptorRegistry registry) { - // 对除静态资源外所有路径进行拦截 registry.addInterceptor(loginTicketInterceptor) - .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**"); + .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**", "/editor-md-upload/**"); registry.addInterceptor(messageInterceptor) - .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**"); + .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**", "/editor-md-upload/**"); registry.addInterceptor(dataInterceptor) - .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**"); + .excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**", "/editor-md-upload/**"); + } + + // 配置虚拟路径映射访问 + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry){ + // System.getProperty("user.dir") 获取程序的当前路径 + String path = System.getProperty("user.dir")+"\\src\\main\\resources\\static\\editor-md-upload\\"; + registry.addResourceHandler("/editor-md-upload/**").addResourceLocations("file:" + path); } } diff --git a/src/main/java/com/greate/community/controller/DiscussPostController.java b/src/main/java/com/greate/community/controller/DiscussPostController.java index 9368074f..7dee75a8 100644 --- a/src/main/java/com/greate/community/controller/DiscussPostController.java +++ b/src/main/java/com/greate/community/controller/DiscussPostController.java @@ -10,13 +10,21 @@ import com.greate.community.util.CommunityConstant; import com.greate.community.util.CommunityUtil; import com.greate.community.util.HostHolder; import com.greate.community.util.RedisKeyUtil; +import com.qiniu.util.Auth; +import com.qiniu.util.StringMap; +import org.checkerframework.checker.units.qual.A; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.util.HtmlUtils; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; import java.util.*; /** @@ -47,6 +55,30 @@ public class DiscussPostController implements CommunityConstant { @Autowired private RedisTemplate redisTemplate; + // 网站域名 + @Value("${community.path.domain}") + private String domain; + + // 项目名(访问路径) + @Value("${server.servlet.context-path}") + private String contextPath; + + @Value("${qiniu.key.access}") + private String accessKey; + + @Value("${qiniu.key.secret}") + private String secretKey; + + @Value("${qiniu.bucket.header.name}") + private String headerBucketName; + + @Value("${qiniu.bucket.header.url}") + private String headerBucketUrl; + + // editorMd 图片上传地址 + @Value("${community.path.editormdUploadPath}") + private String editormdUploadPath; + /** * 进入帖子发布页 * @return @@ -58,13 +90,37 @@ public class DiscussPostController implements CommunityConstant { /** * markdown 图片上传 - * 功能尚未完成 + * @param file * @return */ @PostMapping("/uploadMdPic") @ResponseBody - public String uploadMdPic() { - return null; + public String uploadMdPic(@RequestParam(value = "editormd-image-file", required = false) MultipartFile file) { + + String url = null; // 图片访问地址 + try { + // 获取上传文件的名称 + String trueFileName = file.getOriginalFilename(); + String suffix = trueFileName.substring(trueFileName.lastIndexOf(".")); + String fileName = CommunityUtil.generateUUID() + suffix; + + // 图片存储路径 + File dest = new File(editormdUploadPath + "/" + fileName); + if (!dest.getParentFile().exists()) { + dest.getParentFile().mkdirs(); + } + + // 保存图片到存储路径 + file.transferTo(dest); + + // 图片访问地址 + url = domain + contextPath + "/editor-md-upload/" + fileName; + } catch (Exception e) { + e.printStackTrace(); + return CommunityUtil.getEditorMdJSONString(0, "上传失败", url); + } + + return CommunityUtil.getEditorMdJSONString(1, "上传成功", url); } /** diff --git a/src/main/java/com/greate/community/controller/UserController.java b/src/main/java/com/greate/community/controller/UserController.java index a936661e..4cdd1c0a 100644 --- a/src/main/java/com/greate/community/controller/UserController.java +++ b/src/main/java/com/greate/community/controller/UserController.java @@ -76,15 +76,15 @@ public class UserController implements CommunityConstant { public String getSettingPage(Model model) { // 生成上传文件的名称 String fileName = CommunityUtil.generateUUID(); + model.addAttribute("fileName", fileName); + // 设置响应信息(qiniu 的规定写法) StringMap policy = new StringMap(); policy.put("returnBody", CommunityUtil.getJSONString(0)); // 生成上传到 qiniu 的凭证(qiniu 的规定写法) Auth auth = Auth.create(accessKey, secretKey); String uploadToken = auth.uploadToken(headerBucketName, fileName, 3600, policy); - model.addAttribute("uploadToken", uploadToken); - model.addAttribute("fileName", fileName); return "/site/setting"; } diff --git a/src/main/java/com/greate/community/util/CommunityUtil.java b/src/main/java/com/greate/community/util/CommunityUtil.java index a8f06f2f..feff0883 100644 --- a/src/main/java/com/greate/community/util/CommunityUtil.java +++ b/src/main/java/com/greate/community/util/CommunityUtil.java @@ -60,6 +60,15 @@ public class CommunityUtil { return getJSONString(code, null, null); } + // editor.md 要求返回的 JSON 字符串格式 + public static String getEditorMdJSONString(int success, String message, String url) { + JSONObject json = new JSONObject(); + json.put("success", success); + json.put("message", message); + json.put("url", url); + return json.toJSONString(); + } + /** * 测试 * @param args diff --git a/src/main/resources/application-develop.properties b/src/main/resources/application-develop.properties index 99d3f560..2a2a77de 100644 --- a/src/main/resources/application-develop.properties +++ b/src/main/resources/application-develop.properties @@ -6,6 +6,8 @@ server.servlet.context-path = # վ community.path.domain = http://localhost:8080 +# Editor.Md ͼƬϴ· +community.path.editormdUploadPath = E:/GreateCommunity/src/main/resources/static/editor-md-upload # Thymeleaf spring.thymeleaf.cache=false diff --git a/src/main/resources/static/editor-md-upload/05ed9c9c900d475b86a66bee7c39642e.jpeg b/src/main/resources/static/editor-md-upload/05ed9c9c900d475b86a66bee7c39642e.jpeg new file mode 100644 index 00000000..580cd302 Binary files /dev/null and b/src/main/resources/static/editor-md-upload/05ed9c9c900d475b86a66bee7c39642e.jpeg differ diff --git a/src/main/resources/static/editor-md-upload/5f84429642a042fe8cc0db924a606666.jpeg b/src/main/resources/static/editor-md-upload/5f84429642a042fe8cc0db924a606666.jpeg new file mode 100644 index 00000000..a91c20ec Binary files /dev/null and b/src/main/resources/static/editor-md-upload/5f84429642a042fe8cc0db924a606666.jpeg differ diff --git a/src/main/resources/static/editor-md-upload/ed84395548b045b386ec2f1ca6dde32d.jpeg b/src/main/resources/static/editor-md-upload/ed84395548b045b386ec2f1ca6dde32d.jpeg new file mode 100644 index 00000000..580cd302 Binary files /dev/null and b/src/main/resources/static/editor-md-upload/ed84395548b045b386ec2f1ca6dde32d.jpeg differ diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index af6db8e3..94809fab 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -84,11 +84,13 @@ - - + + + + diff --git a/src/main/resources/templates/site/discuss-detail.html b/src/main/resources/templates/site/discuss-detail.html index a587bcbd..03a7c633 100644 --- a/src/main/resources/templates/site/discuss-detail.html +++ b/src/main/resources/templates/site/discuss-detail.html @@ -9,6 +9,8 @@ + + Echo - 帖子详情 @@ -57,7 +59,7 @@
- +
@@ -210,7 +212,7 @@ tex: true, // 默认不解析 flowChart: true, // 默认不解析 sequenceDiagram: true, // 默认不解析 - codeFold: true, + codeFold: true }) }) diff --git a/src/main/resources/templates/site/discuss-publish.html b/src/main/resources/templates/site/discuss-publish.html index 1e6644e6..b0e5c1f4 100644 --- a/src/main/resources/templates/site/discuss-publish.html +++ b/src/main/resources/templates/site/discuss-publish.html @@ -20,15 +20,17 @@
- +
-