From aeb360bc8a4a92698e63c57690f99bf4901f66eb Mon Sep 17 00:00:00 2001 From: Chuyaoyuan Date: Wed, 13 May 2026 19:16:34 +0800 Subject: [PATCH] Update admin UI overhaul, scores , tooltip/version fixes --- .../controller/AdminSystemController.java | 47 +++++- .../db/migration/V10__score_system.sql | 8 +- .../resources/templates/admin/admin-shell.ftl | 154 +++++++++++++++--- src/main/resources/templates/admin/home.ftl | 87 ++++++---- src/main/resources/templates/admin/scores.ftl | 75 +++++++++ src/main/resources/templates/index.ftl | 4 +- 6 files changed, 307 insertions(+), 68 deletions(-) create mode 100644 src/main/resources/templates/admin/scores.ftl diff --git a/src/main/java/com/yaoyuan/jiscuss/controller/AdminSystemController.java b/src/main/java/com/yaoyuan/jiscuss/controller/AdminSystemController.java index 08d25b1..e2626dd 100644 --- a/src/main/java/com/yaoyuan/jiscuss/controller/AdminSystemController.java +++ b/src/main/java/com/yaoyuan/jiscuss/controller/AdminSystemController.java @@ -55,6 +55,7 @@ public class AdminSystemController extends BaseController { private final UpgradeLogRepository upgradeLogRepository; private final AuditLogRepository auditLogRepository; private final AuditLogService auditLogService; + private final com.yaoyuan.jiscuss.service.IScoreService scoreService; public AdminSystemController( UsersRepository usersRepository, @@ -65,7 +66,8 @@ public class AdminSystemController extends BaseController { UserRoleRepository userRoleRepository, UpgradeLogRepository upgradeLogRepository, AuditLogRepository auditLogRepository, - AuditLogService auditLogService) { + AuditLogService auditLogService, + com.yaoyuan.jiscuss.service.IScoreService scoreService) { this.usersRepository = usersRepository; this.discussionsRepository = discussionsRepository; this.postsRepository = postsRepository; @@ -75,6 +77,7 @@ public class AdminSystemController extends BaseController { this.upgradeLogRepository = upgradeLogRepository; this.auditLogRepository = auditLogRepository; this.auditLogService = auditLogService; + this.scoreService = scoreService; } @GetMapping("/admin/home") @@ -294,6 +297,27 @@ public class AdminSystemController extends BaseController { return "admin/themes"; } + /** 积分管理 — list all users sorted by score desc. */ + @GetMapping("/admin/scores") + public String scores(HttpServletRequest request, ModelMap map) { + fillCommon(request, map, "scores"); + List users = usersRepository.findAll(Sort.by(Sort.Direction.DESC, "score")); + map.put("users", users); + return "admin/scores"; + } + + /** Manually adjust a user's score (admin operation). */ + @PostMapping("/admin/scores/{id}/adjust") + public String adjustScore(@PathVariable Integer id, + @RequestParam int delta, + HttpServletRequest request) { + UserInfo operator = getUserInfo(request); + scoreService.addScore(id, delta); + auditLogService.log(operator, "score_adjust", "user", id, + "score " + (delta >= 0 ? "+" : "") + delta); + return "redirect:/admin/scores"; + } + private void fillCommon(HttpServletRequest request, ModelMap map, String active) { UserInfo user = getUserInfo(request); map.put("adminName", user == null ? "admin" : user.getUsername()); @@ -327,13 +351,30 @@ public class AdminSystemController extends BaseController { result.put("java", System.getProperty("java.version")); result.put("spring", implVersion("org.springframework.core.SpringVersion")); result.put("hibernate", implVersion("org.hibernate.Version")); - result.put("flyway", implVersion("org.flywaydb.core.Flyway")); - result.put("druid", implVersion("com.alibaba.druid.pool.DruidDataSource")); + result.put("flyway", mavenVersion("org.flywaydb", "flyway-core", + implVersion("org.flywaydb.core.Flyway"))); + result.put("druid", mavenVersion("com.alibaba", "druid-spring-boot-3-starter", + mavenVersion("com.alibaba", "druid", + implVersion("com.alibaba.druid.pool.DruidDataSource")))); result.put("ehcache", implVersion("org.ehcache.CacheManager")); result.put("springdoc", implVersion("org.springdoc.core.configuration.SpringDocConfiguration")); return result; } + /** Read version from META-INF/maven pom.properties (works in fat JARs). Falls back to {@code fallback}. */ + private String mavenVersion(String groupId, String artifactId, String fallback) { + String path = "/META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties"; + try (java.io.InputStream is = getClass().getResourceAsStream(path)) { + if (is != null) { + java.util.Properties props = new java.util.Properties(); + props.load(is); + String v = props.getProperty("version"); + if (v != null && !v.isBlank()) return v; + } + } catch (Exception ignored) {} + return fallback; + } + private String implVersion(String className) { try { Class clazz = Class.forName(className); diff --git a/src/main/resources/db/migration/V10__score_system.sql b/src/main/resources/db/migration/V10__score_system.sql index 5652e6d..3d4bcc0 100644 --- a/src/main/resources/db/migration/V10__score_system.sql +++ b/src/main/resources/db/migration/V10__score_system.sql @@ -1,6 +1,6 @@ -- V10: Add score column for the points/level system. -- score: cumulative activity points (default 0). --- level is already present; it will be recomputed by ScoreServiceImpl whenever score changes. +-- level is recomputed by ScoreServiceImpl whenever score changes. ALTER TABLE user ADD COLUMN score INTEGER NOT NULL DEFAULT 0; -- Back-fill an initial score for existing users based on their activity counts. @@ -8,9 +8,10 @@ ALTER TABLE user ADD COLUMN score INTEGER NOT NULL DEFAULT 0; UPDATE user SET score = COALESCE(discussions_count, 0) * 10 + COALESCE(comments_count, 0) * 5; --- Recompute level for all users based on back-filled score. +-- Recompute level for ALL users based on back-filled score. -- Thresholds: 0=新手(<50), 1=学徒(50-199), 2=熟手(200-499), -- 3=达人(500-999), 4=专家(1000-1999), 5=大神(>=2000) +-- Note: admin access is now RBAC-based; level is purely cosmetic. UPDATE user SET level = CASE WHEN score >= 2000 THEN 5 @@ -19,5 +20,4 @@ UPDATE user SET level = WHEN score >= 200 THEN 2 WHEN score >= 50 THEN 1 ELSE 0 - END -WHERE level = 0 OR level IS NULL; + END; diff --git a/src/main/resources/templates/admin/admin-shell.ftl b/src/main/resources/templates/admin/admin-shell.ftl index b27731e..a7ad920 100644 --- a/src/main/resources/templates/admin/admin-shell.ftl +++ b/src/main/resources/templates/admin/admin-shell.ftl @@ -9,46 +9,146 @@ ${title} <#include "admin/admin-commjs.ftl"/> -
-
-
Jiscuss 后台管理
-
当前管理员: ${adminName} | 接口文档 | 前台首页
+ +
+
+ logo + Jiscuss 后台管理 +
+
-
+ + + + + diff --git a/src/main/resources/templates/admin/home.ftl b/src/main/resources/templates/admin/home.ftl index 106aacf..68bface 100644 --- a/src/main/resources/templates/admin/home.ftl +++ b/src/main/resources/templates/admin/home.ftl @@ -1,50 +1,75 @@ <#import "admin/admin-shell.ftl" as shell> <@shell.page title="后台管理 - 总览" active=active adminName=adminName> -

系统总览

+

系统总览

-
-
用户总数
${userCount}
-
文章总数
${discussionCount}
-
评论总数
${postCount}
-
角色总数
${roleCount}
+
+
+
+
用户总数
+
${userCount}
+
+
+
+
+
文章总数
+
${discussionCount}
+
+
+
+
+
评论总数
+
${postCount}
+
+
+
+
+
角色总数
+
${roleCount}
+
+
-

服务器与运行时

-
-
+

服务器与运行时

+
+
-
CPU / 内存
+
CPU / 内存
-

CPU 负载: ${sys.cpuLoad}

-

JVM 已用内存: ${sys.usedMb} MB / ${sys.totalMb} MB

-

JVM 最大内存: ${sys.maxMb} MB

-

Heap 已用: ${sys.heapUsedMb} MB

-

应用运行时长: ${sys.uptimeMs} ms

+

CPU 负载  ${sys.cpuLoad}

+

JVM 已用  ${sys.usedMb} MB / ${sys.totalMb} MB

+

JVM 最大  ${sys.maxMb} MB

+

Heap 已用  ${sys.heapUsedMb} MB

+

运行时长  ${sys.uptimeMs} ms

-
+
-
关键依赖版本
+
关键依赖版本
-

Spring Boot: ${deps.springBoot}

-

Java: ${deps.java}

-

Spring: ${deps.spring}

-

Hibernate: ${deps.hibernate}

-

Flyway: ${deps.flyway}

-

Druid: ${deps.druid}

-

Ehcache: ${deps.ehcache}

-

SpringDoc: ${deps.springdoc}

+ + + + + + + + + +
Spring Boot${deps.springBoot}
Java${deps.java}
Spring${deps.spring}
Hibernate${deps.hibernate}
Flyway${deps.flyway}
Druid${deps.druid}
Ehcache${deps.ehcache}
SpringDoc${deps.springdoc}
-

快捷入口

-
- 用户与角色 - 文章管理 - 评论管理 - 接口文档 +

快捷入口

+ + diff --git a/src/main/resources/templates/admin/scores.ftl b/src/main/resources/templates/admin/scores.ftl new file mode 100644 index 0000000..3846f3d --- /dev/null +++ b/src/main/resources/templates/admin/scores.ftl @@ -0,0 +1,75 @@ +<#import "admin/admin-shell.ftl" as shell> +<@shell.page title="后台管理 - 积分管理" active=active adminName=adminName> +
+

积分管理

+ 共 ${users?size} 位用户 +
+ + <#assign lvlNames = ["新手","学徒","熟手","达人","专家","大神"]> + <#assign lvlColors = ["#95a5a6","#27ae60","#2980b9","#8e44ad","#e67e22","#e74c3c"]> + +
+
+ 等级阈值: + <#list 0..5 as i> + + + Lv.${i} ${lvlNames[i]} + + + <#if i==0><50<#elseif i==1>50–199<#elseif i==2>200–499 + <#elseif i==3>500–999<#elseif i==4>1000–1999<#else>≥2000 + + + +
+
+ + + + + + + + + + + + + + + + <#list users as u> + <#assign lvl = (u.level)!0> + <#assign lvlIdx = lvl?int> + <#if lvlIdx < 0><#assign lvlIdx = 0> + <#if lvlIdx > 5><#assign lvlIdx = 5> + + + + + + + + + + + + +
ID用户名真实姓名等级积分发帖回复手动调整积分
${u.id}${u.username!}${u.realname!'-'} + + Lv.${lvl} ${lvlNames[lvlIdx]} + + ${(u.score)!0}${(u.discussionsCount)!0}${(u.commentsCount)!0} +
+ + + +
+
+ diff --git a/src/main/resources/templates/index.ftl b/src/main/resources/templates/index.ftl index 6788999..cd0b217 100644 --- a/src/main/resources/templates/index.ftl +++ b/src/main/resources/templates/index.ftl @@ -333,9 +333,7 @@
- ${discussions.username}  •   + ${discussions.username}  •   最后由 ${discussions.usernameLast} 回复于${discussions.lastTime}.