管理员日志

This commit is contained in:
none 2023-07-28 16:18:09 +08:00
parent c88fc11c7e
commit e0f807909f
11 changed files with 92 additions and 64 deletions

View File

@ -22,15 +22,10 @@ import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Log public @interface Log {
{ /** 标题 */
/**
* 标题
*/
public String title() default ""; public String title() default "";
/** /** 功能 */
* 功能
*/
public BusinessType businessType() default BusinessType.OTHER; public BusinessType businessType() default BusinessType.OTHER;
} }

View File

@ -17,14 +17,18 @@ package xyz.playedu.api.aspectj;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*; import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import xyz.playedu.api.annotation.Log; import xyz.playedu.api.annotation.Log;
import xyz.playedu.api.domain.AdminLog; import xyz.playedu.api.domain.AdminLog;
import xyz.playedu.api.service.AdminLogService; import xyz.playedu.api.service.AdminLogService;
@ -48,11 +52,11 @@ public class AdminLogAspect {
@Autowired private AdminLogService adminLogService; @Autowired private AdminLogService adminLogService;
/** 排除敏感属性字段 */ /** 排除敏感属性字段 */
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; public static final String[] EXCLUDE_PROPERTIES = {
"password", "oldPassword", "newPassword", "confirmPassword"
};
/** /** Controller层切点 注解拦截 */
* Controller层切点 注解拦截
*/
@Pointcut("@annotation(xyz.playedu.api.annotation.Log)") @Pointcut("@annotation(xyz.playedu.api.annotation.Log)")
public void logPointCut() {} public void logPointCut() {}
@ -107,17 +111,17 @@ public class AdminLogAspect {
Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, String[]> parameterMap = request.getParameterMap();
if (StringUtil.isNotEmpty(parameterMap)) { if (StringUtil.isNotEmpty(parameterMap)) {
params = JSONUtil.toJsonStr(parameterMap); params = JSONUtil.toJsonStr(parameterMap);
}else { } else {
Object[] args = joinPoint.getArgs(); Object[] args = joinPoint.getArgs();
if (StringUtil.isNotNull(args)) { if (StringUtil.isNotNull(args)) {
params = StringUtil.arrayToString(args); params = StringUtil.arrayToString(args);
} }
} }
if(StringUtil.isNotEmpty(params)){ if (StringUtil.isNotEmpty(params)) {
JSONObject paramObj = JSONUtil.parseObj(params); JSONObject paramObj = JSONUtil.parseObj(params);
for(String i : Arrays.asList(EXCLUDE_PROPERTIES)){ for (String i : Arrays.asList(EXCLUDE_PROPERTIES)) {
if(paramObj.containsKey(i)){ if (paramObj.containsKey(i)) {
paramObj.put(i,"******"); paramObj.put(i, "******");
} }
} }
adminLog.setParam(StringUtils.substring(JSONUtil.toJsonStr(paramObj), 0, 2000)); adminLog.setParam(StringUtils.substring(JSONUtil.toJsonStr(paramObj), 0, 2000));
@ -134,13 +138,11 @@ public class AdminLogAspect {
adminLogService.save(adminLog); adminLogService.save(adminLog);
} catch (Exception exp) { } catch (Exception exp) {
// 记录本地异常日志 // 记录本地异常日志
log.error("异常信息:"+exp.getMessage(),e); log.error("异常信息:" + exp.getMessage(), e);
} }
} }
/** /** 是否存在注解,如果存在就获取 */
* 是否存在注解如果存在就获取
*/
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception { private Log getAnnotationLog(JoinPoint joinPoint) throws Exception {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();

View File

@ -36,14 +36,24 @@ public class BackendConstant {
public static final String RESOURCE_TYPE_WORD = "WORD"; public static final String RESOURCE_TYPE_WORD = "WORD";
public static final String RESOURCE_TYPE_PPT = "PPT"; public static final String RESOURCE_TYPE_PPT = "PPT";
public static final String RESOURCE_TYPE_EXCEL = "EXCEL"; public static final String RESOURCE_TYPE_EXCEL = "EXCEL";
public static final String RESOURCE_TYPE_ZIP= "ZIP"; public static final String RESOURCE_TYPE_ZIP = "ZIP";
public static final String RESOURCE_TYPE_RAR = "RAR"; public static final String RESOURCE_TYPE_RAR = "RAR";
public static final String RESOURCE_TYPE_TXT = "TXT"; public static final String RESOURCE_TYPE_TXT = "TXT";
public static final String RESOURCE_TYPE_ATTACHMENT = public static final String RESOURCE_TYPE_ATTACHMENT =
RESOURCE_TYPE_PDF +","+ RESOURCE_TYPE_TXT +","+ RESOURCE_TYPE_PDF
RESOURCE_TYPE_ZIP +","+ RESOURCE_TYPE_RAR +","+ + ","
RESOURCE_TYPE_WORD +","+RESOURCE_TYPE_PPT +","+RESOURCE_TYPE_EXCEL; + RESOURCE_TYPE_TXT
+ ","
+ RESOURCE_TYPE_ZIP
+ ","
+ RESOURCE_TYPE_RAR
+ ","
+ RESOURCE_TYPE_WORD
+ ","
+ RESOURCE_TYPE_PPT
+ ","
+ RESOURCE_TYPE_EXCEL;
public static final HashMap<String, String> RESOURCE_EXT_2_CONTENT_TYPE = public static final HashMap<String, String> RESOURCE_EXT_2_CONTENT_TYPE =
new HashMap<>() { new HashMap<>() {
@ -55,11 +65,17 @@ public class BackendConstant {
put("pdf", "application/pdf"); put("pdf", "application/pdf");
put("mp4", "video/mp4"); put("mp4", "video/mp4");
put("doc", "application/msword"); put("doc", "application/msword");
put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); put(
"docx",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document");
put("ppt", "application/vnd.ms-powerpoint"); put("ppt", "application/vnd.ms-powerpoint");
put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"); put(
"pptx",
"application/vnd.openxmlformats-officedocument.presentationml.presentation");
put("xls", "application/vnd.ms-excel"); put("xls", "application/vnd.ms-excel");
put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); put(
"xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
put("txt", "text/plain"); put("txt", "text/plain");
put("zip", "application/zip"); put("zip", "application/zip");
put("rar", "application/x-rar"); put("rar", "application/x-rar");

View File

@ -15,40 +15,25 @@
*/ */
package xyz.playedu.api.constant; package xyz.playedu.api.constant;
public enum BusinessType public enum BusinessType {
{ /** 其它 */
/**
* 其它
*/
OTHER, OTHER,
/** /** 新增 */
* 新增
*/
INSERT, INSERT,
/** /** 修改 */
* 修改
*/
UPDATE, UPDATE,
/** /** 删除 */
* 删除
*/
DELETE, DELETE,
/** /** 查询 */
* 查询
*/
GET, GET,
/** /** 登录 */
* 登录
*/
LOGIN, LOGIN,
/** /** 退出登录 */
* 退出登录
*/
LOGOUT LOGOUT
} }

View File

@ -209,8 +209,22 @@ public class CourseController {
data.put("dep_ids", depIds); // 已关联的部门 data.put("dep_ids", depIds); // 已关联的部门
data.put("category_ids", categoryIds); // 已关联的分类 data.put("category_ids", categoryIds); // 已关联的分类
data.put("chapters", chapters); data.put("chapters", chapters);
data.put("hours", hours.stream().filter(courseHour -> BackendConstant.RESOURCE_TYPE_VIDEO.equals(courseHour.getType())).collect(Collectors.groupingBy(CourseHour::getChapterId))); data.put(
data.put("attachments", hours.stream().filter(courseHour -> BackendConstant.RESOURCE_TYPE_ATTACHMENT.contains(courseHour.getType())).collect(Collectors.groupingBy(CourseHour::getChapterId))); "hours",
hours.stream()
.filter(
courseHour ->
BackendConstant.RESOURCE_TYPE_VIDEO.equals(
courseHour.getType()))
.collect(Collectors.groupingBy(CourseHour::getChapterId)));
data.put(
"attachments",
hours.stream()
.filter(
courseHour ->
BackendConstant.RESOURCE_TYPE_ATTACHMENT.contains(
courseHour.getType()))
.collect(Collectors.groupingBy(CourseHour::getChapterId)));
return JsonResponse.data(data); return JsonResponse.data(data);
} }

View File

@ -21,9 +21,11 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import xyz.playedu.api.BCtx; import xyz.playedu.api.BCtx;
import xyz.playedu.api.annotation.Log;
import xyz.playedu.api.bus.BackendBus; import xyz.playedu.api.bus.BackendBus;
import xyz.playedu.api.config.PlayEduConfig; import xyz.playedu.api.config.PlayEduConfig;
import xyz.playedu.api.constant.BPermissionConstant; import xyz.playedu.api.constant.BPermissionConstant;
import xyz.playedu.api.constant.BusinessType;
import xyz.playedu.api.domain.AdminUser; import xyz.playedu.api.domain.AdminUser;
import xyz.playedu.api.event.AdminUserLoginEvent; import xyz.playedu.api.event.AdminUserLoginEvent;
import xyz.playedu.api.middleware.BackendPermissionMiddleware; import xyz.playedu.api.middleware.BackendPermissionMiddleware;
@ -57,6 +59,7 @@ public class LoginController {
@Autowired private PlayEduConfig playEduConfig; @Autowired private PlayEduConfig playEduConfig;
@PostMapping("/login") @PostMapping("/login")
@Log(title = "管理员-登录", businessType = BusinessType.LOGIN)
public JsonResponse login(@RequestBody @Validated LoginRequest loginRequest) { public JsonResponse login(@RequestBody @Validated LoginRequest loginRequest) {
AdminUser adminUser = adminUserService.findByEmail(loginRequest.email); AdminUser adminUser = adminUserService.findByEmail(loginRequest.email);
if (adminUser == null) { if (adminUser == null) {
@ -100,12 +103,14 @@ public class LoginController {
} }
@PostMapping("/logout") @PostMapping("/logout")
@Log(title = "管理员-登出", businessType = BusinessType.LOGOUT)
public JsonResponse logout() { public JsonResponse logout() {
authService.logout(); authService.logout();
return JsonResponse.success("success"); return JsonResponse.success("success");
} }
@GetMapping("/detail") @GetMapping("/detail")
@Log(title = "管理员-详情", businessType = BusinessType.GET)
public JsonResponse detail() { public JsonResponse detail() {
AdminUser user = BCtx.getAdminUser(); AdminUser user = BCtx.getAdminUser();
HashMap<String, Boolean> permissions = backendBus.adminUserPermissions(user.getId()); HashMap<String, Boolean> permissions = backendBus.adminUserPermissions(user.getId());
@ -119,6 +124,7 @@ public class LoginController {
@BackendPermissionMiddleware(slug = BPermissionConstant.PASSWORD_CHANGE) @BackendPermissionMiddleware(slug = BPermissionConstant.PASSWORD_CHANGE)
@PutMapping("/password") @PutMapping("/password")
@Log(title = "管理员-密码修改", businessType = BusinessType.UPDATE)
public JsonResponse changePassword(@RequestBody @Validated PasswordChangeRequest req) { public JsonResponse changePassword(@RequestBody @Validated PasswordChangeRequest req) {
AdminUser user = BCtx.getAdminUser(); AdminUser user = BCtx.getAdminUser();
String password = HelperUtil.MD5(req.getOldPassword() + user.getSalt()); String password = HelperUtil.MD5(req.getOldPassword() + user.getSalt());

View File

@ -109,10 +109,10 @@ public class ResourceController {
data.put("admin_users", adminUsers); data.put("admin_users", adminUsers);
} }
if(!type.equals(BackendConstant.RESOURCE_TYPE_VIDEO) && if (!type.equals(BackendConstant.RESOURCE_TYPE_VIDEO)
!type.equals(BackendConstant.RESOURCE_TYPE_IMAGE)){ && !type.equals(BackendConstant.RESOURCE_TYPE_IMAGE)) {
filter.setType(BackendConstant.RESOURCE_TYPE_ATTACHMENT); filter.setType(BackendConstant.RESOURCE_TYPE_ATTACHMENT);
data.put("existing_types",resourceService.paginateType(filter)); data.put("existing_types", resourceService.paginateType(filter));
} }
return JsonResponse.data(data); return JsonResponse.data(data);
} }

View File

@ -120,13 +120,15 @@ public class UploadController {
url); url);
// 视频资源特殊处理--视频封面资源 // 视频资源特殊处理--视频封面资源
if(BackendConstant.RESOURCE_TYPE_VIDEO.equals(type)){ if (BackendConstant.RESOURCE_TYPE_VIDEO.equals(type)) {
// 视频封面素材保存 // 视频封面素材保存
Resource posterResource = uploadService.storeBase64Image(BCtx.getId(), req.getPoster(), null); Resource posterResource =
uploadService.storeBase64Image(BCtx.getId(), req.getPoster(), null);
// 视频的封面素材改为[隐藏 && 属于视频的子素材] // 视频的封面素材改为[隐藏 && 属于视频的子素材]
resourceService.changeParentId(posterResource.getId(), videoResource.getId()); resourceService.changeParentId(posterResource.getId(), videoResource.getId());
// 视频信息 // 视频信息
resourceService.storeResourceVideo(videoResource.getId(), req.getDuration(), posterResource.getUrl()); resourceService.storeResourceVideo(
videoResource.getId(), req.getDuration(), posterResource.getUrl());
} }
HashMap<String, Object> data = new HashMap<>(); HashMap<String, Object> data = new HashMap<>();

View File

@ -82,7 +82,10 @@ public class CourseController {
data.put( data.put(
"hours", "hours",
courseHours.stream() courseHours.stream()
.filter(courseHour -> BackendConstant.RESOURCE_TYPE_VIDEO.equals(courseHour.getType())) .filter(
courseHour ->
BackendConstant.RESOURCE_TYPE_VIDEO.equals(
courseHour.getType()))
.collect(Collectors.groupingBy(CourseHour::getChapterId))); .collect(Collectors.groupingBy(CourseHour::getChapterId)));
data.put("learn_record", userCourseRecordService.find(FCtx.getId(), course.getId())); data.put("learn_record", userCourseRecordService.find(FCtx.getId(), course.getId()));
data.put( data.put(
@ -92,7 +95,10 @@ public class CourseController {
data.put( data.put(
"attachments", "attachments",
courseHours.stream() courseHours.stream()
.filter(courseHour -> BackendConstant.RESOURCE_TYPE_ATTACHMENT.contains(courseHour.getType())) .filter(
courseHour ->
BackendConstant.RESOURCE_TYPE_ATTACHMENT.contains(
courseHour.getType()))
.collect(Collectors.groupingBy(CourseHour::getChapterId))); .collect(Collectors.groupingBy(CourseHour::getChapterId)));
return JsonResponse.data(data); return JsonResponse.data(data);
} }

View File

@ -146,7 +146,8 @@ public class AdminLog implements Serializable {
result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode()); result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode());
result = prime * result + ((getOpt() == null) ? 0 : getOpt().hashCode()); result = prime * result + ((getOpt() == null) ? 0 : getOpt().hashCode());
result = prime * result + ((getMethod() == null) ? 0 : getMethod().hashCode()); result = prime * result + ((getMethod() == null) ? 0 : getMethod().hashCode());
result = prime * result + ((getRequestMethod() == null) ? 0 : getRequestMethod().hashCode()); result =
prime * result + ((getRequestMethod() == null) ? 0 : getRequestMethod().hashCode());
result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode()); result = prime * result + ((getUrl() == null) ? 0 : getUrl().hashCode());
result = prime * result + ((getParam() == null) ? 0 : getParam().hashCode()); result = prime * result + ((getParam() == null) ? 0 : getParam().hashCode());
result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode()); result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode());

View File

@ -16,6 +16,7 @@
package xyz.playedu.api.util; package xyz.playedu.api.util;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import java.util.*; import java.util.*;
@ -537,8 +538,8 @@ public class StringUtil extends org.apache.commons.lang3.StringUtils {
try { try {
Object jsonObj = JSONUtil.toJsonStr(o); Object jsonObj = JSONUtil.toJsonStr(o);
result.append(jsonObj.toString()); result.append(jsonObj.toString());
} catch (Exception e) {
} }
catch (Exception e) {}
} }
} }
} }