1. 增加富文本编辑
如果发布的问题中有代码片段如何能正常的显示出来呢?

1.1 在static中加入以下资源

1.2 在发布页面引入

加入js代码

<div class="form-group" id="question-editor">
<label for="description">问题补充 (必填,请参照右侧提示):</label>
<textarea name="description" id="description" style="display: none"
class="form-control"
cols="30"
rows="10"
th:text="${description}"></textarea>
</div>
<script type="text/javascript">
$(function () {
var editor = editormd("question-editor", {
width: "100%",
height: 350,
path: "/js/lib/",
delay: 0,
watch: false,
placeholder: "请输入问题描述",
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "/file/upload",
});
});
</script>
1.3 在问题页面引入

内容的展示

<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" id="question-view">
<textarea style="display:none;" th:text="${question.description}"></textarea>
</div>
<script type="text/javascript">
$(function () {
editormd.markdownToHTML("question-view", {});
});
</script>
2. 图片上传
2.1 创建FileDTO

2.2 引入plugins

2.3 提交页面js改变

<div class="form-group" id="question-editor">
<label for="description">问题补充 (必填,请参照右侧提示):</label>
<textarea name="description" id="description" style="display: none"
class="form-control"
cols="30"
rows="10"
th:text="${description}"></textarea>
</div>
<script type="text/javascript">
$(function () {
var editor = editormd("question-editor", {
width: "100%",
height: 350,
path: "/js/lib/",
delay: 0,
watch: false,
placeholder: "请输入问题描述",
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "/file/upload",
});
});
</script>
2.4 引入依赖
<dependency>
<groupId>cn.ucloud.ufile</groupId>
<artifactId>ufile-client-java</artifactId>
<version>2.1.1</version>
</dependency>
2.5 UCloud注册


2.6 创建UcloudProvider


package life.guohui.community.provider;
@Service
public class UCloudProvider {
@Value("${ucloud.ufile.public-key}")
private String publicKey;
@Value("${ucloud.ufile.private-key}")
private String privateKey;
@Value("${ucloud.ufile.bucket-name}")
private String bucketName;
@Value("${ucloud.ufile.region}")
private String region;
@Value("${ucloud.ufile.suffix}")
private String suffix;
@Value("${ucloud.ufile.expires}")
private Integer expires;
public String upload(InputStream fileStream, String mimeType, String fileName) {
String generatedFileName;
String[] filePaths = fileName.split("\\.");
if (filePaths.length > 1) {
generatedFileName = UUID.randomUUID().toString() + "." + filePaths[filePaths.length - 1];
} else {
throw new CustomizeException(CustomizeErrorCode.FILE_UPLOAD_FAIL);
}
try {
ObjectAuthorization objectAuthorization = new UfileObjectLocalAuthorization(publicKey, privateKey);
ObjectConfig config = new ObjectConfig(region, suffix);
PutObjectResultBean response = UfileClient.object(objectAuthorization, config)
.putObject(fileStream, mimeType)
.nameAs(generatedFileName)
.toBucket(bucketName)
.setOnProgressListener((bytesWritten, contentLength) -> {
})
.execute();
if (response != null && response.getRetCode() == 0) {
String url = UfileClient.object(objectAuthorization, config)
.getDownloadUrlFromPrivateBucket(generatedFileName, bucketName, expires)
.createUrl();
return url;
} else {
//log.error("upload error,{}", response);
throw new CustomizeException(CustomizeErrorCode.FILE_UPLOAD_FAIL);
}
} catch (UfileClientException e) {
//log.error("upload error,{}", fileName, e);
throw new CustomizeException(CustomizeErrorCode.FILE_UPLOAD_FAIL);
} catch (UfileServerException e) {
//log.error("upload error,{}", fileName, e);
throw new CustomizeException(CustomizeErrorCode.FILE_UPLOAD_FAIL);
}
}
}
异常信息

2.7 在配置文件中配置信息

server.port=8887
github.client.id=Iv1.bf5154208e60707f
github.client.secret=a486e92081386641d69c8f81c7ad228afce2f062
github.redirect.uri=http://localhost:8887/callback
spring.datasource.url=jdbc:h2:E:/Users/IdeaProjects/community
spring.datasource.username=sa
spring.datasource.password=123
spring.datasource.driver-class-name=org.h2.Driver
# 开启驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=true
# 扫描mapper.xml和mapper接口模型
mybatis.type-aliases-package=life.guohui.community.mapper
mybatis.mapper-locations=classpath:mapper/*.xml
# 文件上传
ucloud.ufile.public-key=xxx
ucloud.ufile.private-key=xxx
ucloud.ufile.bucket-name=coderuan
ucloud.ufile.region=cn-bj
ucloud.ufile.suffix=ufileos.com
ucloud.ufile.expires=315360000
2.8 创建FileController

package life.guohui.community.controller;
@Controller
public class FileController {
@Autowired
private UCloudProvider uCloudProvider;
@RequestMapping("/file/upload")
@ResponseBody
public FileDTO upload(HttpServletRequest request){
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("editormd-image-file");
try {
String fileName = uCloudProvider.upload(file.getInputStream(), file.getContentType(), file.getOriginalFilename());
FileDTO fileDTO = new FileDTO();
fileDTO.setSuccess(1);
fileDTO.setUrl(fileName);
return fileDTO;
} catch (Exception e) {
//log.error("upload error", e);
FileDTO fileDTO = new FileDTO();
fileDTO.setSuccess(0);
fileDTO.setMessage("上传失败");
return fileDTO;
}
}
}
3. 多人登陆问题
3.1 评论者头像和昵称
从session中获取当前用户,还要判断是否存在,没有登陆使用默认头像和昵称

3.2 如果发布者和问题评论者是一个人不创建通知

4. 搜索功能
4.1 index增加查询条件参数
把查询条件存入Model中,让分页使用

4.2 创建QuestionQueryDTO
封装查询条件和,分页参数

4.3 在questionService中

public PaginationDTO list(String search, Integer page, Integer size) {
PaginationDTO paginationDTO = new PaginationDTO();
Integer totalPage;
QuestionQueryDTO questionQueryDTO = new QuestionQueryDTO();
questionQueryDTO.setSearch(search);
Integer totalCount = questionMapper.countBySearch(questionQueryDTO);
//拿到总数
if(totalCount % size == 0){totalPage = totalCount/size;}else{totalPage = totalCount/size + 1;}
if(page<1){ page = 1;}
if(page>totalPage){page = totalPage;}
paginationDTO.setPagination(totalPage,page);
Integer offset = size * (page - 1);
QuestionExample qustionExample = new QuestionExample();
qustionExample.setOrderByClause("gmt_create desc");
questionQueryDTO.setSize(size);
questionQueryDTO.setPage(offset);
List<Question> questions = questionMapper.selectBySearch(questionQueryDTO);
List<QuestionDTO> questionDTOList = new ArrayList<>();
for(Question question : questions){
User user = userMapper.selectByPrimaryKey(question.getCreator());
QuestionDTO questionDTO = new QuestionDTO();
BeanUtils.copyProperties(question,questionDTO);
questionDTO.setUser(user);
questionDTOList.add(questionDTO);
}
paginationDTO.setData(questionDTOList);
return paginationDTO;
}
4.4 mapper中创建方法

<select id="countBySearch" parameterType="life.guohui.community.dto.QuestionQueryDTO"
resultType="java.lang.Integer">
select count(*) from QUESTION
<where>
<if test="search != null and search != ''">
and title regexp #{search}
</if>
</where>
</select>
<select id="selectBySearch" parameterType="life.guohui.community.dto.QuestionQueryDTO"
resultMap="BaseResultMap">
select * from QUESTION
<where>
<if test="search != null and search != ''">
and title regexp #{search}
</if>
</where>
order by gmt_create desc limit #{page},#{size}
</select>
4.5 index.html分页
请求链接携带多个参数
th:href="@{/(page=${page},search=${search})}"

网友评论