fix(backend): Restore service flow and admin management integration
This commit is contained in:
+68
@@ -0,0 +1,68 @@
|
||||
package com.nuaa.video.admin.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nuaa.video.admin.annotation.OperationLog;
|
||||
import com.nuaa.video.admin.feign.CommentFeignClient;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 评论管理控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/platform/comment")
|
||||
@RequiredArgsConstructor
|
||||
public class CommentManageController {
|
||||
|
||||
@Value("${service.auth.token}")
|
||||
private String internalServiceToken;
|
||||
|
||||
private final CommentFeignClient commentFeignClient;
|
||||
|
||||
/**
|
||||
* 获取评论列表
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('comment:manage')")
|
||||
@GetMapping("/list")
|
||||
public Result<Page<Object>> getCommentList(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "videoId", required = false) Long videoId,
|
||||
@RequestParam(value = "userId", required = false) Long userId,
|
||||
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return commentFeignClient.getCommentList(page, size, videoId, userId, keyword, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评论详情
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('comment:manage')")
|
||||
@GetMapping("/{commentId}")
|
||||
public Result<Object> getCommentDetail(@PathVariable Long commentId) {
|
||||
return commentFeignClient.getCommentDetail(commentId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除评论
|
||||
*/
|
||||
@OperationLog("删除评论")
|
||||
@PreAuthorize("hasAuthority('comment:manage')")
|
||||
@DeleteMapping("/{commentId}")
|
||||
public Result<Void> deleteComment(@PathVariable Long commentId) {
|
||||
return commentFeignClient.deleteComment(commentId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评论统计信息
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('comment:manage')")
|
||||
@GetMapping("/stats")
|
||||
public Result<Object> getCommentStats() {
|
||||
return commentFeignClient.getCommentStats(internalServiceToken);
|
||||
}
|
||||
}
|
||||
+25
-22
@@ -6,6 +6,7 @@ import com.nuaa.video.admin.feign.ContentFeignClient;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -18,6 +19,9 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequiredArgsConstructor
|
||||
public class ContentManageController {
|
||||
|
||||
@Value("${service.auth.token}")
|
||||
private String internalServiceToken;
|
||||
|
||||
private final ContentFeignClient contentFeignClient;
|
||||
|
||||
/**
|
||||
@@ -30,9 +34,8 @@ public class ContentManageController {
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "categoryId", required = false) Long categoryId,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.getVideoList(page, size, keyword, categoryId, status, token);
|
||||
@RequestParam(value = "status", required = false) Integer status) {
|
||||
return contentFeignClient.getVideoList(page, size, keyword, categoryId, status, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,9 +44,8 @@ public class ContentManageController {
|
||||
@PreAuthorize("hasAuthority('video:manage')")
|
||||
@GetMapping("/video/{videoId}")
|
||||
public Result<Object> getVideoDetail(
|
||||
@PathVariable Long videoId,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.getVideoDetail(videoId, token);
|
||||
@PathVariable Long videoId) {
|
||||
return contentFeignClient.getVideoDetail(videoId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,8 +58,10 @@ public class ContentManageController {
|
||||
@PathVariable Long videoId,
|
||||
@RequestParam Integer status,
|
||||
@RequestParam(required = false) String reason,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.reviewVideo(videoId, status, reason, token);
|
||||
jakarta.servlet.http.HttpServletRequest request) {
|
||||
Object adminId = request.getAttribute("adminId");
|
||||
Long currentAdminId = adminId instanceof Long ? (Long) adminId : 0L;
|
||||
return contentFeignClient.reviewVideo(videoId, status, reason, internalServiceToken, currentAdminId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,8 +72,10 @@ public class ContentManageController {
|
||||
@PutMapping("/video/disable/{videoId}")
|
||||
public Result<Void> disableVideo(
|
||||
@PathVariable Long videoId,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.disableVideo(videoId, token);
|
||||
jakarta.servlet.http.HttpServletRequest request) {
|
||||
Object adminId = request.getAttribute("adminId");
|
||||
Long currentAdminId = adminId instanceof Long ? (Long) adminId : 0L;
|
||||
return contentFeignClient.disableVideo(videoId, internalServiceToken, currentAdminId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,8 +83,8 @@ public class ContentManageController {
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('category:manage')")
|
||||
@GetMapping("/category/list")
|
||||
public Result<Object> getCategoryList(@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.getCategoryList(token);
|
||||
public Result<Object> getCategoryList() {
|
||||
return contentFeignClient.getCategoryList(internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,9 +94,8 @@ public class ContentManageController {
|
||||
@PreAuthorize("hasAuthority('category:manage')")
|
||||
@PostMapping("/category")
|
||||
public Result<Void> addCategory(
|
||||
@RequestBody Object category,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.addCategory(category, token);
|
||||
@RequestBody Object category) {
|
||||
return contentFeignClient.addCategory(category, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,9 +105,8 @@ public class ContentManageController {
|
||||
@PreAuthorize("hasAuthority('category:manage')")
|
||||
@PutMapping("/category")
|
||||
public Result<Void> updateCategory(
|
||||
@RequestBody Object category,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.updateCategory(category, token);
|
||||
@RequestBody Object category) {
|
||||
return contentFeignClient.updateCategory(category, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,8 +116,7 @@ public class ContentManageController {
|
||||
@PreAuthorize("hasAuthority('category:manage')")
|
||||
@DeleteMapping("/category/{categoryId}")
|
||||
public Result<Void> deleteCategory(
|
||||
@PathVariable Long categoryId,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return contentFeignClient.deleteCategory(categoryId, token);
|
||||
@PathVariable Long categoryId) {
|
||||
return contentFeignClient.deleteCategory(categoryId, internalServiceToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package com.nuaa.video.admin.controller;
|
||||
|
||||
import com.nuaa.video.admin.feign.CommentFeignClient;
|
||||
import com.nuaa.video.admin.feign.ContentFeignClient;
|
||||
import com.nuaa.video.admin.feign.UserFeignClient;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 后台首页统计控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/dashboard")
|
||||
@RequiredArgsConstructor
|
||||
public class DashboardController {
|
||||
|
||||
@Value("${service.auth.token}")
|
||||
private String internalServiceToken;
|
||||
|
||||
private final UserFeignClient userFeignClient;
|
||||
private final ContentFeignClient contentFeignClient;
|
||||
private final CommentFeignClient commentFeignClient;
|
||||
|
||||
/**
|
||||
* 获取后台仪表盘统计信息
|
||||
*/
|
||||
@PreAuthorize("hasAuthority('operation:log')")
|
||||
@GetMapping("/stats")
|
||||
public Result<Map<String, Object>> getDashboardStats() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
Result<Object> userStats = userFeignClient.getUserStats(internalServiceToken);
|
||||
Result<Object> videoStats = contentFeignClient.getVideoStats(internalServiceToken);
|
||||
Result<Object> commentStats = commentFeignClient.getCommentStats(internalServiceToken);
|
||||
|
||||
result.put("userStats", userStats.getData());
|
||||
result.put("videoStats", videoStats.getData());
|
||||
result.put("commentStats", commentStats.getData());
|
||||
|
||||
long totalUsers = readLong(userStats.getData(), "totalUsers");
|
||||
long totalVideos = readLong(videoStats.getData(), "totalVideos");
|
||||
long totalComments = readLong(commentStats.getData(), "commentCount");
|
||||
result.put("overview", Map.of(
|
||||
"totalUsers", totalUsers,
|
||||
"totalVideos", totalVideos,
|
||||
"totalComments", totalComments
|
||||
));
|
||||
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private long readLong(Object payload, String key) {
|
||||
if (!(payload instanceof Map<?, ?> map)) {
|
||||
return 0L;
|
||||
}
|
||||
Object value = ((Map<String, Object>) map).get(key);
|
||||
if (value instanceof Number number) {
|
||||
return number.longValue();
|
||||
}
|
||||
if (value != null) {
|
||||
try {
|
||||
return Long.parseLong(value.toString());
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -6,6 +6,7 @@ import com.nuaa.video.admin.feign.UserFeignClient;
|
||||
import com.nuaa.video.common.model.vo.Result;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -18,6 +19,9 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequiredArgsConstructor
|
||||
public class UserManageController {
|
||||
|
||||
@Value("${service.auth.token}")
|
||||
private String internalServiceToken;
|
||||
|
||||
private final UserFeignClient userFeignClient;
|
||||
|
||||
/**
|
||||
@@ -28,9 +32,8 @@ public class UserManageController {
|
||||
public Result<Page<Object>> getUserList(
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return userFeignClient.getUserList(page, size, keyword, token);
|
||||
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||
return userFeignClient.getUserList(page, size, keyword, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,9 +42,8 @@ public class UserManageController {
|
||||
@PreAuthorize("hasAuthority('user:manage')")
|
||||
@GetMapping("/{userId}")
|
||||
public Result<Object> getUserDetail(
|
||||
@PathVariable Long userId,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return userFeignClient.getUserDetail(userId, token);
|
||||
@PathVariable Long userId) {
|
||||
return userFeignClient.getUserDetail(userId, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,9 +54,8 @@ public class UserManageController {
|
||||
@PutMapping("/{userId}/status/{status}")
|
||||
public Result<Void> updateUserStatus(
|
||||
@PathVariable Long userId,
|
||||
@PathVariable Integer status,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return userFeignClient.updateUserStatus(userId, status, token);
|
||||
@PathVariable Integer status) {
|
||||
return userFeignClient.updateUserStatus(userId, status, internalServiceToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,8 +66,7 @@ public class UserManageController {
|
||||
@PutMapping("/{userId}/reset-password")
|
||||
public Result<Void> resetUserPassword(
|
||||
@PathVariable Long userId,
|
||||
@RequestParam String newPassword,
|
||||
@RequestHeader("Authorization") String token) {
|
||||
return userFeignClient.resetUserPassword(userId, newPassword, token);
|
||||
@RequestParam String newPassword) {
|
||||
return userFeignClient.resetUserPassword(userId, newPassword, internalServiceToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,12 @@ public class LoginDTO implements Serializable {
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String captcha;
|
||||
|
||||
/**
|
||||
* 验证码Key
|
||||
*/
|
||||
@NotBlank(message = "验证码Key不能为空")
|
||||
private String captchaKey;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -21,25 +21,25 @@ public interface CommentFeignClient {
|
||||
@RequestParam(value = "videoId", required = false) Long videoId,
|
||||
@RequestParam(value = "userId", required = false) Long userId,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 获取评论详情
|
||||
*/
|
||||
@GetMapping("/comment/admin/{commentId}")
|
||||
Result<Object> getCommentDetail(@PathVariable("commentId") Long commentId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 删除评论
|
||||
*/
|
||||
@DeleteMapping("/comment/admin/{commentId}")
|
||||
Result<Void> deleteComment(@PathVariable("commentId") Long commentId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 获取评论统计信息
|
||||
*/
|
||||
@GetMapping("/comment/admin/stats")
|
||||
Result<Object> getCommentStats(@RequestHeader("Authorization") String token);
|
||||
}
|
||||
Result<Object> getCommentStats(@RequestHeader("X-Internal-Token") String internalToken);
|
||||
}
|
||||
|
||||
+5
-5
@@ -19,24 +19,24 @@ public class CommentFeignClientFallbackFactory implements FallbackFactory<Commen
|
||||
|
||||
return new CommentFeignClient() {
|
||||
@Override
|
||||
public Result<Page<Object>> getCommentList(Integer page, Integer size, Long videoId, Long userId, String keyword, String token) {
|
||||
public Result<Page<Object>> getCommentList(Integer page, Integer size, Long videoId, Long userId, String keyword, String internalToken) {
|
||||
return Result.error("获取评论列表失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getCommentDetail(Long commentId, String token) {
|
||||
public Result<Object> getCommentDetail(Long commentId, String internalToken) {
|
||||
return Result.error("获取评论详情失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> deleteComment(Long commentId, String token) {
|
||||
public Result<Void> deleteComment(Long commentId, String internalToken) {
|
||||
return Result.error("删除评论失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getCommentStats(String token) {
|
||||
public Result<Object> getCommentStats(String internalToken) {
|
||||
return Result.error("获取评论统计信息失败:服务不可用");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-9
@@ -21,14 +21,14 @@ public interface ContentFeignClient {
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "categoryId", required = false) Long categoryId,
|
||||
@RequestParam(value = "status", required = false) Integer status,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 获取视频详情
|
||||
*/
|
||||
@GetMapping("/content/video/admin/{videoId}")
|
||||
Result<Object> getVideoDetail(@PathVariable("videoId") Long videoId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 审核视频
|
||||
@@ -37,37 +37,42 @@ public interface ContentFeignClient {
|
||||
Result<Void> reviewVideo(@PathVariable("videoId") Long videoId,
|
||||
@RequestParam("status") Integer status,
|
||||
@RequestParam(value = "reason", required = false) String reason,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken,
|
||||
@RequestHeader("X-Admin-Id") Long adminId);
|
||||
|
||||
/**
|
||||
* 下架视频
|
||||
*/
|
||||
@PutMapping("/content/video/admin/disable/{videoId}")
|
||||
Result<Void> disableVideo(@PathVariable("videoId") Long videoId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken,
|
||||
@RequestHeader("X-Admin-Id") Long adminId);
|
||||
|
||||
/**
|
||||
* 分类列表
|
||||
*/
|
||||
@GetMapping("/content/category/admin/list")
|
||||
Result<Object> getCategoryList(@RequestHeader("Authorization") String token);
|
||||
Result<Object> getCategoryList(@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 添加分类
|
||||
*/
|
||||
@PostMapping("/content/category/admin")
|
||||
Result<Void> addCategory(@RequestBody Object category, @RequestHeader("Authorization") String token);
|
||||
Result<Void> addCategory(@RequestBody Object category, @RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 更新分类
|
||||
*/
|
||||
@PutMapping("/content/category/admin")
|
||||
Result<Void> updateCategory(@RequestBody Object category, @RequestHeader("Authorization") String token);
|
||||
Result<Void> updateCategory(@RequestBody Object category, @RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 删除分类
|
||||
*/
|
||||
@DeleteMapping("/content/category/admin/{categoryId}")
|
||||
Result<Void> deleteCategory(@PathVariable("categoryId") Long categoryId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
}
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
@GetMapping("/content/video/admin/stats")
|
||||
Result<Object> getVideoStats(@RequestHeader("X-Internal-Token") String internalToken);
|
||||
}
|
||||
|
||||
+13
-8
@@ -19,44 +19,49 @@ public class ContentFeignClientFallbackFactory implements FallbackFactory<Conten
|
||||
|
||||
return new ContentFeignClient() {
|
||||
@Override
|
||||
public Result<Page<Object>> getVideoList(Integer page, Integer size, String keyword, Long categoryId, Integer status, String token) {
|
||||
public Result<Page<Object>> getVideoList(Integer page, Integer size, String keyword, Long categoryId, Integer status, String internalToken) {
|
||||
return Result.error("获取视频列表失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getVideoDetail(Long videoId, String token) {
|
||||
public Result<Object> getVideoDetail(Long videoId, String internalToken) {
|
||||
return Result.error("获取视频详情失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> reviewVideo(Long videoId, Integer status, String reason, String token) {
|
||||
public Result<Void> reviewVideo(Long videoId, Integer status, String reason, String internalToken, Long adminId) {
|
||||
return Result.error("审核视频失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> disableVideo(Long videoId, String token) {
|
||||
public Result<Void> disableVideo(Long videoId, String internalToken, Long adminId) {
|
||||
return Result.error("下架视频失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getCategoryList(String token) {
|
||||
public Result<Object> getCategoryList(String internalToken) {
|
||||
return Result.error("获取分类列表失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> addCategory(Object category, String token) {
|
||||
public Result<Void> addCategory(Object category, String internalToken) {
|
||||
return Result.error("添加分类失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> updateCategory(Object category, String token) {
|
||||
public Result<Void> updateCategory(Object category, String internalToken) {
|
||||
return Result.error("更新分类失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> deleteCategory(Long categoryId, String token) {
|
||||
public Result<Void> deleteCategory(Long categoryId, String internalToken) {
|
||||
return Result.error("删除分类失败:服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getVideoStats(String internalToken) {
|
||||
return Result.error("获取视频统计失败:服务不可用");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ public interface UserFeignClient {
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "size", defaultValue = "10") Integer size,
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 获取用户详情
|
||||
*/
|
||||
@GetMapping("/user/profile/admin/{userId}")
|
||||
Result<Object> getUserDetail(@PathVariable("userId") Long userId,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 禁用/启用用户
|
||||
@@ -34,7 +34,7 @@ public interface UserFeignClient {
|
||||
@PutMapping("/user/profile/admin/status/{userId}/{status}")
|
||||
Result<Void> updateUserStatus(@PathVariable("userId") Long userId,
|
||||
@PathVariable("status") Integer status,
|
||||
@RequestHeader("Authorization") String token);
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
@@ -42,5 +42,8 @@ public interface UserFeignClient {
|
||||
@PutMapping("/user/profile/admin/reset-password/{userId}")
|
||||
Result<Void> resetUserPassword(@PathVariable("userId") Long userId,
|
||||
@RequestParam String newPassword,
|
||||
@RequestHeader("Authorization") String token);
|
||||
}
|
||||
@RequestHeader("X-Internal-Token") String internalToken);
|
||||
|
||||
@GetMapping("/user/profile/admin/stats")
|
||||
Result<Object> getUserStats(@RequestHeader("X-Internal-Token") String internalToken);
|
||||
}
|
||||
|
||||
+11
-5
@@ -18,28 +18,34 @@ public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeign
|
||||
log.error("用户服务调用失败:", cause);
|
||||
return new UserFeignClient() {
|
||||
@Override
|
||||
public Result<Page<Object>> getUserList(Integer page, Integer size, String keyword, String token) {
|
||||
public Result<Page<Object>> getUserList(Integer page, Integer size, String keyword, String internalToken) {
|
||||
log.error("获取用户列表失败");
|
||||
return Result.error("获取用户列表失败,用户服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getUserDetail(Long userId, String token) {
|
||||
public Result<Object> getUserDetail(Long userId, String internalToken) {
|
||||
log.error("获取用户详情失败,用户ID: {}", userId);
|
||||
return Result.error("获取用户详情失败,用户服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> updateUserStatus(Long userId, Integer status, String token) {
|
||||
public Result<Void> updateUserStatus(Long userId, Integer status, String internalToken) {
|
||||
log.error("更新用户状态失败,用户ID: {}, 状态: {}", userId, status);
|
||||
return Result.error("更新用户状态失败,用户服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Void> resetUserPassword(Long userId, String newPassword, String token) {
|
||||
public Result<Void> resetUserPassword(Long userId, String newPassword, String internalToken) {
|
||||
log.error("重置用户密码失败,用户ID: {}", userId);
|
||||
return Result.error("重置用户密码失败,用户服务不可用");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Object> getUserStats(String internalToken) {
|
||||
log.error("获取用户统计失败");
|
||||
return Result.error("获取用户统计失败,用户服务不可用");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -46,15 +46,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
.map(SimpleGrantedAuthority::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 创建认证对象
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||
username, null, simpleGrantedAuthorities);
|
||||
|
||||
// 设置用户详情
|
||||
AdminUserDetails userDetails = new AdminUserDetails();
|
||||
userDetails.setId(adminId);
|
||||
userDetails.setUsername(username);
|
||||
userDetails.setAuthorities(simpleGrantedAuthorities);
|
||||
|
||||
// 将完整用户详情作为 principal,便于 @AuthenticationPrincipal 直接获取
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||
userDetails, null, simpleGrantedAuthorities);
|
||||
authentication.setDetails(userDetails);
|
||||
|
||||
// 设置认证信息到安全上下文
|
||||
@@ -82,4 +82,4 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -4,8 +4,10 @@ import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
@@ -20,14 +22,19 @@ import java.util.function.Function;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class JwtTokenProvider {
|
||||
|
||||
private static final String TOKEN_KEY_PREFIX = "admin:token:";
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
private String secret;
|
||||
|
||||
@Value("${jwt.expiration}")
|
||||
private Long expiration;
|
||||
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 生成JWT令牌
|
||||
*/
|
||||
@@ -53,7 +60,7 @@ public class JwtTokenProvider {
|
||||
public boolean validateToken(String token) {
|
||||
try {
|
||||
Jwts.parser().verifyWith(getSignKey()).build().parseSignedClaims(token);
|
||||
return true;
|
||||
return Boolean.TRUE.equals(stringRedisTemplate.hasKey(TOKEN_KEY_PREFIX + token));
|
||||
} catch (JwtException | IllegalArgumentException e) {
|
||||
log.error("无效的JWT令牌: {}", e.getMessage());
|
||||
return false;
|
||||
@@ -107,4 +114,4 @@ public class JwtTokenProvider {
|
||||
.getPayload();
|
||||
return claimsResolver.apply(claims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ public class AdminUserInitService implements ApplicationRunner {
|
||||
private final AdminUserRoleMapper adminUserRoleMapper;
|
||||
private final PasswordService passwordService;
|
||||
|
||||
@Value("${app.init.admin-password:admin123}")
|
||||
@Value("${app.init.admin-password}")
|
||||
private String initAdminPassword;
|
||||
|
||||
@Override
|
||||
@@ -49,7 +49,7 @@ public class AdminUserInitService implements ApplicationRunner {
|
||||
adminUser.setRealName("系统管理员");
|
||||
adminUser.setEmail("admin@example.com");
|
||||
adminUser.setStatus(1); // 正常状态
|
||||
adminUser.setSalt("aaaaaa"); // 盐值可以设置为默认值,该字段已抛弃
|
||||
adminUser.setSalt(null);
|
||||
adminUser.setCreatedBy("system");
|
||||
adminUser.setUpdatedBy("system");
|
||||
adminUser.setCreateTime(LocalDateTime.now());
|
||||
@@ -69,4 +69,4 @@ public class AdminUserInitService implements ApplicationRunner {
|
||||
|
||||
log.info("管理员账号初始化完成");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -90,18 +90,16 @@ public class AuthServiceImpl implements AuthService {
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
if (StringUtils.hasText(loginDTO.getCaptchaKey()) && StringUtils.hasText(loginDTO.getCaptcha())) {
|
||||
String captchaKey = CAPTCHA_KEY_PREFIX + loginDTO.getCaptchaKey();
|
||||
String captchaValue = (String) redisTemplate.opsForValue().get(captchaKey);
|
||||
String captchaKey = CAPTCHA_KEY_PREFIX + loginDTO.getCaptchaKey();
|
||||
String captchaValue = (String) redisTemplate.opsForValue().get(captchaKey);
|
||||
|
||||
if (!StringUtils.hasText(captchaValue) || !captchaValue.equalsIgnoreCase(loginDTO.getCaptcha())) {
|
||||
return Result.error("验证码错误");
|
||||
}
|
||||
|
||||
// 验证通过后删除验证码
|
||||
redisTemplate.delete(captchaKey);
|
||||
if (!StringUtils.hasText(captchaValue) || !captchaValue.equalsIgnoreCase(loginDTO.getCaptcha())) {
|
||||
return Result.error("验证码错误");
|
||||
}
|
||||
|
||||
// 验证通过后删除验证码
|
||||
redisTemplate.delete(captchaKey);
|
||||
|
||||
try {
|
||||
// 进行认证
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
@@ -276,4 +274,4 @@ public class AuthServiceImpl implements AuthService {
|
||||
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
server:
|
||||
port: 9004
|
||||
port: 9006
|
||||
|
||||
spring:
|
||||
application:
|
||||
@@ -18,14 +18,14 @@ spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/video_admin?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: root
|
||||
password: ${MYSQL_ROOT_PASSWORD}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:redis}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: redis_EsJ8FX
|
||||
database: 3
|
||||
password: ${REDIS_PASSWORD}
|
||||
database: 5
|
||||
timeout: 10000
|
||||
lettuce:
|
||||
pool:
|
||||
@@ -40,7 +40,6 @@ mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: false
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
@@ -50,4 +49,14 @@ mybatis-plus:
|
||||
|
||||
app:
|
||||
init:
|
||||
admin-password: admin123
|
||||
admin-password: ${ADMIN_INIT_PASSWORD}
|
||||
|
||||
service:
|
||||
auth:
|
||||
token: ${SERVICE_AUTH_TOKEN}
|
||||
|
||||
jwt:
|
||||
secret: ${ADMIN_JWT_SECRET}
|
||||
expiration: ${JWT_EXPIRATION}
|
||||
token-header: Authorization
|
||||
token-prefix: Bearer
|
||||
|
||||
Reference in New Issue
Block a user