This commit is contained in:
oneao committed 2025-12-25 17:31:09 +08:00
1 parent 5221d1cc91
commit a8a2657753
30 files changed
+552 -255

No files matched your search

@@ -0,0 +1,64 @@
package cn.link56.post.controller;
import cn.link56.common.BasePageVO;
import cn.link56.common.Result;
import cn.link56.post.model.dto.*;
import cn.link56.post.model.vo.EditorDashboardVO;
import cn.link56.post.model.vo.EditorPostVO;
import cn.link56.post.model.vo.QueryEditorPostVO;
import cn.link56.post.service.PostService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/editor/post")
public class EditorPostController {
@Resource
private PostService postService;
@GetMapping("/{id}")
public Result<EditorPostVO> getEditDetail(@PathVariable("id") Long id) {
EditorPostVO editorPostVO = postService.getEditDetail(id);
return Result.success(editorPostVO);
}
@PostMapping("/create")
public Result<EditorPostVO> createPost(@RequestBody @Validated CreatePostDTO createPostDTO) {
EditorPostVO editorPostVO = postService.createPost(createPostDTO);
return Result.success(editorPostVO);
}
@PostMapping("/update")
public Result<EditorPostVO> updatePost(@RequestBody @Validated UpdatePostDTO updatePostDTO){
EditorPostVO editorPostVO = postService.updatePost(updatePostDTO);
return Result.success(editorPostVO);
}
@PostMapping("/update/status")
public Result<EditorPostVO> updatePostStatus(@RequestBody @Validated UpdatePostStatusDTO updatePostStatusDTO){
postService.updatePostStatus(updatePostStatusDTO);
return Result.success();
}
@PostMapping("/delete")
public Result<Void> deletePost(@RequestBody @Validated DeletePostDTO deletePostDTO){
postService.deletePost(deletePostDTO);
return Result.success();
}
@PostMapping("/query")
public Result<BasePageVO<QueryEditorPostVO>> queryEditorPosts(@RequestBody QueryEditorPostDTO queryEditorPostDTO){
BasePageVO<QueryEditorPostVO> data = postService.queryEditorPosts(queryEditorPostDTO);
return Result.success(data);
}
@GetMapping("/dashboard")
public Result<EditorDashboardVO> getEditorDashboard(){
EditorDashboardVO editorDashboardVO = postService.getEditorDashboard();
return Result.success(editorDashboardVO);
}
}
@@ -1,27 +0,0 @@
package cn.link56.post.controller;
import cn.link56.common.Result;
import cn.link56.post.model.vo.PostCategoryVO;
import cn.link56.post.model.vo.PostTagVO;
import cn.link56.post.service.PostCategoryService;
import cn.link56.post.service.PostTagService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/post/category")
public class PostCategoryController {
@Resource
private PostCategoryService postCategoryService;
@GetMapping
public Result<List<PostCategoryVO>> listCategories(){
List<PostCategoryVO> list = postCategoryService.listCategories();
return Result.success(list);
}
}
@@ -2,65 +2,34 @@ package cn.link56.post.controller;
import cn.link56.common.BasePageVO;
import cn.link56.common.Result;
import cn.link56.post.model.dto.*;
import cn.link56.post.model.vo.EditPostVO;
import cn.link56.post.model.vo.DashboardVO;
import cn.link56.post.model.vo.QueryPostVO;
import cn.link56.post.model.dto.QueryPublicPostDTO;
import cn.link56.post.model.vo.PostTagVO;
import cn.link56.post.model.vo.QueryPublicPostVO;
import cn.link56.post.service.PostService;
import org.springframework.validation.annotation.Validated;
import cn.link56.post.service.PostTagService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/post")
public class PostController {
@Resource
private PostService postService;
@Resource
private PostTagService postTagService;
@GetMapping("/{id}")
public Result<EditPostVO> getDetail(@PathVariable("id") Long id) {
EditPostVO editPostVO = postService.getDetail(id);
return Result.success(editPostVO);
}
@GetMapping("/tag")
public Result<List<PostTagVO>> listTags(){
List<PostTagVO> list = postTagService.listTags();
@PostMapping("/add")
public Result<EditPostVO> addPost(@RequestBody @Validated AddPostDTO addPostDTO) {
EditPostVO editPostVO = postService.addPost(addPostDTO);
return Result.success(editPostVO);
}
@PostMapping("/update")
public Result<EditPostVO> updatePost(@RequestBody @Validated UpdatePostDTO updatePostDTO){
EditPostVO editPostVO = postService.updatePost(updatePostDTO);
return Result.success(editPostVO);
}
@PostMapping("/update/status")
public Result<EditPostVO> updatePostStatus(@RequestBody @Validated UpdatePostStatusDTO updatePostStatusDTO){
postService.updatePostStatus(updatePostStatusDTO);
return Result.success();
return Result.success(list);
}
@PostMapping("/query")
public Result<BasePageVO<QueryPostVO>> queryPost(@RequestBody QueryPostDTO queryPostDTO){
BasePageVO<QueryPostVO> data = postService.queryPost(queryPostDTO);
return Result.success(data);
public Result<BasePageVO<QueryPublicPostVO>> queryPublicPosts(@RequestBody QueryPublicPostDTO dto){
BasePageVO<QueryPublicPostVO> res = postService.queryPublicPosts(dto);
return Result.success(res);
}
@PostMapping("/delete")
public Result<Void> deletePost(@RequestBody @Validated DeletePostDTO deletePostDTO){
postService.deletePost(deletePostDTO);
return Result.success();
}
@GetMapping("/dashboard")
public Result<DashboardVO> getDashboardData(){
DashboardVO dashboardVO = postService.getDashboardData();
return Result.success(dashboardVO);
}
}
@@ -1,27 +0,0 @@
package cn.link56.post.controller;
import cn.link56.common.Result;
import cn.link56.post.mapper.PostTagMapper;
import cn.link56.post.model.vo.PostTagVO;
import cn.link56.post.service.PostTagService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/post/tag")
public class PostTagController {
@Resource
private PostTagService postTagService;
@GetMapping
public Result<List<PostTagVO>> listTags(){
List<PostTagVO> list = postTagService.listTags();
return Result.success(list);
}
}
@@ -1,8 +1,8 @@
package cn.link56.post.mapper;
import cn.link56.post.model.po.Post;
import cn.link56.post.model.vo.DashboardVO;
import cn.link56.post.model.vo.QueryPostVO;
import cn.link56.post.model.vo.EditorDashboardVO;
import cn.link56.post.model.vo.QueryEditorPostVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -11,7 +11,7 @@ import java.util.List;
@Mapper
public interface PostMapper extends BaseMapper<Post> {
List<QueryPostVO> selectPostPage(
List<QueryEditorPostVO> selectEditorPostPage(
@Param("offset") int offset,
@Param("limit") int limit,
@Param("userId") Long userId,
@@ -21,7 +21,7 @@ public interface PostMapper extends BaseMapper<Post> {
@Param("month") String month
);
Long selectPostTotal(
Long selectEditorPostTotal(
@Param("userId") Long userId,
@Param("title") String title,
@Param("status") Integer status,
@@ -29,8 +29,8 @@ public interface PostMapper extends BaseMapper<Post> {
@Param("month") String month
);
DashboardVO.Count selectDashboardOverview(@Param("userId") Long userId);
EditorDashboardVO.Count selectDashboardOverview(@Param("userId") Long userId);
List<DashboardVO.Chart> selectDashboardViewStats(@Param("userId") Long userId);
List<DashboardVO.Chart> selectDashboardNumberStats(@Param("userId") Long userId);
List<EditorDashboardVO.Chart> selectDashboardViewStats(@Param("userId") Long userId);
List<EditorDashboardVO.Chart> selectDashboardNumberStats(@Param("userId") Long userId);
}
@@ -10,7 +10,7 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AddPostDTO {
public class CreatePostDTO {
@NotBlank(message = "帖子标题不能为空")
private String title;
@NotBlank(message = "帖子内容不能为空")
@@ -7,7 +7,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QueryPostDTO {
public class QueryEditorPostDTO {
private Integer currentPage;
private Integer pageSize;
@@ -0,0 +1,13 @@
package cn.link56.post.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QueryPublicPostDTO {
private String title;
private String tag;
}
@@ -18,6 +18,9 @@ public class PostTag {
@TableField("b_name")
private String name;
@TableField("b_icon")
private String icon;
@TableField("b_canuse")
private String canuse;
}
@@ -9,7 +9,7 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DashboardVO {
public class EditorDashboardVO {
private Count allCount;
private List<Chart> numberChart;
private List<Chart> viewChart;
@@ -10,7 +10,7 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EditPostVO {
public class EditorPostVO {
private Long id;
private String title;
private String content;
@@ -10,4 +10,5 @@ import lombok.NoArgsConstructor;
public class PostCategoryVO {
private Long id;
private String name;
private String icon;
}
@@ -10,4 +10,5 @@ import lombok.NoArgsConstructor;
public class PostTagVO {
private Long id;
private String name;
private String icon;
}
@@ -10,7 +10,7 @@ import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QueryPostVO {
public class QueryEditorPostVO {
private Long id;
private String title;
@@ -0,0 +1,25 @@
package cn.link56.post.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QueryPublicPostVO {
private Long id;
private String title;
private List<String> tags;
private Long companyId;
private String companyName;
private Integer viewCount;
private Integer commentCount;
private Date activeTime;
}
@@ -7,9 +7,10 @@ import cn.link56.post.mapper.PostMapper;
import cn.link56.post.model.dto.*;
import cn.link56.post.model.enums.PostStatusEnum;
import cn.link56.post.model.po.Post;
import cn.link56.post.model.vo.DashboardVO;
import cn.link56.post.model.vo.EditPostVO;
import cn.link56.post.model.vo.QueryPostVO;
import cn.link56.post.model.vo.EditorDashboardVO;
import cn.link56.post.model.vo.EditorPostVO;
import cn.link56.post.model.vo.QueryEditorPostVO;
import cn.link56.post.model.vo.QueryPublicPostVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
@@ -30,7 +31,7 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
private PostMapper postMapper;
@Transactional
public EditPostVO addPost(AddPostDTO dto) {
public EditorPostVO createPost(CreatePostDTO dto) {
Post post = new Post();
BeanUtils.copyProperties(dto, post);
@@ -44,7 +45,7 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
return buildEditPostVO(post);
}
public EditPostVO updatePost(UpdatePostDTO dto) {
public EditorPostVO updatePost(UpdatePostDTO dto) {
Post post = postMapper.selectById(dto.getId());
if (post == null) {
return null;
@@ -59,7 +60,7 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
return buildEditPostVO(post);
}
public EditPostVO getDetail(Long id) {
public EditorPostVO getEditDetail(Long id) {
Post post = postMapper.selectById(id);
if (post == null) {
return null;
@@ -68,11 +69,11 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
return buildEditPostVO(post);
}
public BasePageVO<QueryPostVO> queryPost(QueryPostDTO dto) {
public BasePageVO<QueryEditorPostVO> queryEditorPosts(QueryEditorPostDTO dto) {
int offset = (dto.getCurrentPage() - 1) * dto.getPageSize() + 1;
int limit = dto.getCurrentPage() * dto.getPageSize();
List<QueryPostVO> records = postMapper.selectPostPage(
List<QueryEditorPostVO> records = postMapper.selectEditorPostPage(
offset,
limit,
UserContext.getUserId(),
@@ -82,7 +83,7 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
dto.getMonth()
);
Long total = postMapper.selectPostTotal(
Long total = postMapper.selectEditorPostTotal(
UserContext.getUserId(),
dto.getTitle(),
dto.getStatus(),
@@ -90,7 +91,7 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
dto.getMonth()
);
BasePageVO<QueryPostVO> page = new BasePageVO<>();
BasePageVO<QueryEditorPostVO> page = new BasePageVO<>();
page.setRecords(records);
page.setTotal(total);
return page;
@@ -98,8 +99,8 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
/* ================= 私有方法 ================= */
private EditPostVO buildEditPostVO(Post post) {
EditPostVO vo = new EditPostVO();
private EditorPostVO buildEditPostVO(Post post) {
EditorPostVO vo = new EditorPostVO();
BeanUtils.copyProperties(post, vo);
vo.setTags(
@@ -142,45 +143,45 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
postMapper.updateById(post);
}
public DashboardVO getDashboardData() {
public EditorDashboardVO getEditorDashboard() {
Long userId = UserContext.getUserId();
DashboardVO dashboardVO = new DashboardVO();
EditorDashboardVO editorDashboardVO = new EditorDashboardVO();
DashboardVO.Count count = postMapper.selectDashboardOverview(userId);
EditorDashboardVO.Count count = postMapper.selectDashboardOverview(userId);
// 原始数据
List<DashboardVO.Chart> viewCharts = postMapper.selectDashboardViewStats(userId);
List<DashboardVO.Chart> numberCharts = postMapper.selectDashboardNumberStats(userId);
List<DashboardVO.Chart> typeCharts = getDashboardTypeStats(userId);
List<EditorDashboardVO.Chart> viewCharts = postMapper.selectDashboardViewStats(userId);
List<EditorDashboardVO.Chart> numberCharts = postMapper.selectDashboardNumberStats(userId);
List<EditorDashboardVO.Chart> typeCharts = getDashboardTypeStats(userId);
// 统一处理最近 7 天,补齐缺失值
dashboardVO.setViewChart(fillLast7Days(viewCharts));
dashboardVO.setNumberChart(fillLast7Days(numberCharts));
dashboardVO.setTypeChart(typeCharts);
editorDashboardVO.setViewChart(fillLast7Days(viewCharts));
editorDashboardVO.setNumberChart(fillLast7Days(numberCharts));
editorDashboardVO.setTypeChart(typeCharts);
dashboardVO.setAllCount(count);
return dashboardVO;
editorDashboardVO.setAllCount(count);
return editorDashboardVO;
}
/**
* 填充最近7天的 chart 数据,如果 map 里没有,则补 0
*/
private List<DashboardVO.Chart> fillLast7Days(List<DashboardVO.Chart> originalCharts) {
private List<EditorDashboardVO.Chart> fillLast7Days(List<EditorDashboardVO.Chart> originalCharts) {
// 转 map,方便查
Map<String, Integer> map = originalCharts.stream()
.collect(Collectors.toMap(DashboardVO.Chart::getLabel, DashboardVO.Chart::getValue, (a, b) -> b));
.collect(Collectors.toMap(EditorDashboardVO.Chart::getLabel, EditorDashboardVO.Chart::getValue, (a, b) -> b));
List<DashboardVO.Chart> result = new ArrayList<>();
List<EditorDashboardVO.Chart> result = new ArrayList<>();
for (int i = 6; i >= 0; i--) {
String date = LocalDate.now().minusDays(i).toString();
result.add(new DashboardVO.Chart(date, map.getOrDefault(date, 0)));
result.add(new EditorDashboardVO.Chart(date, map.getOrDefault(date, 0)));
}
return result;
}
private List<DashboardVO.Chart> getDashboardTypeStats(Long userId) {
private List<EditorDashboardVO.Chart> getDashboardTypeStats(Long userId) {
LambdaQueryWrapper<Post> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.select(Post::getTag)
@@ -209,10 +210,19 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
}
// 转成 DashboardVO.Chart 列表
List<DashboardVO.Chart> result = new ArrayList<>();
tagCountMap.forEach((tag, count) -> result.add(new DashboardVO.Chart(tag, count)));
List<EditorDashboardVO.Chart> result = new ArrayList<>();
tagCountMap.forEach((tag, count) -> result.add(new EditorDashboardVO.Chart(tag, count)));
return result;
}
public BasePageVO<QueryPublicPostVO> queryPublicPosts(QueryPublicPostDTO dto) {
String title = dto.getTitle();
String tag = dto.getTag();
BasePageVO<QueryPublicPostVO> result = new BasePageVO<>();
return result;
}
}
@@ -4,8 +4,8 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.link56.post.mapper.PostMapper">
<resultMap id="QueryPostVOMap"
type="cn.link56.post.model.vo.QueryPostVO">
<resultMap id="QueryEditorPostVOMap"
type="cn.link56.post.model.vo.QueryEditorPostVO">
<id property="id" column="id"/>
<result property="title" column="title"/>
@@ -25,7 +25,27 @@
<result property="commentCount" column="commentCount"/>
</resultMap>
<select id="selectPostPage" resultMap="QueryPostVOMap">
<resultMap id="QueryPublicPostVOMap"
type="cn.link56.post.model.vo.QueryPublicPostVO">
<id property="id" column="id"/>
<result property="title" column="title"/>
<!-- tags 字符串 → List<String> -->
<result
property="tags"
column="tagsString"
typeHandler="cn.link56.common.mybatis.StringListTypeHandler"/>
<result property="companyId" column="companyId"/>
<result property="companyName" column="companyName"/>
<result property="viewCount" column="viewCount"/>
<result property="commentCount" column="commentCount"/>
<result property="activeTime" column="activeTime"/>
</resultMap>
<select id="selectEditorPostPage" resultMap="QueryEditorPostVOMap">
SELECT *
FROM (
SELECT
@@ -68,7 +88,7 @@
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
<select id="selectPostTotal" resultType="java.lang.Long">
<select id="selectEditorPostTotal" resultType="java.lang.Long">
SELECT COUNT(*)
FROM b_post p
<where>
@@ -94,7 +114,7 @@
</where>
</select>
<select id="selectDashboardOverview" resultType="cn.link56.post.model.vo.DashboardVO$Count">
<select id="selectDashboardOverview" resultType="cn.link56.post.model.vo.EditorDashboardVO$Count">
SELECT
(SELECT COUNT(*) FROM b_post WHERE b_create_by = #{userId}) AS postCount,
(SELECT COUNT(*) FROM b_post_view WHERE b_post_id IN (SELECT b_id FROM b_post WHERE b_create_by = #{userId})) AS viewCount,
@@ -102,7 +122,7 @@
(SELECT COUNT(*) FROM b_post_favorite WHERE b_post_id IN (SELECT b_id FROM b_post WHERE b_create_by = #{userId})) AS favoriteCount
</select>
<select id="selectDashboardViewStats" resultType="cn.link56.post.model.vo.DashboardVO$Chart">
<select id="selectDashboardViewStats" resultType="cn.link56.post.model.vo.EditorDashboardVO$Chart">
SELECT
CONVERT(VARCHAR(10), v.b_create_time, 120) AS label,
COUNT(*) AS value
@@ -115,7 +135,7 @@
ORDER BY label
</select>
<select id="selectDashboardNumberStats" resultType="cn.link56.post.model.vo.DashboardVO$Chart">
<select id="selectDashboardNumberStats" resultType="cn.link56.post.model.vo.EditorDashboardVO$Chart">
SELECT
CONVERT(VARCHAR(10), p.b_create_time, 120) AS label,
COUNT(*) AS value
@@ -127,4 +147,61 @@
ORDER BY label
</select>
<select id="selectPublicPostPage" resultMap="QueryPublicPostVOMap">
SELECT
t.id,
t.title,
t.tagsString,
t.companyId,
t.companyName,
t.viewCount,
t.commentCount,
t.activeTime
FROM (
SELECT
p.b_id AS id,
p.b_title AS title,
p.b_tag AS tagsString,
p.company_id AS companyId,
bc.b_name AS companyName,
ISNULL(pv.viewCount, 0) AS viewCount,
ISNULL(pc.commentCount, 0) AS commentCount,
-- 活跃时间:最后评论时间优先
ISNULL(pc.lastCommentTime, p.b_update_time) AS activeTime,
ROW_NUMBER() OVER (
ORDER BY ISNULL(pc.lastCommentTime, p.b_update_time) DESC
) AS rn
FROM b_post p
LEFT JOIN b_company bc ON bc.b_id = p.company_id
LEFT JOIN (
SELECT
b_post_id,
COUNT(1) AS viewCount
FROM b_post_view
GROUP BY b_post_id
) pv ON pv.b_post_id = p.b_id
LEFT JOIN (
SELECT
b_post_id,
COUNT(1) AS commentCount,
MAX(b_create_time) AS lastCommentTime
FROM b_post_comment
GROUP BY b_post_id
) pc ON pc.b_post_id = p.b_id
<where>
<if test="title != null and title != ''">
AND p.b_title LIKE '%' + #{title} + '%'
</if>
<if test="tag != null and tag != -1">
AND p.b_tag LIKE '%' + #{tag} + '%'
</if>
</where>
) t
WHERE t.rn BETWEEN #{offset} AND #{limit}
</select>
</mapper>