Compare commits

..

2 Commits

Author SHA1 Message Date
苏元皓
dda2cdfdc1 Merge branch 'main' of https://gitea.xinxijishubu.asia/iVMiku/guidance-backend 2024-08-29 22:24:42 +08:00
苏元皓
00cc0b32e2 新增教程 2024-08-29 22:24:32 +08:00
25 changed files with 744 additions and 21 deletions

View File

@@ -67,8 +67,8 @@
<option name="tableUIInfoList">
<list>
<TableUIInfo>
<option name="className" value="BrowingHistory" />
<option name="tableName" value="browing_history" />
<option name="className" value="TutorialTags" />
<option name="tableName" value="tutorial_tags" />
</TableUIInfo>
</list>
</option>

View File

@@ -10,6 +10,7 @@ import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.CommentService;
import com.ivmiku.tutorial.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import org.apiguardian.api.API;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
@@ -24,6 +25,7 @@ import java.util.List;
@RestController
@RequestMapping("/comments")
@SaCheckLogin
public class CommentController {
private static final Logger logger = LoggerFactory.getLogger(CommentController.class);

View File

@@ -49,6 +49,7 @@ public class CommunityController {
* @return 包含社区信息的响应
*/
@GetMapping("/get/{id}")
@Operation(summary = "通过id获取社区信息")
public Result getCommunity(@PathVariable Long id) {
Community community = communityService.getById(id); // 根据ID获取社区信息
return Result.ok(community); // 返回包含社区信息的成功结果
@@ -62,6 +63,7 @@ public class CommunityController {
* @return 更新结果的响应
*/
@PutMapping("/update/{id}")
@Operation(summary = "根据id修改社区")
public Result updateCommunity(@PathVariable Long id, @RequestBody Community community) {
communityService.updateCommunity(id, community); // 调用服务层更新社区信息
return Result.ok(); // 返回成功结果
@@ -74,6 +76,7 @@ public class CommunityController {
* @return 删除结果的响应
*/
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除社区")
public Result deleteCommunity(@PathVariable Long id) {
communityService.deleteCommunity(id); // 调用服务层删除社区
return Result.ok(); // 返回成功结果
@@ -86,6 +89,7 @@ public class CommunityController {
* @return 包含社区信息的响应
*/
@GetMapping("/getByName/{name}")
@Operation(summary = "根据name获取社区信息")
public Result getCommunityByName(@PathVariable String name) {
logger.info("社区名称为: {}", name);
List<Community> communitys = communityService.getByName(name); // 根据ID获取社区信息
@@ -98,6 +102,7 @@ public class CommunityController {
* @return 包含社区信息的响应
*/
@GetMapping("/list")
@Operation(summary = "获取所有社区")
public Result getCommunityList() {
List<Community> communities = communityService.getCommunityList(); // 获取社区列表
return Result.ok(communities); // 返回包含社区信息的成功结果

View File

@@ -3,6 +3,7 @@ package com.ivmiku.tutorial.controller;
import com.ivmiku.tutorial.entity.Communitytag;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.CommunitytagService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -16,30 +17,35 @@ public class CommunitytagController {
private CommunitytagService communitytagService;
@PostMapping("/create")
@Operation(summary = "创建社区标签")
public Result createCommunityTag(@RequestBody Communitytag communityTag) {
communitytagService.createCommunityTag(communityTag);
return Result.ok();
}
@PutMapping("/update/{id}")
@Operation(summary = "更新社区标签")
public Result updateCommunityTag(@PathVariable Long id, @RequestBody Communitytag communityTag) {
communitytagService.updateCommunityTag(id, communityTag);
return Result.ok();
}
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除社区标签")
public Result deleteCommunityTag(@PathVariable Long id) {
communitytagService.deleteCommunityTag(id);
return Result.ok();
}
@GetMapping("/get/{id}")
@Operation(summary = "获取社区标签详情")
public Result getCommunityTag(@PathVariable Long id) {
Communitytag communityTag = communitytagService.getCommunityTagById(id);
return Result.ok(communityTag);
}
@GetMapping("/list/{communityId}")
@Operation(summary = "获取社区标签列表")
public Result getCommunityTagListByCommunityId(@PathVariable Long communityId) {
List<Communitytag> tags = communitytagService.getCommunityTagListByCommunityId(communityId);
return Result.ok(tags);

View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ivmiku.tutorial.entity.Post;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.InteractionService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@@ -33,6 +34,7 @@ public class InteractionController {
* @return 操作结果
*/
@PostMapping("/favorite")
@Operation(summary = "对帖子收藏")
public Result favoritePost(@RequestParam Long postId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is favoriting post {}", userOpenid, postId);
@@ -47,6 +49,7 @@ public class InteractionController {
* @return 操作结果
*/
@PostMapping("/likePost")
@Operation(summary = "对帖子点赞")
public Result likePost(@RequestParam Long postId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is liking post {}", userOpenid, postId);
@@ -61,6 +64,7 @@ public class InteractionController {
* @return 操作结果
*/
@PostMapping("/likeComment")
@Operation(summary = "对评论点赞")
public Result likeComment(@RequestParam Long commentId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is liking comment {}", userOpenid, commentId);
@@ -75,6 +79,7 @@ public class InteractionController {
* @return 操作结果
*/
@DeleteMapping("/unfavorite")
@Operation(summary = "取消收藏帖子")
public Result unfavoritePost(@RequestParam Long postId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is unfavoriting post {}", userOpenid, postId);
@@ -89,6 +94,7 @@ public class InteractionController {
* @return 操作结果
*/
@DeleteMapping("/unlikePost")
@Operation(summary = "取消对帖子的点赞")
public Result unlikePost(@RequestParam Long postId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is unliking post {}", userOpenid, postId);
@@ -103,6 +109,7 @@ public class InteractionController {
* @return 操作结果
*/
@DeleteMapping("/unlikeComment")
@Operation(summary = "取消对评论的点赞")
public Result unlikeComment(@RequestParam Long commentId) {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("User {} is unliking comment {}", userOpenid, commentId);
@@ -116,6 +123,7 @@ public class InteractionController {
* @return
*/
@GetMapping("/getFavoritePosts")
@Operation(summary = "获取用户收藏的帖子")
public Result getFavoritePosts() {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("用户 {} 正在获取收藏的帖子", userOpenid);
@@ -134,6 +142,7 @@ public class InteractionController {
* 统计我的获赞数量 笔记数量 收藏数量
*/
@GetMapping("/getLikeCount")
@Operation(summary = "统计用户获赞数量")
public Result getLikeCount() {
String userOpenid = StpUtil.getLoginIdAsString();
log.info("用户 {} 正在获取用户获赞的数量", userOpenid);

View File

@@ -9,8 +9,11 @@ import com.ivmiku.tutorial.entity.Post;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.FileService;
import com.ivmiku.tutorial.service.PostService;
import io.swagger.v3.oas.annotations.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -36,7 +39,12 @@ public class PostController {
@Resource
private FileService fileService;
// RedisTemplate 用于存储和检索搜索历史
@Resource
private RedisTemplate redisTemplate;
@PostMapping("/create")
@Operation(summary = "创建帖子")
public Result createPost(@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("communityId") Long communityId,
@@ -82,6 +90,7 @@ public class PostController {
@GetMapping("/get/{id}")
@Operation(summary = "获取帖子详细信息")
public Result getPost(@PathVariable Long id) {
logger.info("开始获取帖子ID{}的详细信息", id);
String userId = StpUtil.getLoginIdAsString();
@@ -95,6 +104,7 @@ public class PostController {
}
@PutMapping("/update/{id}")
@Operation(summary = "更新帖子信息")
public Result updatePost(@PathVariable Long id, @RequestBody Post post) {
String userId = StpUtil.getLoginIdAsString(); // 获取当前登录用户的ID
logger.info("用户ID{}开始更新帖子ID{}", userId, id);
@@ -104,6 +114,7 @@ public class PostController {
}
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除帖子")
public Result deletePost(@PathVariable Long id) {
String userId = StpUtil.getLoginIdAsString(); // 获取当前登录用户的ID
logger.info("用户ID{}开始删除帖子ID{}", userId, id);
@@ -117,6 +128,7 @@ public class PostController {
* @return 当前用户帖子列表与该用户的总发布数量
*/
@GetMapping("/getPostList")
@Operation(summary = "用户获取自己发布的帖子的列表")
public Result getPostList(@RequestBody Pages pages) {
logger.info("开始获取帖子列表");
String userId = StpUtil.getLoginIdAsString(); // 获取当前登录用户的ID
@@ -132,6 +144,7 @@ public class PostController {
* @return 当前用户帖子列表
*/
@GetMapping("/getCommunityPostList/{communityId}")
@Operation(summary = "获取当前社区帖子列表")
public Result getCommunityPostList(@PathVariable("communityId") Long communityId, @RequestBody Pages pages) {
logger.info("开始获取帖子列表");
IPage<Post> posts = postService.getCommunityPostList(communityId, pages.getPageNum(), pages.getPageSize());
@@ -143,6 +156,7 @@ public class PostController {
* @return
*/
@GetMapping("/official")
@Operation(summary = "获取所有官方创建的帖子")
public IPage<Post> getOfficialPosts(@RequestBody Pages pages) {
return postService.getOfficialPosts(pages.getPageNum(), pages.getPageSize());
}
@@ -152,11 +166,13 @@ public class PostController {
* @return
*/
@GetMapping("/nonOfficial")
@Operation(summary = "获取所有非官方创建的帖子")
public IPage<Post> getNonOfficialPosts(@RequestBody Pages pages) {
return postService.getNonOfficialPosts(pages.getPageNum(), pages.getPageSize());
}
@PutMapping("/changePublic")
@Operation(summary = "修改帖子公开状态")
public Result changePublic(@RequestParam Long postId, @RequestParam Integer isPublic) {
String userId = StpUtil.getLoginIdAsString(); // 获取当前登录用户的ID
logger.info("用户ID{}开始修改帖子ID{}的公开状态", userId, postId);
@@ -164,4 +180,130 @@ public class PostController {
logger.info("用户ID{}的帖子ID{}修改成功", userId, postId);
return Result.ok();
}
@GetMapping("/popularSearches")
@Operation(summary = "获取热门搜索词")
public Result getPopularSearches() {
List<String> popularSearches = postService.getPopularSearches();
return Result.ok(popularSearches);
}
@PostMapping("/searchHistory")
@Operation(summary = "保存搜索历史")
public Result saveSearchHistory(@RequestParam String keyword) {
String userId = StpUtil.getLoginIdAsString();
String key = "search_history:" + userId;
// 保存搜索历史到 Redis 中
redisTemplate.opsForList().rightPush(key, keyword);
// 如果列表长度超过 10 条,删除最早的记录
Long listSize = redisTemplate.opsForList().size(key);
if (listSize != null && listSize > 10) {
redisTemplate.opsForList().leftPop(key); // 删除最早的记录
}
return Result.ok("搜索历史保存成功");
}
/**
* 获取用户的搜索历史
*/
@GetMapping("/searchHistory")
@Operation(summary = "获取用户的搜索历史")
public Result getSearchHistory() {
String userId = StpUtil.getLoginIdAsString();
String key = "search_history:" + userId;
// 从 Redis 中获取搜索历史
List<String> history = redisTemplate.opsForList().range(key, 0, -1);
return Result.ok(history);
}
/**
* 根据关键字搜索帖子,包括标题和内容
*/
@GetMapping("/search")
@Operation(summary = "根据关键字搜索帖子")
public Result searchPosts(@RequestParam String keyword) {
// 保存用户搜索历史
saveSearchHistory(keyword);
// 调用服务层方法进行帖子搜索
List<Post> posts = postService.searchPosts(keyword);
return Result.ok(posts);
}
@GetMapping("/topFavorited")
@Operation(summary = "获取用户收藏数量较高的帖子")
public Result getTopFavoritedPosts(@RequestParam(defaultValue = "10") int limit) {
List<Post> topFavoritedPosts = postService.getTopFavoritedPosts(limit);
return Result.ok(topFavoritedPosts);
}
@PostMapping("/saveDraft")
@Operation(summary = "暂存帖子草稿")
public Result saveDraft(@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("communityId") Long communityId,
@RequestParam(value = "imageFiles", required = false) MultipartFile[] imageFiles,
@RequestParam(value = "videoFile", required = false) MultipartFile videoFile,
@RequestParam(value = "location", required = false) String location) {
String userId = StpUtil.getLoginIdAsString();
logger.info("用户ID{} 开始暂存帖子草稿", userId);
Post post = new Post();
post.setUserOpenid(userId);
post.setTitle(title);
post.setContent(content);
post.setCommunityId(communityId);
post.setIsDraft(0); // 0 表示草稿
post.setLocation(location);
try {
// 上传视频
if (videoFile != null && !videoFile.isEmpty()) {
String uploadResult = fileService.uploadMinio(videoFile);
post.setVideoUrl(uploadResult);
}
// 上传图片
if (imageFiles != null && imageFiles.length > 0) {
StringBuilder imageUrls = new StringBuilder();
for (MultipartFile file : imageFiles) {
String uploadResult = fileService.uploadMinio(file);
imageUrls.append(uploadResult).append(";");
}
post.setImageUrls(imageUrls.toString());
}
} catch (Exception e) {
logger.error("文件上传失败", e);
return Result.error("文件上传失败");
}
postService.createPost(post); // 保存草稿
logger.info("用户ID{} 的帖子草稿暂存成功", userId);
return Result.ok(post);
}
@GetMapping("/getDrafts")
@Operation(summary = "获取用户的所有草稿")
public Result getDrafts() {
String userId = StpUtil.getLoginIdAsString();
logger.info("用户ID{} 开始获取草稿", userId);
List<Post> drafts = postService.getDraftsByUserId(userId);
if (drafts.isEmpty()) {
return Result.error("未找到任何草稿");
}
return Result.ok(drafts);
}
}

View File

@@ -6,6 +6,7 @@ import com.ivmiku.tutorial.entity.PostTag;
import com.ivmiku.tutorial.entity.Tag;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.PostTagService;
import io.swagger.v3.oas.annotations.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +25,7 @@ public class PostTagController {
private PostTagService postTagService;
@PostMapping("/create")
@Operation(summary = "创建帖子标签")
public Result createPostTag(@RequestBody PostTag postTag) {
logger.info("开始创建帖子标签");
postTagService.createPostTag(postTag);
@@ -32,6 +34,7 @@ public class PostTagController {
}
@GetMapping("/get/{id}")
@Operation(summary = "获取帖子标签详细信息")
public Result getPostTag(@PathVariable Long id) {
logger.info("开始获取帖子标签ID{}的详细信息", id);
PostTag postTag = postTagService.getPostTagById(id);
@@ -44,6 +47,7 @@ public class PostTagController {
}
@PutMapping("/update/{id}")
@Operation(summary = "更新帖子标签")
public Result updatePostTag(@PathVariable Long id, @RequestBody PostTag postTag) {
logger.info("开始更新帖子标签ID{}", id);
postTagService.updatePostTag(id, postTag);
@@ -52,6 +56,7 @@ public class PostTagController {
}
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除帖子标签")
public Result deletePostTag(@PathVariable Long id) {
logger.info("开始删除帖子标签ID{}", id);
postTagService.deletePostTag(id);
@@ -60,6 +65,7 @@ public class PostTagController {
}
@GetMapping("/getPostTagList/{postId}")
@Operation(summary = "获取帖子附带的标签列表")
public Result getPostTagList(@PathVariable Long postId) {
logger.info("开始获取帖子标签列表");
List<Tag> tags = postTagService.getPostTagList(postId);
@@ -67,6 +73,7 @@ public class PostTagController {
}
@GetMapping("/getTagPostList/{tagId}")
@Operation(summary = "获取标签附带的帖子列表")
public Result getTagPostList(@PathVariable Long tagId) {
logger.info("开始获取标签帖子列表");
List<Post> posts = postTagService.getTagPostList(tagId);
@@ -74,6 +81,7 @@ public class PostTagController {
}
@GetMapping("/topTags")
@Operation(summary = "获取使用次数最多的标签")
public Result getTopTags(@RequestParam(defaultValue = "10") int topN) {
logger.info("开始获取前{}个使用次数最多的标签", topN);
List<String> tags = postTagService.getTopTags(topN);

View File

@@ -5,6 +5,7 @@ import com.ivmiku.tutorial.entity.Tag;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.PostTagService;
import com.ivmiku.tutorial.service.TagService;
import io.swagger.v3.oas.annotations.Operation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +35,7 @@ public class TagController {
* @return Result 返回操作结果
*/
@PostMapping("/create")
@Operation(summary = "创建标签")
public Result createTag(@RequestBody Tag tag) {
logger.info("开始创建标签:{}", tag.getName());
tagService.createTag(tag);
@@ -49,6 +51,7 @@ public class TagController {
* @return Result 返回操作结果和标签详情
*/
@GetMapping("/get/{id}")
@Operation(summary = "获取标签详情")
public Result getTag(@PathVariable Long id) {
logger.info("开始获取标签ID{}的详细信息", id);
Tag tag = tagService.getTagById(id);
@@ -69,6 +72,7 @@ public class TagController {
* @return Result 返回操作结果
*/
@PutMapping("/update/{id}")
@Operation(summary = "更新标签")
public Result updateTag(@PathVariable Long id, @RequestBody Tag tag) {
logger.info("开始更新标签ID{}的信息", id);
tagService.updateTag(id, tag);
@@ -84,6 +88,7 @@ public class TagController {
* @return Result 返回操作结果
*/
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除标签")
public Result deleteTag(@PathVariable Long id) {
logger.info("开始删除标签ID{}", id);
tagService.deleteTag(id);
@@ -97,6 +102,7 @@ public class TagController {
* @return Result 返回操作结果和标签详情
*/
@GetMapping("/getTagList")
@Operation(summary = "获取所有标签详情")
public Result getTagList() {
List<Tag> tags = tagService.getTagList();
return Result.ok(tags);
@@ -107,6 +113,7 @@ public class TagController {
* @return Result 返回操作结果和排序后的标签列表
*/
@GetMapping("/sorted-tag-list")
@Operation(summary = "获取排序后的标签列表")
public Result getSortedTagList() {
logger.info("开始获取排序后的标签列表");
List<Tag> tags = postTagService.getSortedTagList();

View File

@@ -0,0 +1,126 @@
package com.ivmiku.tutorial.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.ivmiku.tutorial.entity.Tutorials;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.FileService;
import com.ivmiku.tutorial.service.TutorialsService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@RestController
@RequestMapping("/tutorial")
@Slf4j
public class TutorialController {
private static final Logger logger = LoggerFactory.getLogger(TutorialController.class);
@Autowired
private TutorialsService tutorialsService;
@Resource
private FileService fileService;
@PostMapping("/create")
@Operation(summary = "创建教程")
public Result createTutorial(@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("tagId") Long tagId,
@RequestParam(value = "imageFile", required = false) MultipartFile imageFile,
@RequestParam(value = "videoFile", required = false) MultipartFile videoFile,
@RequestParam("isOfficial") Integer isOfficial) {
String userId = StpUtil.getLoginIdAsString(); // 获取 userOpenid
logger.info("用户ID{} 开始创建教程", userId);
Tutorials tutorial = new Tutorials();
tutorial.setTitle(title);
tutorial.setContent(content);
tutorial.setTagId(tagId);
tutorial.setIsOfficial(isOfficial);
tutorial.setUserOpenid(userId); // 设置 userOpenid
try {
// 上传图片
if (imageFile != null && !imageFile.isEmpty()) {
String uploadResult = fileService.uploadMinio(imageFile);
tutorial.setImageUrl(uploadResult);
}
// 上传视频
if (videoFile != null && !videoFile.isEmpty()) {
String uploadResult = fileService.uploadMinio(videoFile);
tutorial.setVideoUrl(uploadResult);
}
} catch (Exception e) {
logger.error("文件上传失败", e);
return Result.error("文件上传失败");
}
tutorialsService.createTutorial(tutorial);
logger.info("用户ID{} 的教程创建成功", userId);
return Result.ok(tutorial);
}
// 获取教程详细信息
@GetMapping("/get/{id}")
@Operation(summary = "获取教程详细信息")
public Result getTutorial(@PathVariable Long id) {
Tutorials tutorial = tutorialsService.getById(id);
if (tutorial != null) {
return Result.ok("教程获取成功");
}
return Result.error("未找到教程");
}
// 更新教程
@PutMapping("/update/{id}")
@Operation(summary = "更新教程")
public Result updateTutorial(@PathVariable Long id, @RequestBody Tutorials tutorial) {
tutorial.setTutorialId(id); // 确保教程ID是正确的
boolean updated = tutorialsService.updateById(tutorial);
if (updated) {
return Result.ok("教程更新成功");
}
return Result.error("教程更新失败");
}
// 删除教程
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除教程")
public Result deleteTutorial(@PathVariable Long id) {
boolean deleted = tutorialsService.removeById(id);
if (deleted) {
return Result.ok("教程删除成功");
}
return Result.error("教程删除失败");
}
// 获取所有教程
@GetMapping("/list")
@Operation(summary = "获取所有教程")
public Result listTutorials() {
List<Tutorials> tutorials = tutorialsService.list();
return Result.ok("教程列表获取成功");
}
// 根据教程标签ID获取教程列表
@GetMapping("/listByTag/{tagId}")
@Operation(summary = "根据教程标签ID获取教程列表")
public Result listTutorialsByTag(@PathVariable Long tagId) {
List<Tutorials> tutorials = tutorialsService.getTutorialsByTagId(tagId);
if (tutorials.isEmpty()) {
return Result.error("未找到对应标签的教程");
}
return Result.ok(tutorials);
}
}

View File

@@ -0,0 +1,61 @@
package com.ivmiku.tutorial.controller;
import com.ivmiku.tutorial.entity.TutorialTags;
import com.ivmiku.tutorial.response.Result;
import com.ivmiku.tutorial.service.TutorialTagsService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/tutorialTags")
public class TutorialTagsController {
@Autowired
private TutorialTagsService tutorialTagsService;
@PostMapping("/create")
@Operation(summary = "创建教程标签")
public Result createTag(@RequestParam("tagName") String tagName,
@RequestParam("isOfficial") Integer isOfficial) {
TutorialTags tag = new TutorialTags();
tag.setTagName(tagName);
tag.setIsOfficial(isOfficial);
tutorialTagsService.createTag(tag);
return Result.ok(tag);
}
@GetMapping("/getAll")
@Operation(summary = "获取所有教程标签")
public Result getAllTags() {
List<TutorialTags> tags = tutorialTagsService.getAllTags();
return Result.ok(tags);
}
@PutMapping("/update")
@Operation(summary = "更新教程标签")
public Result updateTag(@RequestParam("tagId") Long tagId,
@RequestParam("tagName") String tagName,
@RequestParam("isOfficial") Integer isOfficial) {
TutorialTags tag = tutorialTagsService.getTagById(tagId);
if (tag == null) {
return Result.error("标签不存在");
}
tag.setTagName(tagName);
tag.setIsOfficial(isOfficial);
tutorialTagsService.updateTag(tag);
return Result.ok(tag);
}
@DeleteMapping("/delete")
@Operation(summary = "删除教程标签")
public Result deleteTag(@RequestParam("tagId") Long tagId) {
tutorialTagsService.deleteTag(tagId);
return Result.ok("标签已删除");
}
}

View File

@@ -37,6 +37,8 @@ public class Post implements Serializable {
private String location; // 存储帖子位置信息
private Integer isDraft; // 是否为草稿 0不是 1是
private Date createdAt;
private Date updatedAt;

View File

@@ -0,0 +1,25 @@
package com.ivmiku.tutorial.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import lombok.Data;
/**
* @TableName tutorial_tags
*/
@TableName(value ="tutorial_tags")
@Data
public class TutorialTags implements Serializable {
@TableId(type = IdType.AUTO)
private Long tagId;
private String tagName;
private Integer isOfficial;
@TableLogic
private Integer isDeleted;
private static final long serialVersionUID = 1L;
}

View File

@@ -0,0 +1,38 @@
package com.ivmiku.tutorial.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* @TableName tutorials
*/
@TableName(value ="tutorials")
@Data
public class Tutorials implements Serializable {
@TableId(type = IdType.AUTO)
private Long tutorialId;
private String title;
private String content;
private String imageUrl;
private String videoUrl;
private Integer isOfficial;
@TableLogic
private Integer isDeleted;
private Date createdAt;
private Long tagId;
private String userOpenid; // 新增的字段
private static final long serialVersionUID = 1L;
}

View File

@@ -17,6 +17,12 @@ public interface PostMapper extends BaseMapper<Post> {
List<Post> getTagPostList(Long tagId);
List<String> selectPopularSearches();
List<Post> searchPosts(String keyword);
List<Post> getTopFavoritedPosts(int limit);
}

View File

@@ -0,0 +1,18 @@
package com.ivmiku.tutorial.mapper;
import com.ivmiku.tutorial.entity.TutorialTags;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author rog
* @description 针对表【tutorial_tags】的数据库操作Mapper
* @createDate 2024-08-29 21:15:08
* @Entity com.ivmiku.tutorial.entity.TutorialTags
*/
public interface TutorialTagsMapper extends BaseMapper<TutorialTags> {
}

View File

@@ -0,0 +1,18 @@
package com.ivmiku.tutorial.mapper;
import com.ivmiku.tutorial.entity.Tutorials;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author rog
* @description 针对表【tutorials】的数据库操作Mapper
* @createDate 2024-08-29 21:14:50
* @Entity com.ivmiku.tutorial.entity.Tutorials
*/
public interface TutorialsMapper extends BaseMapper<Tutorials> {
}

View File

@@ -23,4 +23,12 @@ public interface PostService extends IService<Post> {
IPage<Post> getNonOfficialPosts(int pageNum, int pageSize);
void changePublic(Long postId, Integer isPublic);
List<String> getPopularSearches();
List<Post> searchPosts(String keyword);
List<Post> getTopFavoritedPosts(int limit);
List<Post> getDraftsByUserId(String userId);
}

View File

@@ -0,0 +1,25 @@
package com.ivmiku.tutorial.service;
import com.ivmiku.tutorial.entity.TutorialTags;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author rog
* @description 针对表【tutorial_tags】的数据库操作Service
* @createDate 2024-08-29 21:15:08
*/
public interface TutorialTagsService extends IService<TutorialTags> {
void createTag(TutorialTags tag);
List<TutorialTags> getAllTags();
TutorialTags getTagById(Long tagId);
void updateTag(TutorialTags tag);
void deleteTag(Long tagId);
}

View File

@@ -0,0 +1,18 @@
package com.ivmiku.tutorial.service;
import com.ivmiku.tutorial.entity.Tutorials;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author rog
* @description 针对表【tutorials】的数据库操作Service
* @createDate 2024-08-29 21:14:50
*/
public interface TutorialsService extends IService<Tutorials> {
void createTutorial(Tutorials tutorial);
List<Tutorials> getTutorialsByTagId(Long tagId);
}

View File

@@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {
@@ -170,4 +171,31 @@ public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements Po
post.setIsPublic(isPublic);
postMapper.update(post, wrapper);
}
@Override
public List<String> getPopularSearches() {
return postMapper.selectPopularSearches();
}
@Override
public List<Post> searchPosts(String keyword) {
// 调用 Mapper 中的搜索方法
return postMapper.searchPosts(keyword);
}
@Override
public List<Post> getTopFavoritedPosts(int limit) {
return postMapper.getTopFavoritedPosts(limit);
}
@Override
public List<Post> getDraftsByUserId(String userId) {
return postMapper.selectList(new LambdaQueryWrapper<Post>()
.eq(Post::getUserOpenid, userId)
.eq(Post::getIsDraft, 0)); // 0 表示草稿
}
}

View File

@@ -0,0 +1,56 @@
package com.ivmiku.tutorial.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ivmiku.tutorial.entity.TutorialTags;
import com.ivmiku.tutorial.service.TutorialTagsService;
import com.ivmiku.tutorial.mapper.TutorialTagsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author rog
* @description 针对表【tutorial_tags】的数据库操作Service实现
* @createDate 2024-08-29 21:15:08
*/
@Service
public class TutorialTagsServiceImpl extends ServiceImpl<TutorialTagsMapper, TutorialTags>
implements TutorialTagsService{
@Autowired
private TutorialTagsMapper tutorialTagsMapper;
@Override
public void createTag(TutorialTags tag) {
tutorialTagsMapper.insert(tag);
}
@Override
public List<TutorialTags> getAllTags() {
QueryWrapper<TutorialTags> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("is_deleted", 0);
return tutorialTagsMapper.selectList(queryWrapper);
}
@Override
public TutorialTags getTagById(Long tagId) {
return tutorialTagsMapper.selectById(tagId);
}
@Override
public void updateTag(TutorialTags tag) {
tutorialTagsMapper.updateById(tag);
}
@Override
public void deleteTag(Long tagId) {
tutorialTagsMapper.deleteById(tagId);
}
}

View File

@@ -0,0 +1,43 @@
package com.ivmiku.tutorial.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ivmiku.tutorial.entity.Tutorials;
import com.ivmiku.tutorial.service.TutorialsService;
import com.ivmiku.tutorial.mapper.TutorialsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author rog
* @description 针对表【tutorials】的数据库操作Service实现
* @createDate 2024-08-29 21:14:50
*/
@Service
public class TutorialsServiceImpl extends ServiceImpl<TutorialsMapper, Tutorials>
implements TutorialsService{
@Autowired
private TutorialsMapper tutorialsMapper;
// 其他已存在的方法
@Override
public List<Tutorials> getTutorialsByTagId(Long tagId) {
QueryWrapper<Tutorials> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("tag_id", tagId);
return tutorialsMapper.selectList(queryWrapper);
}
@Override
public void createTutorial(Tutorials tutorial) {
this.save(tutorial);
}
}

View File

@@ -16,6 +16,7 @@
<result property="isOfficial" column="is_official" jdbcType="TINYINT"/>
<result property="isPublic" column="is_public" jdbcType="TINYINT"/>
<result property="location" column="location" jdbcType="VARCHAR"/>
<result property="isDraft" column="is_draft" jdbcType="TINYINT"/>
<result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
<result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
</resultMap>
@@ -37,32 +38,33 @@
<!-- 插入新的帖子 -->
<insert id="insertPost" parameterType="com.ivmiku.tutorial.entity.Post">
INSERT INTO post (
post_id, user_openid, community_id, title, content,
video_url, image_urls,
is_deleted, is_official, is_public, location, created_at, updated_at
post_id, user_openid, community_id, title, content,
video_url, image_urls,
is_deleted, is_official, is_public, location, is_draft, created_at, updated_at
) VALUES (
#{postId}, #{userOpenid}, #{communityId}, #{title}, #{content},
#{videoUrl}, #{imageUrls},
#{isDeleted}, #{isOfficial}, #{is_public}, #{location}, #{createdAt}, #{updatedAt}
)
#{postId}, #{userOpenid}, #{communityId}, #{title}, #{content},
#{videoUrl}, #{imageUrls},
#{isDeleted}, #{isOfficial}, #{isPublic}, #{location}, #{isDraft}, #{createdAt}, #{updatedAt}
)
</insert>
<!-- 更新帖子 -->
<update id="updatePost" parameterType="com.ivmiku.tutorial.entity.Post">
UPDATE post
SET
user_openid = #{userOpenid},
community_id = #{communityId},
title = #{title},
content = #{content},
video_url = #{videoUrl},
image_urls = #{imageUrls},
is_deleted = #{isDeleted},
is_official = #{isOfficial},
is_public = #{is_public},
location = #{location},
created_at = #{createdAt},
updated_at = #{updatedAt}
user_openid = #{userOpenid},
community_id = #{communityId},
title = #{title},
content = #{content},
video_url = #{videoUrl},
image_urls = #{imageUrls},
is_deleted = #{isDeleted},
is_official = #{isOfficial},
is_public = #{isPublic},
location = #{location},
is_draft = #{isDraft},
created_at = #{createdAt},
updated_at = #{updatedAt}
WHERE post_id = #{postId}
</update>
@@ -80,5 +82,31 @@
FROM post p, posttag pt, tag t
WHERE p.post_id = pt.post_id AND pt.tag_id = t.tag_id AND t.tag_id = #{tagId} AND p.is_deleted = 0 AND p.is_public = 1
</select>
<select id="selectPopularSearches" resultType="java.lang.String">
SELECT title
FROM post
WHERE is_deleted = 0 AND is_public = 1
ORDER BY view_count DESC, like_count DESC
LIMIT 9
</select>
<select id="searchPosts" resultType="com.ivmiku.tutorial.entity.Post">
SELECT
<include refid="Base_Column_List"/>
FROM post
WHERE is_deleted = 0
AND is_public = 1
AND (title LIKE CONCAT('%', #{keyword}, '%')
OR content LIKE CONCAT('%', #{keyword}, '%'))
</select>
<select id="getTopFavoritedPosts" resultType="com.ivmiku.tutorial.entity.Post">
SELECT p.post_id, p.user_openid, p.community_id, p.title, p.content,
p.is_deleted, p.is_official, p.is_public, p.location, p.created_at, p.updated_at
FROM post p
JOIN favorite f ON p.post_id = f.post_id
WHERE p.is_deleted = 0 AND p.is_public = 1 AND f.is_deleted = 0
GROUP BY p.post_id
ORDER BY COUNT(f.id) DESC
LIMIT #{limit}
</select>
</mapper>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ivmiku.tutorial.mapper.TutorialTagsMapper">
<resultMap id="BaseResultMap" type="com.ivmiku.tutorial.entity.TutorialTags">
<id property="tagId" column="tag_id" jdbcType="BIGINT"/>
<result property="tagName" column="tag_name" jdbcType="VARCHAR"/>
<result property="isOfficial" column="is_official" jdbcType="TINYINT"/>
<result property="isDeleted" column="is_deleted" jdbcType="TINYINT"/>
</resultMap>
<sql id="Base_Column_List">
tag_id,tag_name,is_official,
is_deleted
</sql>
</mapper>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ivmiku.tutorial.mapper.TutorialsMapper">
<resultMap id="BaseResultMap" type="com.ivmiku.tutorial.entity.Tutorials">
<id column="tutorial_id" property="tutorialId" jdbcType="BIGINT"/>
<result column="title" property="title" jdbcType="VARCHAR"/>
<result column="content" property="content" jdbcType="VARCHAR"/>
<result column="image_url" property="imageUrl" jdbcType="VARCHAR"/>
<result column="video_url" property="videoUrl" jdbcType="VARCHAR"/>
<result column="is_official" property="isOfficial" jdbcType="INTEGER"/>
<result column="is_deleted" property="isDeleted" jdbcType="INTEGER"/>
<result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
<result column="tag_id" property="tagId" jdbcType="BIGINT"/>
<result column="user_openid" property="userOpenid" jdbcType="VARCHAR"/> <!-- 新增的映射 -->
</resultMap>
<sql id="Base_Column_List">
tutorial_id,title,content,
image_url,video_url,is_official,
is_deleted,created_at,tag_id
</sql>
</mapper>