forked from iVMiku/guidance-backend
main #2
2
.idea/encodings.xml
generated
2
.idea/encodings.xml
generated
@@ -7,6 +7,8 @@
|
|||||||
<file url="file://$PROJECT_DIR$/community-8073/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/community-8073/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/gateway-8133/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/gateway-8133/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/gateway-8133/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/gateway-8133/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/navigate-8432/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/navigate-8432/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/user-8072/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/user-8072/src/main/java" charset="UTF-8" />
|
||||||
|
|||||||
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -5,10 +5,11 @@
|
|||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
<list>
|
<list>
|
||||||
<option value="$PROJECT_DIR$/pom.xml" />
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
<option value="$PROJECT_DIR$/navigate-8432/pom.xml" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -24,6 +24,17 @@
|
|||||||
<!-- <artifactId>springfox-boot-starter</artifactId>-->
|
<!-- <artifactId>springfox-boot-starter</artifactId>-->
|
||||||
<!-- <version>3.0.0</version>-->
|
<!-- <version>3.0.0</version>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
|
<!-- 集成redis依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||||
|
<version>1.28.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.minio</groupId>
|
<groupId>io.minio</groupId>
|
||||||
<artifactId>minio</artifactId>
|
<artifactId>minio</artifactId>
|
||||||
@@ -76,11 +87,11 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
<!-- <!– Sa-Token 权限认证,在线文档:https://sa-token.cc –>-->
|
||||||
<dependency>
|
<!-- <dependency>-->
|
||||||
<groupId>cn.dev33</groupId>
|
<!-- <groupId>cn.dev33</groupId>-->
|
||||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
<!-- <artifactId>sa-token-spring-boot3-starter</artifactId>-->
|
||||||
</dependency>
|
<!-- </dependency>-->
|
||||||
<!-- fastjson2 -->
|
<!-- fastjson2 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.fastjson2</groupId>
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
@@ -157,7 +168,7 @@
|
|||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<version>3.0.13</version>
|
<version>3.0.13</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>com.ivmiku.tutorial.Main8072</mainClass>
|
<mainClass>com.ivmiku.tutorial.Main8073</mainClass>
|
||||||
<layout>JAR</layout>
|
<layout>JAR</layout>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.ivmiku.tutorial.entity.Comment;
|
import com.ivmiku.tutorial.entity.Comment;
|
||||||
import com.ivmiku.tutorial.response.Result;
|
import com.ivmiku.tutorial.response.Result;
|
||||||
@@ -19,6 +20,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/comments")
|
@RequestMapping("/comments")
|
||||||
|
@SaCheckLogin
|
||||||
public class CommentController {
|
public class CommentController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CommentController.class);
|
private static final Logger logger = LoggerFactory.getLogger(CommentController.class);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import com.ivmiku.tutorial.entity.Community;
|
import com.ivmiku.tutorial.entity.Community;
|
||||||
import com.ivmiku.tutorial.response.Result;
|
import com.ivmiku.tutorial.response.Result;
|
||||||
import com.ivmiku.tutorial.service.CommunityService;
|
import com.ivmiku.tutorial.service.CommunityService;
|
||||||
@@ -18,7 +19,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/communities")
|
@RequestMapping("/communities")
|
||||||
|
@SaCheckLogin
|
||||||
public class CommunityController {
|
public class CommunityController {
|
||||||
|
|
||||||
// 使用SLF4J的LoggerFactory来创建一个日志记录器
|
// 使用SLF4J的LoggerFactory来创建一个日志记录器
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.ivmiku.tutorial.response.Result;
|
import com.ivmiku.tutorial.response.Result;
|
||||||
import com.ivmiku.tutorial.service.InteractionService;
|
import com.ivmiku.tutorial.service.InteractionService;
|
||||||
@@ -14,6 +15,7 @@ import javax.annotation.Resource;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/interaction")
|
@RequestMapping("/interaction")
|
||||||
|
@SaCheckLogin
|
||||||
public class InteractionController {
|
public class InteractionController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.ivmiku.tutorial.entity.Post;
|
import com.ivmiku.tutorial.entity.Post;
|
||||||
import com.ivmiku.tutorial.response.Result;
|
import com.ivmiku.tutorial.response.Result;
|
||||||
@@ -19,6 +20,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/post")
|
@RequestMapping("/post")
|
||||||
|
@SaCheckLogin
|
||||||
public class PostController {
|
public class PostController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PostController.class);
|
private static final Logger logger = LoggerFactory.getLogger(PostController.class);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import com.ivmiku.tutorial.entity.Post;
|
import com.ivmiku.tutorial.entity.Post;
|
||||||
import com.ivmiku.tutorial.entity.PostTag;
|
import com.ivmiku.tutorial.entity.PostTag;
|
||||||
import com.ivmiku.tutorial.entity.Tag;
|
import com.ivmiku.tutorial.entity.Tag;
|
||||||
@@ -14,22 +15,14 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/post-tag")
|
@RequestMapping("/post-tag")
|
||||||
|
@SaCheckLogin
|
||||||
public class PostTagController {
|
public class PostTagController {
|
||||||
|
|
||||||
// 日志记录器,用于记录控制器中的日志信息
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PostTagController.class);
|
private static final Logger logger = LoggerFactory.getLogger(PostTagController.class);
|
||||||
|
|
||||||
// 通过@Autowired注解自动装配PostTagService服务
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PostTagService postTagService;
|
private PostTagService postTagService;
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建帖子标签接口。
|
|
||||||
* 用户通过POST请求提交帖子标签数据,服务端接收并保存帖子标签。
|
|
||||||
*
|
|
||||||
* @param postTag 提交的帖子标签数据
|
|
||||||
* @return Result 返回操作结果
|
|
||||||
*/
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
public Result createPostTag(@RequestBody PostTag postTag) {
|
public Result createPostTag(@RequestBody PostTag postTag) {
|
||||||
logger.info("开始创建帖子标签");
|
logger.info("开始创建帖子标签");
|
||||||
@@ -38,13 +31,6 @@ public class PostTagController {
|
|||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取帖子标签详情接口。
|
|
||||||
* 根据帖子标签ID获取帖子标签的详细信息。
|
|
||||||
*
|
|
||||||
* @param id 帖子标签的唯一标识ID
|
|
||||||
* @return Result 返回操作结果和帖子标签详情
|
|
||||||
*/
|
|
||||||
@GetMapping("/get/{id}")
|
@GetMapping("/get/{id}")
|
||||||
public Result getPostTag(@PathVariable Long id) {
|
public Result getPostTag(@PathVariable Long id) {
|
||||||
logger.info("开始获取帖子标签ID:{}的详细信息", id);
|
logger.info("开始获取帖子标签ID:{}的详细信息", id);
|
||||||
@@ -57,14 +43,6 @@ public class PostTagController {
|
|||||||
return Result.ok(postTag);
|
return Result.ok(postTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新帖子标签接口。
|
|
||||||
* 用户通过PUT请求提交更新后的帖子标签数据,服务端接收并更新帖子标签。
|
|
||||||
*
|
|
||||||
* @param id 要更新的帖子标签的唯一标识ID
|
|
||||||
* @param postTag 更新后的帖子标签数据
|
|
||||||
* @return Result 返回操作结果
|
|
||||||
*/
|
|
||||||
@PutMapping("/update/{id}")
|
@PutMapping("/update/{id}")
|
||||||
public Result updatePostTag(@PathVariable Long id, @RequestBody PostTag postTag) {
|
public Result updatePostTag(@PathVariable Long id, @RequestBody PostTag postTag) {
|
||||||
logger.info("开始更新帖子标签ID:{}", id);
|
logger.info("开始更新帖子标签ID:{}", id);
|
||||||
@@ -73,13 +51,6 @@ public class PostTagController {
|
|||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除帖子标签接口。
|
|
||||||
* 根据帖子标签ID删除指定的帖子标签。
|
|
||||||
*
|
|
||||||
* @param id 要删除的帖子标签的唯一标识ID
|
|
||||||
* @return Result 返回操作结果
|
|
||||||
*/
|
|
||||||
@DeleteMapping("/delete/{id}")
|
@DeleteMapping("/delete/{id}")
|
||||||
public Result deletePostTag(@PathVariable Long id) {
|
public Result deletePostTag(@PathVariable Long id) {
|
||||||
logger.info("开始删除帖子标签ID:{}", id);
|
logger.info("开始删除帖子标签ID:{}", id);
|
||||||
@@ -88,25 +59,24 @@ public class PostTagController {
|
|||||||
return Result.ok();
|
return Result.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@GetMapping("/getPostTagList/{postId}")
|
||||||
* 获取当前帖子所有标签列表接口。
|
public Result getPostTagList(@PathVariable Long postId) {
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GetMapping("/getPostTagList{postId}")
|
|
||||||
public Result getPostTagList(@PathVariable("postId") Long postId) {
|
|
||||||
logger.info("开始获取帖子标签列表");
|
logger.info("开始获取帖子标签列表");
|
||||||
List<Tag> tags = postTagService.getPostTagList(postId);
|
List<Tag> tags = postTagService.getPostTagList(postId);
|
||||||
return Result.ok(tags);
|
return Result.ok(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@GetMapping("/getTagPostList/{tagId}")
|
||||||
* 获取当前标签所有帖子列表接口。
|
public Result getTagPostList(@PathVariable Long tagId) {
|
||||||
* @return
|
logger.info("开始获取标签帖子列表");
|
||||||
*/
|
|
||||||
@GetMapping("/getTagPostList{tagId}")
|
|
||||||
public Result getTagPostList(@PathVariable("tagId") Long tagId) {
|
|
||||||
logger.info("开始获取帖子标签列表");
|
|
||||||
List<Post> posts = postTagService.getTagPostList(tagId);
|
List<Post> posts = postTagService.getTagPostList(tagId);
|
||||||
return Result.ok(posts);
|
return Result.ok(posts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/topTags")
|
||||||
|
public Result getTopTags(@RequestParam(defaultValue = "10") int topN) {
|
||||||
|
logger.info("开始获取前{}个使用次数最多的标签", topN);
|
||||||
|
List<String> tags = postTagService.getTopTags(topN);
|
||||||
|
return Result.ok(tags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ivmiku.tutorial.controller;
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
import com.ivmiku.tutorial.entity.Tag;
|
import com.ivmiku.tutorial.entity.Tag;
|
||||||
import com.ivmiku.tutorial.response.Result;
|
import com.ivmiku.tutorial.response.Result;
|
||||||
import com.ivmiku.tutorial.service.PostTagService;
|
import com.ivmiku.tutorial.service.PostTagService;
|
||||||
@@ -13,12 +14,12 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/tag")
|
@RequestMapping("/tag")
|
||||||
|
@SaCheckLogin
|
||||||
public class TagController {
|
public class TagController {
|
||||||
|
|
||||||
// 日志记录器,用于记录控制器中的日志信息
|
// 日志记录器,用于记录控制器中的日志信息
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TagController.class);
|
private static final Logger logger = LoggerFactory.getLogger(TagController.class);
|
||||||
|
|
||||||
// 通过@Autowired注解自动装配TagService服务
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TagService tagService;
|
private TagService tagService;
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,6 @@ public interface PostTagService extends IService<PostTag> {
|
|||||||
List<Post> getTagPostList(Long tagId);
|
List<Post> getTagPostList(Long tagId);
|
||||||
|
|
||||||
List<Tag> getSortedTagList();
|
List<Tag> getSortedTagList();
|
||||||
|
|
||||||
|
List<String> getTopTags(int topN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 帖子标签服务实现类。
|
* 帖子标签服务实现类。
|
||||||
@@ -21,7 +24,6 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
public class PostTagServiceImpl extends ServiceImpl<PostTagMapper, PostTag> implements PostTagService {
|
public class PostTagServiceImpl extends ServiceImpl<PostTagMapper, PostTag> implements PostTagService {
|
||||||
|
|
||||||
// 日志记录器,用于记录服务层的日志信息
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PostTagServiceImpl.class);
|
private static final Logger logger = LoggerFactory.getLogger(PostTagServiceImpl.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -33,39 +35,26 @@ public class PostTagServiceImpl extends ServiceImpl<PostTagMapper, PostTag> impl
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PostTagMapper postTagMapper;
|
private PostTagMapper postTagMapper;
|
||||||
|
|
||||||
/**
|
@Autowired
|
||||||
* 创建帖子标签。
|
private StringRedisTemplate redisTemplate;
|
||||||
* 将帖子标签数据保存到数据库。
|
|
||||||
*
|
private static final String TAG_KEY = "tags";
|
||||||
* @param postTag 要保存的帖子标签数据
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void createPostTag(PostTag postTag) {
|
public void createPostTag(PostTag postTag) {
|
||||||
logger.info("开始创建帖子标签");
|
logger.info("开始创建帖子标签");
|
||||||
save(postTag);
|
save(postTag);
|
||||||
|
// 更新标签的使用次数
|
||||||
|
redisTemplate.opsForZSet().incrementScore(TAG_KEY, postTag.getTagId().toString(), 1);
|
||||||
logger.info("帖子标签创建成功,标签ID:{}", postTag.getPostTagId());
|
logger.info("帖子标签创建成功,标签ID:{}", postTag.getPostTagId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ID获取帖子标签详情。
|
|
||||||
* 从数据库中根据帖子标签ID获取帖子标签的详细信息。
|
|
||||||
*
|
|
||||||
* @param postTagId 帖子标签的唯一标识ID
|
|
||||||
* @return PostTag 返回查询到的帖子标签对象
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public PostTag getPostTagById(Long postTagId) {
|
public PostTag getPostTagById(Long postTagId) {
|
||||||
logger.info("开始根据ID获取帖子标签详情,标签ID:{}", postTagId);
|
logger.info("开始根据ID获取帖子标签详情,标签ID:{}", postTagId);
|
||||||
return getById(postTagId);
|
return getById(postTagId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新帖子标签。
|
|
||||||
* 根据帖子标签ID更新帖子标签的内容。
|
|
||||||
*
|
|
||||||
* @param postTagId 要更新的帖子标签的唯一标识ID
|
|
||||||
* @param postTag 更新后的帖子标签数据
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePostTag(Long postTagId, PostTag postTag) {
|
public void updatePostTag(Long postTagId, PostTag postTag) {
|
||||||
logger.info("开始更新帖子标签,标签ID:{}", postTagId);
|
logger.info("开始更新帖子标签,标签ID:{}", postTagId);
|
||||||
@@ -74,15 +63,14 @@ public class PostTagServiceImpl extends ServiceImpl<PostTagMapper, PostTag> impl
|
|||||||
logger.info("帖子标签更新成功,标签ID:{}", postTagId);
|
logger.info("帖子标签更新成功,标签ID:{}", postTagId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除帖子标签。
|
|
||||||
* 根据帖子标签ID删除指定的帖子标签。
|
|
||||||
*
|
|
||||||
* @param postTagId 要删除的帖子标签的唯一标识ID
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void deletePostTag(Long postTagId) {
|
public void deletePostTag(Long postTagId) {
|
||||||
logger.info("开始删除帖子标签,标签ID:{}", postTagId);
|
logger.info("开始删除帖子标签,标签ID:{}", postTagId);
|
||||||
|
// 删除标签时减少使用次数
|
||||||
|
PostTag postTag = getById(postTagId);
|
||||||
|
if (postTag != null) {
|
||||||
|
redisTemplate.opsForZSet().incrementScore(TAG_KEY, postTag.getTagId().toString(), -1);
|
||||||
|
}
|
||||||
removeById(postTagId);
|
removeById(postTagId);
|
||||||
logger.info("帖子标签删除成功,标签ID:{}", postTagId);
|
logger.info("帖子标签删除成功,标签ID:{}", postTagId);
|
||||||
}
|
}
|
||||||
@@ -104,4 +92,14 @@ public class PostTagServiceImpl extends ServiceImpl<PostTagMapper, PostTag> impl
|
|||||||
logger.info("开始获取排序后的标签列表");
|
logger.info("开始获取排序后的标签列表");
|
||||||
return tagMapper.getSortedTagList();
|
return tagMapper.getSortedTagList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTopTags(int topN) {
|
||||||
|
logger.info("开始获取前{}个使用次数最多的标签", topN);
|
||||||
|
Set<String> tagSet = redisTemplate.opsForZSet().reverseRange(TAG_KEY, 0, topN - 1);
|
||||||
|
if (tagSet == null) {
|
||||||
|
return List.of(); // 或者返回一个空的List
|
||||||
|
}
|
||||||
|
return tagSet.stream().collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,87 +11,66 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* 标签服务实现类
|
|
||||||
*/
|
|
||||||
@Service
|
@Service
|
||||||
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {
|
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements TagService {
|
||||||
|
|
||||||
// 使用SLF4J的LoggerFactory创建一个Logger实例
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TagServiceImpl.class);
|
private static final Logger logger = LoggerFactory.getLogger(TagServiceImpl.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TagMapper tagMapper;
|
private TagMapper tagMapper;
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建标签
|
|
||||||
* @param tag 标签实体对象
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void createTag(Tag tag) {
|
public void createTag(Tag tag) {
|
||||||
try {
|
try {
|
||||||
// 保存标签到数据库
|
|
||||||
save(tag);
|
save(tag);
|
||||||
logger.info("Tag created successfully: {}", tag);
|
logger.info("标签创建成功:{}", tag);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to create tag: {}", tag, e);
|
logger.error("标签创建失败:{}", tag, e);
|
||||||
|
throw e; // 重新抛出异常以便控制器能捕获并处理
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据ID获取标签
|
|
||||||
* @param tagId 标签ID
|
|
||||||
* @return 标签实体对象
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Tag getTagById(Long tagId) {
|
public Tag getTagById(Long tagId) {
|
||||||
try {
|
try {
|
||||||
// 根据ID查询标签
|
|
||||||
return getById(tagId);
|
return getById(tagId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to get tag by id: {}", tagId, e);
|
logger.error("获取标签ID:{}失败", tagId, e);
|
||||||
return null;
|
throw e; // 重新抛出异常
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新标签信息
|
|
||||||
* @param tagId 标签ID
|
|
||||||
* @param tag 更新后的标签实体对象
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTag(Long tagId, Tag tag) {
|
public void updateTag(Long tagId, Tag tag) {
|
||||||
try {
|
try {
|
||||||
// 设置标签ID并更新标签信息
|
|
||||||
tag.setTagId(tagId);
|
tag.setTagId(tagId);
|
||||||
updateById(tag);
|
updateById(tag);
|
||||||
logger.info("Tag updated successfully: {}", tag);
|
logger.info("标签更新成功:{}", tag);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to update tag with id {}: {}", tagId, tag, e);
|
logger.error("更新标签ID:{}失败", tagId, e);
|
||||||
|
throw e; // 重新抛出异常
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除标签
|
|
||||||
* @param tagId 标签ID
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTag(Long tagId) {
|
public void deleteTag(Long tagId) {
|
||||||
try {
|
try {
|
||||||
// 根据ID删除标签
|
|
||||||
removeById(tagId);
|
removeById(tagId);
|
||||||
logger.info("Tag deleted successfully with id: {}", tagId);
|
logger.info("标签删除成功,ID:{}", tagId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to delete tag with id: {}", tagId, e);
|
logger.error("删除标签ID:{}失败", tagId, e);
|
||||||
|
throw e; // 重新抛出异常
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tag> getTagList() {
|
public List<Tag> getTagList() {
|
||||||
List<Tag> tags = tagMapper.selectList(null);
|
try {
|
||||||
if (tags != null) {
|
return tagMapper.selectList(null);
|
||||||
return tags;
|
} catch (Exception e) {
|
||||||
|
logger.error("获取标签列表失败", e);
|
||||||
|
throw e; // 重新抛出异常
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ wx.miniapp.configs[0].secret=989f155fcc3aee616568473faf1b1d3b
|
|||||||
spring.data.redis.host=localhost
|
spring.data.redis.host=localhost
|
||||||
spring.data.redis.port=6379
|
spring.data.redis.port=6379
|
||||||
spring.data.redis.database=0
|
spring.data.redis.database=0
|
||||||
|
spring.data.redis.lettuce.pool.max-active=32
|
||||||
|
spring.data.redis.lettuce.pool.max-idle=16
|
||||||
|
spring.data.redis.lettuce.pool.min-idle=8
|
||||||
|
|
||||||
spring.application.name=community
|
spring.application.name=community
|
||||||
|
|
||||||
|
|||||||
@@ -98,5 +98,10 @@
|
|||||||
<artifactId>tencentcloud-sdk-java-ocr</artifactId>
|
<artifactId>tencentcloud-sdk-java-ocr</artifactId>
|
||||||
<version>3.1.1076</version>
|
<version>3.1.1076</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java-tts</artifactId>
|
||||||
|
<version>3.1.1076</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.ivmiku.tutorial.config;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.context.SaHolder;
|
||||||
|
import cn.dev33.satoken.filter.SaServletFilter;
|
||||||
|
import cn.dev33.satoken.same.SaSameUtil;
|
||||||
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sa-Token 权限认证 配置类
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SaTokenConfigure implements WebMvcConfigurer {
|
||||||
|
// 注册 Sa-Token 全局过滤器
|
||||||
|
@Bean
|
||||||
|
public SaServletFilter getSaServletFilter() {
|
||||||
|
return new SaServletFilter()
|
||||||
|
.addInclude("/**")
|
||||||
|
.addExclude("/favicon.ico")
|
||||||
|
.setAuth(obj -> {
|
||||||
|
// 校验 Same-Token 身份凭证 —— 以下两句代码可简化为:SaSameUtil.checkCurrentRequestToken();
|
||||||
|
String token = SaHolder.getRequest().getHeader(SaSameUtil.SAME_TOKEN);
|
||||||
|
SaSameUtil.checkToken(token);
|
||||||
|
})
|
||||||
|
.setError(e -> {
|
||||||
|
return SaResult.error(e.getMessage());
|
||||||
|
})
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.ivmiku.tutorial.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||||
|
import com.ivmiku.tutorial.response.Result;
|
||||||
|
import com.ivmiku.tutorial.service.AssistantService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/assistant")
|
||||||
|
@SaCheckLogin
|
||||||
|
public class AssistantController {
|
||||||
|
@Resource
|
||||||
|
private AssistantService assistantService;
|
||||||
|
|
||||||
|
@GetMapping("/response")
|
||||||
|
public Object getResponse(@RequestParam String input) {
|
||||||
|
Map<String, Object> map = assistantService.getResponse(input);
|
||||||
|
if (map == null) {
|
||||||
|
return Result.error("请求出错");
|
||||||
|
}
|
||||||
|
return Result.ok(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tts")
|
||||||
|
public Object textToSpeech(@RequestParam String input) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("content", assistantService.textToSpeech(input));
|
||||||
|
return Result.ok(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,9 @@ public class NavigateController {
|
|||||||
String userId = (String) StpUtil.getLoginId();
|
String userId = (String) StpUtil.getLoginId();
|
||||||
if (!origin.isEmpty() && !destination.isEmpty()) {
|
if (!origin.isEmpty() && !destination.isEmpty()) {
|
||||||
Map<String, Object> route = navigateService.getRoute(origin, destination);
|
Map<String, Object> route = navigateService.getRoute(origin, destination);
|
||||||
|
if (route == null) {
|
||||||
|
return JSON.toJSON(Result.error("路线规划失败!"));
|
||||||
|
}
|
||||||
List<RouteStep> stepsList = (List<RouteStep>) route.get("steps");
|
List<RouteStep> stepsList = (List<RouteStep>) route.get("steps");
|
||||||
STEPS_MAP.put(userId, stepsList);
|
STEPS_MAP.put(userId, stepsList);
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
@@ -50,13 +53,24 @@ public class NavigateController {
|
|||||||
map.put("step", STEPS_MAP.get(userId).get(step-1));
|
map.put("step", STEPS_MAP.get(userId).get(step-1));
|
||||||
return JSON.toJSON(Result.ok(map));
|
return JSON.toJSON(Result.ok(map));
|
||||||
}
|
}
|
||||||
return JSON.toJSON(Result.error("非法的请求参数"));
|
return Result.error("非法的请求参数");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/ticket")
|
@PostMapping("/ticket")
|
||||||
public Object scanTicket(@RequestPart MultipartFile file) throws IOException {
|
public Object scanTicket(@RequestPart MultipartFile file) throws IOException {
|
||||||
BufferedImage image = ImageIO.read(file.getInputStream());
|
BufferedImage image = ImageIO.read(file.getInputStream());
|
||||||
Map<String, Object> map = navigateService.scanTicket(image);
|
Map<String, Object> map = navigateService.scanTicket(image);
|
||||||
return JSON.toJSON(Result.ok(map));
|
return Result.ok(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/geocode")
|
||||||
|
public Object getGeoCode(@RequestParam String address, @RequestParam(defaultValue = "") String city) {
|
||||||
|
String geoCode = navigateService.getGeoCode(address, city);
|
||||||
|
if (geoCode == null) {
|
||||||
|
return JSON.toJSON(Result.error("未获取到有效信息"));
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("geocode", geoCode);
|
||||||
|
return Result.ok(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package com.ivmiku.tutorial.service;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ivmiku.tutorial.utils.SnowflakeUtil;
|
||||||
|
import com.tencentcloudapi.common.AbstractModel;
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.tts.v20190823.TtsClient;
|
||||||
|
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceRequest;
|
||||||
|
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceResponse;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AssistantService {
|
||||||
|
private final String auth = "bad1f6cad39a4c26aa9fe9e4324e096f:ZDczMDIwOTg3NjlhODdmYWVjYTY0YjM1";
|
||||||
|
private final String secretId = "AKID09INNYxYEFFJH3g9VhljVF3qbDiFdx50";
|
||||||
|
private final String secretKey = "KajjcNyNaaUCqQroqpzNoMtTHNj4Lbil";
|
||||||
|
|
||||||
|
public Map<String, Object> getResponse(String userInput) {
|
||||||
|
Map<String, Object> message1 = new HashMap<>();
|
||||||
|
message1.put("role", "system");
|
||||||
|
message1.put("content", "模仿语音助手,对用户的问题给出简短的回答");
|
||||||
|
Map<String, Object> message2 = new HashMap<>();
|
||||||
|
message2.put("role", "user");
|
||||||
|
message2.put("content", userInput);
|
||||||
|
JSONArray array = new JSONArray();
|
||||||
|
array.add(message1);
|
||||||
|
array.add(message2);
|
||||||
|
JSONObject params = new JSONObject();
|
||||||
|
params.put("model", "general");
|
||||||
|
params.put("messages", array);
|
||||||
|
HttpResponse response = HttpRequest.post("https://spark-api-open.xf-yun.com/v1/chat/completions")
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("Authorization", "Bearer " + auth)
|
||||||
|
.body(params.toJSONString())
|
||||||
|
.execute();
|
||||||
|
JSONObject result = JSONObject.parseObject(response.body());
|
||||||
|
response.close();
|
||||||
|
if (result.getInteger("code") != 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONArray choices = result.getJSONArray("choices");
|
||||||
|
JSONObject message = choices.getJSONObject(0);
|
||||||
|
JSONObject content = message.getJSONObject("message");
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("content", content.get("content"));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String textToSpeech(String content) {
|
||||||
|
try{
|
||||||
|
Credential cred = new Credential(secretId, secretKey);
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("tts.tencentcloudapi.com");
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
TtsClient client = new TtsClient(cred, "ap-shanghai", clientProfile);
|
||||||
|
TextToVoiceRequest req = new TextToVoiceRequest();
|
||||||
|
req.setText(content);
|
||||||
|
req.setSessionId(SnowflakeUtil.getNext());
|
||||||
|
req.setVoiceType(101006L);
|
||||||
|
TextToVoiceResponse resp = client.TextToVoice(req);
|
||||||
|
return resp.getAudio();
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,11 @@ public class NavigateService {
|
|||||||
.execute();
|
.execute();
|
||||||
String result = response.body();
|
String result = response.body();
|
||||||
response.close();
|
response.close();
|
||||||
JSONObject route = JSONObject.parseObject(JSONObject.parseObject(result).getString("route"));
|
JSONObject resultObj = JSONObject.parseObject(result);
|
||||||
|
if (resultObj.getInteger("status")==0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject route = JSONObject.parseObject(resultObj.getString("route"));
|
||||||
JSONArray paths = JSONArray.parseArray(route.getString("paths"));
|
JSONArray paths = JSONArray.parseArray(route.getString("paths"));
|
||||||
JSONObject path = paths.getJSONObject(0);
|
JSONObject path = paths.getJSONObject(0);
|
||||||
String distance = path.getString("distance");
|
String distance = path.getString("distance");
|
||||||
@@ -81,4 +85,25 @@ public class NavigateService {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getGeoCode(String address, String city) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("key", key);
|
||||||
|
params.put("address", address);
|
||||||
|
if (!city.isEmpty()) {
|
||||||
|
params.put("city", city);
|
||||||
|
}
|
||||||
|
HttpResponse response = HttpRequest.get("https://restapi.amap.com/v3/geocode/geo")
|
||||||
|
.form(params)
|
||||||
|
.execute();
|
||||||
|
String result = response.body();
|
||||||
|
response.close();
|
||||||
|
JSONObject resultObj = JSONObject.parseObject(result);
|
||||||
|
if (resultObj.getInteger("status")==0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONArray array = resultObj.getJSONArray("geocodes");
|
||||||
|
JSONObject location = array.getJSONObject(0);
|
||||||
|
return location.getString("location");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ivmiku.tutorial.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.generator.SnowflakeGenerator;
|
||||||
|
|
||||||
|
public class SnowflakeUtil {
|
||||||
|
private static SnowflakeGenerator generator;
|
||||||
|
|
||||||
|
static {
|
||||||
|
generator = new SnowflakeGenerator();
|
||||||
|
}
|
||||||
|
public static String getNext() {
|
||||||
|
return String.valueOf(generator.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user