diff --git a/backend/design/db_schema_pgsql.sql b/backend/design/db_schema_pgsql.sql
index d8b07de..833d00b 100644
--- a/backend/design/db_schema_pgsql.sql
+++ b/backend/design/db_schema_pgsql.sql
@@ -524,8 +524,8 @@ INSERT INTO sys_param ("param_id", "param_key", "param_value", "param_type", "st
INSERT INTO sys_param ("param_id", "param_key", "param_value", "param_type", "status", "is_system", "description", "is_deleted", "created_at", "updated_at") VALUES (1, 'security.token.access_ttl_minutes', '120', 'int', 1, 1, 'Access Token 有效期(分钟)', 0, '2026-02-09 09:54:21.888052', '2026-03-10 10:15:39.55035');
-INSERT INTO sys_user ("user_id", "username", "display_name", "email", "phone", "password_hash", "status", "is_deleted", "created_at", "updated_at", "is_platform_admin", "pwd_reset_required")
-VALUES (1, 'admin', '管理员', 'admin', NULL, '$2a$10$BOm1iCFj3ObfBeyQxOvjVO659vXvIRGOd4YR62r0TUHqSusWW5bFS', 1, 0, '2026-02-09 09:54:21.880637', '2026-02-28 17:57:32.63338', 't', NULL);
+INSERT INTO sys_user ( "username", "display_name", "email", "phone", "password_hash", "status", "is_deleted", "created_at", "updated_at", "is_platform_admin", "pwd_reset_required")
+VALUES ( 'admin', '管理员', 'admin', NULL, '$2a$10$BOm1iCFj3ObfBeyQxOvjVO659vXvIRGOd4YR62r0TUHqSusWW5bFS', 1, 0, '2026-02-09 09:54:21.880637', '2026-02-28 17:57:32.63338', 't', NULL);
INSERT INTO "sys_dict_type" ("dict_type_id", "type_code", "type_name", "status", "remark", "created_at", "updated_at") VALUES (9, 'biz_hotword_category', '热词类别', 1, '语音识别纠错分类', '2026-02-28 17:08:52.362532', '2026-02-28 17:08:52.362532');
diff --git a/backend/pom.xml b/backend/pom.xml
index 89e193b..4e8246b 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -124,6 +124,11 @@
jsoup
1.17.2
+
+ com.unisbase
+ unisbase-spring-boot-starter
+ 0.1.0
+
diff --git a/backend/src/main/java/com/imeeting/auth/JwtAuthenticationFilter.java b/backend/src/main/java/com/imeeting/auth/JwtAuthenticationFilter.java
deleted file mode 100644
index 85c6772..0000000
--- a/backend/src/main/java/com/imeeting/auth/JwtAuthenticationFilter.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.imeeting.auth;
-
-import com.imeeting.common.RedisKeys;
-import com.imeeting.entity.SysTenant;
-import com.imeeting.entity.SysUser;
-import com.imeeting.security.LoginUser;
-import com.imeeting.service.AuthScopeService;
-import com.imeeting.service.AuthVersionService;
-import com.imeeting.service.SysParamService;
-import com.imeeting.service.SysPermissionService;
-import com.imeeting.mapper.SysTenantMapper;
-import com.imeeting.mapper.SysUserMapper;
-import io.jsonwebtoken.Claims;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.Set;
-
-@Component
-public class JwtAuthenticationFilter extends OncePerRequestFilter {
- private final JwtTokenProvider jwtTokenProvider;
- private final SysPermissionService sysPermissionService;
- private final SysTenantMapper sysTenantMapper;
- private final SysUserMapper sysUserMapper;
- private final SysParamService sysParamService;
- private final StringRedisTemplate redisTemplate;
- private final AuthScopeService authScopeService;
- private final AuthVersionService authVersionService;
-
- public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider,
- @Lazy SysPermissionService sysPermissionService,
- SysTenantMapper sysTenantMapper,
- SysUserMapper sysUserMapper,
- @Lazy SysParamService sysParamService,
- StringRedisTemplate redisTemplate,
- AuthScopeService authScopeService,
- AuthVersionService authVersionService) {
- this.jwtTokenProvider = jwtTokenProvider;
- this.sysPermissionService = sysPermissionService;
- this.sysTenantMapper = sysTenantMapper;
- this.sysUserMapper = sysUserMapper;
- this.sysParamService = sysParamService;
- this.redisTemplate = redisTemplate;
- this.authScopeService = authScopeService;
- this.authVersionService = authVersionService;
- }
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- String uri = request.getRequestURI();
- // Skip filter for public endpoints
- if (uri.startsWith("/auth/") || uri.equals("/api/params/value")) {
- filterChain.doFilter(request, response);
- return;
- }
-
- String authHeader = request.getHeader("Authorization");
- if (authHeader != null && authHeader.startsWith("Bearer ")) {
- String token = authHeader.substring(7);
- try {
- Claims claims = jwtTokenProvider.parseToken(token);
- String username = claims.get("username", String.class);
- String displayName = claims.get("displayName", String.class);
- Long userId = claims.get("userId", Long.class);
- Long tenantId = claims.get("tenantId", Long.class);
- Number tokenAuthVersionNum = claims.get("authVersion", Number.class);
-
- if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
- // 1. Validate User Status (Ignore Tenant isolation here)
- SysUser user = sysUserMapper.selectByIdIgnoreTenant(userId);
- if (user == null || user.getStatus() != 1 || user.getIsDeleted() != 0) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"User account is disabled or deleted\"}");
- return;
- }
-
- // 2. Validate Tenant Status & Grace Period
- // Skip validation for system platform tenant (ID=0)
- Long activeTenantId = tenantId;
- if (activeTenantId != null && !Long.valueOf(0).equals(activeTenantId)) {
- SysTenant tenant = sysTenantMapper.selectByIdIgnoreTenant(activeTenantId);
- if (tenant == null || tenant.getStatus() != 1) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"Tenant is disabled\"}");
- return;
- }
-
- if (tenant.getExpireTime() != null) {
- LocalDateTime now = LocalDateTime.now();
- if (now.isAfter(tenant.getExpireTime())) {
- String graceDaysStr = sysParamService.getParamValue("sys.tenant.grace_period_days", "0");
- int graceDays = Integer.parseInt(graceDaysStr);
- if (now.isAfter(tenant.getExpireTime().plusDays(graceDays))) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"Tenant subscription expired\"}");
- return;
- }
- }
- }
- }
-
- long currentAuthVersion = authVersionService.getVersion(userId, activeTenantId);
- long requestAuthVersion = tokenAuthVersionNum == null ? 0L : tokenAuthVersionNum.longValue();
- if (currentAuthVersion != requestAuthVersion) {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"Token revoked\"}");
- return;
- }
-
- // 3. Get Permissions (With Redis Cache, Key must include tenantId)
- String permKey = RedisKeys.authPermKey(userId, activeTenantId, currentAuthVersion);
- Set permissions;
- String cachedPerms = redisTemplate.opsForValue().get(permKey);
- if (cachedPerms != null && !cachedPerms.trim().isEmpty()) {
- permissions = Set.of(cachedPerms.split(","));
- } else {
- permissions = sysPermissionService.listPermissionCodesByUserId(userId, activeTenantId);
- if (permissions != null && !permissions.isEmpty()) {
- redisTemplate.opsForValue().set(permKey, String.join(",", permissions), java.time.Duration.ofHours(2));
- } else {
- permissions = Collections.emptySet();
- }
- }
-
- boolean isTenantAdmin = authScopeService.isTenantAdmin(userId, activeTenantId);
- LoginUser loginUser = new LoginUser(userId, activeTenantId, username, displayName,user.getIsPlatformAdmin(), isTenantAdmin, permissions);
-
- UsernamePasswordAuthenticationToken authentication =
- new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
- authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(authentication);
- }
- } catch (io.jsonwebtoken.ExpiredJwtException e) {
- SecurityContextHolder.clearContext();
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"Token expired\"}");
- return;
- } catch (io.jsonwebtoken.JwtException e) {
- SecurityContextHolder.clearContext();
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.setContentType("application/json;charset=UTF-8");
- response.getWriter().write("{\"code\":\"401\",\"msg\":\"Invalid token\"}");
- return;
- } catch (Exception ignored) {
- SecurityContextHolder.clearContext();
- }
- }
- filterChain.doFilter(request, response);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/auth/JwtTokenProvider.java b/backend/src/main/java/com/imeeting/auth/JwtTokenProvider.java
deleted file mode 100644
index f8cc728..0000000
--- a/backend/src/main/java/com/imeeting/auth/JwtTokenProvider.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.imeeting.auth;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.Keys;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.nio.charset.StandardCharsets;
-import java.security.Key;
-import java.util.Date;
-import java.util.Map;
-
-@Component
-public class JwtTokenProvider {
- private final Key key;
-
- public JwtTokenProvider(@Value("${security.jwt.secret}") String secret) {
- this.key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
- }
-
- public String createToken(Map claims, long ttlMillis) {
- Date now = new Date();
- Date exp = new Date(now.getTime() + ttlMillis);
- return Jwts.builder()
- .setClaims(claims)
- .setIssuedAt(now)
- .setExpiration(exp)
- .signWith(key, SignatureAlgorithm.HS256)
- .compact();
- }
-
- public Claims parseToken(String token) {
- return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
- }
-}
diff --git a/backend/src/main/java/com/imeeting/auth/dto/CaptchaResponse.java b/backend/src/main/java/com/imeeting/auth/dto/CaptchaResponse.java
deleted file mode 100644
index 9a19ec8..0000000
--- a/backend/src/main/java/com/imeeting/auth/dto/CaptchaResponse.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.imeeting.auth.dto;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-@Data
-@AllArgsConstructor
-public class CaptchaResponse {
- private String captchaId;
- private String imageBase64;
-}
diff --git a/backend/src/main/java/com/imeeting/auth/dto/DeviceCodeRequest.java b/backend/src/main/java/com/imeeting/auth/dto/DeviceCodeRequest.java
deleted file mode 100644
index 0bc531d..0000000
--- a/backend/src/main/java/com/imeeting/auth/dto/DeviceCodeRequest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.imeeting.auth.dto;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-
-@Data
-public class DeviceCodeRequest {
- @NotBlank
- private String username;
- @NotBlank
- private String password;
- private String captchaId;
- private String captchaCode;
- private String deviceName;
-}
diff --git a/backend/src/main/java/com/imeeting/auth/dto/LoginRequest.java b/backend/src/main/java/com/imeeting/auth/dto/LoginRequest.java
deleted file mode 100644
index 43e8a6f..0000000
--- a/backend/src/main/java/com/imeeting/auth/dto/LoginRequest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.imeeting.auth.dto;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-
-@Data
-public class LoginRequest {
- private String tenantCode;
- @NotBlank
- private String username;
- @NotBlank
- private String password;
- private String captchaId;
- private String captchaCode;
- private String deviceCode;
-}
diff --git a/backend/src/main/java/com/imeeting/auth/dto/RefreshRequest.java b/backend/src/main/java/com/imeeting/auth/dto/RefreshRequest.java
deleted file mode 100644
index 2bb995b..0000000
--- a/backend/src/main/java/com/imeeting/auth/dto/RefreshRequest.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.imeeting.auth.dto;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-
-@Data
-public class RefreshRequest {
- @NotBlank
- private String refreshToken;
-}
diff --git a/backend/src/main/java/com/imeeting/auth/dto/TokenResponse.java b/backend/src/main/java/com/imeeting/auth/dto/TokenResponse.java
deleted file mode 100644
index 78f18b2..0000000
--- a/backend/src/main/java/com/imeeting/auth/dto/TokenResponse.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.imeeting.auth.dto;
-
-import lombok.Builder;
-import lombok.Data;
-import java.util.List;
-
-@Data
-@Builder
-public class TokenResponse {
- private String accessToken;
- private String refreshToken;
- private long accessExpiresInMinutes;
- private long refreshExpiresInDays;
- private Integer pwdResetRequired;
- private List availableTenants;
-
- @Data
- @Builder
- public static class TenantInfo {
- private Long tenantId;
- private String tenantCode;
- private String tenantName;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/common/ApiResponse.java b/backend/src/main/java/com/imeeting/common/ApiResponse.java
deleted file mode 100644
index 8a9b39b..0000000
--- a/backend/src/main/java/com/imeeting/common/ApiResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.imeeting.common;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class ApiResponse {
- private String code;
- private String msg;
- private T data;
-
- public static ApiResponse ok(T data) {
- return new ApiResponse<>("0", "OK", data);
- }
-
- public static ApiResponse error(String msg) {
- return new ApiResponse<>("-1", msg, null);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/common/GlobalExceptionHandler.java b/backend/src/main/java/com/imeeting/common/GlobalExceptionHandler.java
deleted file mode 100644
index c23c8c6..0000000
--- a/backend/src/main/java/com/imeeting/common/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.imeeting.common;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-@RestControllerAdvice
-public class GlobalExceptionHandler {
- private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
-
- @ExceptionHandler(IllegalArgumentException.class)
- public ApiResponse handleIllegalArgument(IllegalArgumentException ex) {
- log.warn("Business error: {}", ex.getMessage());
- return ApiResponse.error(ex.getMessage());
- }
-
- @ExceptionHandler(org.springframework.security.access.AccessDeniedException.class)
- public ApiResponse handleAccessDenied(org.springframework.security.access.AccessDeniedException ex) {
- log.warn("Access denied: {}", ex.getMessage());
- return ApiResponse.error("无权限操作");
- }
-
- @ExceptionHandler(Exception.class)
- public ApiResponse handleGeneric(Exception ex) {
- log.error("Unhandled exception", ex);
- return ApiResponse.error("系统异常");
- }
-}
diff --git a/backend/src/main/java/com/imeeting/common/PageResult.java b/backend/src/main/java/com/imeeting/common/PageResult.java
deleted file mode 100644
index c77de57..0000000
--- a/backend/src/main/java/com/imeeting/common/PageResult.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.common;
-
-import lombok.Data;
-
-@Data
-public class PageResult {
- private long total;
- private T records;
-}
diff --git a/backend/src/main/java/com/imeeting/common/annotation/Log.java b/backend/src/main/java/com/imeeting/common/annotation/Log.java
deleted file mode 100644
index b9fee6e..0000000
--- a/backend/src/main/java/com/imeeting/common/annotation/Log.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.imeeting.common.annotation;
-
-import java.lang.annotation.*;
-
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface Log {
- String value() default ""; // 操作描述
- String type() default ""; // 资源类型/模块名
-}
diff --git a/backend/src/main/java/com/imeeting/common/aspect/LogAspect.java b/backend/src/main/java/com/imeeting/common/aspect/LogAspect.java
deleted file mode 100644
index 80cf8ba..0000000
--- a/backend/src/main/java/com/imeeting/common/aspect/LogAspect.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.imeeting.common.aspect;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.imeeting.common.annotation.Log;
-import com.imeeting.entity.SysLog;
-import com.imeeting.security.LoginUser;
-import com.imeeting.service.SysLogService;
-import jakarta.servlet.http.HttpServletRequest;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-import java.lang.reflect.Method;
-import java.time.LocalDateTime;
-
-@Aspect
-@Component
-public class LogAspect {
-
- private final SysLogService sysLogService;
- private final ObjectMapper objectMapper;
-
- public LogAspect(SysLogService sysLogService, ObjectMapper objectMapper) {
- this.sysLogService = sysLogService;
- this.objectMapper = objectMapper;
- }
-
- @Around("@annotation(com.imeeting.common.annotation.Log)")
- public Object around(ProceedingJoinPoint point) throws Throwable {
- long start = System.currentTimeMillis();
- Object result = null;
- Exception exception = null;
-
- try {
- result = point.proceed();
- return result;
- } catch (Exception e) {
- exception = e;
- throw e;
- } finally {
- saveLog(point, result, exception, System.currentTimeMillis() - start);
- }
- }
-
- private void saveLog(ProceedingJoinPoint joinPoint, Object result, Exception e, long duration) {
- try {
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- if (attributes == null) return;
- HttpServletRequest request = attributes.getRequest();
-
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- Method method = signature.getMethod();
- Log logAnnotation = method.getAnnotation(Log.class);
-
- SysLog sysLog = new SysLog();
- sysLog.setLogType("OPERATION");
- sysLog.setOperation(logAnnotation.value());
- sysLog.setMethod(request.getMethod() + " " + request.getRequestURI());
- sysLog.setDuration(duration);
- sysLog.setIp(request.getRemoteAddr());
- sysLog.setCreatedAt(LocalDateTime.now());
-
- // 仅保留请求参数,移除响应结果
- sysLog.setParams(getArgsJson(joinPoint));
-
- // 获取当前租户和用户信息
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- LoginUser user = (LoginUser) auth.getPrincipal();
- sysLog.setUserId(user.getUserId());
- sysLog.setTenantId(user.getTenantId());
- sysLog.setUsername(user.getUsername());
- }
-
- sysLog.setStatus(e != null ? 0 : 1);
- sysLogService.recordLog(sysLog);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
-
- private String getArgsJson(ProceedingJoinPoint joinPoint) {
- try {
- Object[] args = joinPoint.getArgs();
- if (args == null || args.length == 0) return null;
-
- StringBuilder sb = new StringBuilder();
- for (Object arg : args) {
- if (arg instanceof jakarta.servlet.ServletRequest
- || arg instanceof jakarta.servlet.ServletResponse
- || arg instanceof org.springframework.web.multipart.MultipartFile) {
- continue;
- }
- try {
- sb.append(objectMapper.writeValueAsString(arg)).append(" ");
- } catch (Exception e) {
- sb.append("[Unserializable Argument] ");
- }
- }
- return sb.toString().trim();
- } catch (Exception e) {
- return "[Error capturing params]";
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/CacheConfig.java b/backend/src/main/java/com/imeeting/config/CacheConfig.java
deleted file mode 100644
index 08cf9f3..0000000
--- a/backend/src/main/java/com/imeeting/config/CacheConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.imeeting.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.redis.cache.RedisCacheConfiguration;
-import org.springframework.data.redis.cache.RedisCacheManager;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
-import org.springframework.data.redis.serializer.RedisSerializationContext;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-import java.time.Duration;
-
-@Configuration
-public class CacheConfig {
-
- @Bean
- public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
- RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
- .entryTtl(Duration.ofHours(1)) // Default TTL
- .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
- .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
- .disableCachingNullValues();
-
- return RedisCacheManager.builder(connectionFactory)
- .cacheDefaults(config)
- .build();
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/MybatisPlusConfig.java b/backend/src/main/java/com/imeeting/config/MybatisPlusConfig.java
deleted file mode 100644
index d92c137..0000000
--- a/backend/src/main/java/com/imeeting/config/MybatisPlusConfig.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.imeeting.config;
-
-import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
-import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
-import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
-import com.imeeting.security.LoginUser;
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.expression.LongValue;
-import org.apache.ibatis.reflection.MetaObject;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Configuration
-public class MybatisPlusConfig {
-
- @Bean
- public MybatisPlusInterceptor mybatisPlusInterceptor() {
- MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
- interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
- @Override
- public Expression getTenantId() {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- LoginUser user = (LoginUser) auth.getPrincipal();
- if (user.getTenantId() != null) {
- return new LongValue(user.getTenantId());
- }
- }
- // If no tenant context (e.g. system task or error), return 0
- return new LongValue(0);
- }
-
- @Override
- public String getTenantIdColumn() {
- return "tenant_id";
- }
-
- @Override
- public boolean ignoreTable(String tableName) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- LoginUser user = (LoginUser) auth.getPrincipal();
- // 只有当平台管理员处于系统租户(0)时,才忽略所有过滤。
- // 如果他切换到了具体租户(>0),则必须接受过滤,确保只能看到当前租户数据。
- if (Boolean.TRUE.equals(user.getIsPlatformAdmin()) && Long.valueOf(0).equals(user.getTenantId())) {
- return true;
- }
- }
-
- // 公共表始终忽略过滤
- return List.of("sys_tenant","sys_platform_config", "sys_user", "sys_tenant_user", "sys_permission", "sys_role_permission", "sys_user_role", "sys_dict_type", "sys_dict_item", "sys_param", "biz_speakers", "biz_prompt_templates", "biz_asr_models", "biz_llm_models", "biz_meetings", "biz_meeting_transcripts", "biz_ai_tasks").contains(tableName.toLowerCase());
- }
- }));
- interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
- return interceptor;
- }
-
- @Bean
- public MetaObjectHandler metaObjectHandler() {
- return new MetaObjectHandler() {
- @Override
- public void insertFill(MetaObject metaObject) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- LoginUser user = (LoginUser) auth.getPrincipal();
- strictInsertFill(metaObject, "tenantId", Long.class, user.getTenantId());
- } else {
- strictInsertFill(metaObject, "tenantId", Long.class, 0L);
- }
-
- strictInsertFill(metaObject, "createdAt", LocalDateTime::now, LocalDateTime.class);
- strictInsertFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
- strictInsertFill(metaObject, "status", () -> 1, Integer.class);
- strictInsertFill(metaObject, "isDeleted", () -> 0, Integer.class);
- }
-
- @Override
- public void updateFill(MetaObject metaObject) {
- strictUpdateFill(metaObject, "updatedAt", LocalDateTime::now, LocalDateTime.class);
- }
- };
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/SecurityConfig.java b/backend/src/main/java/com/imeeting/config/SecurityConfig.java
deleted file mode 100644
index c6f621d..0000000
--- a/backend/src/main/java/com/imeeting/config/SecurityConfig.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.imeeting.config;
-
-import com.imeeting.auth.JwtAuthenticationFilter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
-import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
-import java.util.List;
-
-@Configuration
-@EnableMethodSecurity
-public class SecurityConfig {
- @Bean
- public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception {
- http.csrf(csrf -> csrf.disable())
- .cors(cors -> cors.configurationSource(corsConfigurationSource()))
- .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .authorizeHttpRequests(auth -> auth
- .requestMatchers("/auth/**").permitAll()
- .requestMatchers("/api/open/**").permitAll()
- .requestMatchers("/api/static/**").permitAll()
- .requestMatchers("/api/params/value").permitAll()
- .anyRequest().authenticated()
- )
- .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
- return http.build();
- }
-
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- @Bean
- public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
- return configuration.getAuthenticationManager();
- }
-
- @Bean
- public CorsConfigurationSource corsConfigurationSource() {
- CorsConfiguration config = new CorsConfiguration();
- config.setAllowedOriginPatterns(List.of("*"));
- config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
- config.setAllowedHeaders(List.of("*"));
- config.setAllowCredentials(true);
-
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", config);
- return source;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/SysParamCacheInitializer.java b/backend/src/main/java/com/imeeting/config/SysParamCacheInitializer.java
deleted file mode 100644
index d73a664..0000000
--- a/backend/src/main/java/com/imeeting/config/SysParamCacheInitializer.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.imeeting.config;
-
-import com.imeeting.service.SysParamService;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.stereotype.Component;
-
-@Component
-public class SysParamCacheInitializer implements ApplicationRunner {
- private final SysParamService sysParamService;
-
- public SysParamCacheInitializer(SysParamService sysParamService) {
- this.sysParamService = sysParamService;
- }
-
- @Override
- public void run(ApplicationArguments args) {
- sysParamService.syncAllToCache();
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/WebConfig.java b/backend/src/main/java/com/imeeting/config/WebConfig.java
deleted file mode 100644
index 4e16405..0000000
--- a/backend/src/main/java/com/imeeting/config/WebConfig.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.imeeting.config;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-@Configuration
-public class WebConfig implements WebMvcConfigurer {
-
- @Value("${app.upload-path}")
- private String uploadPath;
-
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- String base = uploadPath.endsWith("/") ? uploadPath : uploadPath + "/";
- String audioPath = "file:" + base + "audio/";
-
- registry.addResourceHandler("/api/static/audio/**")
- .addResourceLocations(audioPath);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/config/WebMvcConfig.java b/backend/src/main/java/com/imeeting/config/WebMvcConfig.java
index 30f616d..6254a61 100644
--- a/backend/src/main/java/com/imeeting/config/WebMvcConfig.java
+++ b/backend/src/main/java/com/imeeting/config/WebMvcConfig.java
@@ -10,10 +10,10 @@ import java.io.File;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
- @Value("${app.upload-path}")
+ @Value("${unisbase.app.upload-path}")
private String uploadPath;
- @Value("${app.resource-prefix}")
+ @Value("${unisbase.app.resource-prefix}")
private String resourcePrefix;
@Override
diff --git a/backend/src/main/java/com/imeeting/controller/AuthController.java b/backend/src/main/java/com/imeeting/controller/AuthController.java
deleted file mode 100644
index be956cc..0000000
--- a/backend/src/main/java/com/imeeting/controller/AuthController.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.auth.JwtTokenProvider;
-import com.imeeting.auth.dto.CaptchaResponse;
-import com.imeeting.auth.dto.DeviceCodeRequest;
-import com.imeeting.auth.dto.LoginRequest;
-import com.imeeting.auth.dto.RefreshRequest;
-import com.imeeting.auth.dto.TokenResponse;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.common.SysParamKeys;
-import com.imeeting.service.SysParamService;
-import com.imeeting.service.AuthService;
-import com.wf.captcha.SpecCaptcha;
-import jakarta.validation.Valid;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.web.bind.annotation.*;
-
-import java.time.Duration;
-import java.util.UUID;
-
-@RestController
-@RequestMapping("/auth")
-public class AuthController {
- private final AuthService authService;
- private final StringRedisTemplate stringRedisTemplate;
- private final JwtTokenProvider jwtTokenProvider;
- private final SysParamService sysParamService;
-
- @Value("${app.captcha.ttl-seconds:120}")
- private long captchaTtlSeconds;
-
- public AuthController(AuthService authService, StringRedisTemplate stringRedisTemplate,
- JwtTokenProvider jwtTokenProvider, SysParamService sysParamService) {
- this.authService = authService;
- this.stringRedisTemplate = stringRedisTemplate;
- this.jwtTokenProvider = jwtTokenProvider;
- this.sysParamService = sysParamService;
- }
-
- @GetMapping("/captcha")
- public ApiResponse captcha() {
- if (!isCaptchaEnabled()) {
- return ApiResponse.error("Captcha disabled");
- }
- SpecCaptcha captcha = new SpecCaptcha(130, 48, 4);
- String code = captcha.text();
- String imageBase64 = captcha.toBase64();
- String captchaId = UUID.randomUUID().toString().replace("-", "");
-
- stringRedisTemplate.opsForValue().set(RedisKeys.captchaKey(captchaId), code, Duration.ofSeconds(captchaTtlSeconds));
- return ApiResponse.ok(new CaptchaResponse(captchaId, imageBase64));
- }
-
- @PostMapping("/device-code")
- public ApiResponse deviceCode(@Valid @RequestBody DeviceCodeRequest request) {
- LoginRequest loginRequest = new LoginRequest();
- loginRequest.setUsername(request.getUsername());
- loginRequest.setPassword(request.getPassword());
- loginRequest.setCaptchaId(request.getCaptchaId());
- loginRequest.setCaptchaCode(request.getCaptchaCode());
- String deviceCode = authService.createDeviceCode(loginRequest, request.getDeviceName());
- return ApiResponse.ok(deviceCode);
- }
-
- @PostMapping("/login")
- public ApiResponse login(@Valid @RequestBody LoginRequest request) {
- return ApiResponse.ok(authService.login(request));
- }
-
- @PostMapping("/refresh")
- public ApiResponse refresh(@Valid @RequestBody RefreshRequest request) {
- return ApiResponse.ok(authService.refresh(request.getRefreshToken()));
- }
-
- @PostMapping("/switch-tenant")
- public ApiResponse switchTenant(@RequestParam Long tenantId, @RequestHeader("Authorization") String authorization) {
- String token = authorization.replace("Bearer ", "");
- var claims = jwtTokenProvider.parseToken(token);
- Long userId = claims.get("userId", Long.class);
- String deviceCode = claims.get("deviceCode", String.class);
- return ApiResponse.ok(authService.switchTenant(userId, tenantId, deviceCode));
- }
-
- @PostMapping("/logout")
- public ApiResponse logout(@RequestHeader("Authorization") String authorization) {
- String token = authorization.replace("Bearer ", "");
- var claims = jwtTokenProvider.parseToken(token);
- Long userId = claims.get("userId", Long.class);
- String deviceCode = claims.get("deviceCode", String.class);
- authService.logout(userId, deviceCode);
- return ApiResponse.ok(null);
- }
-
- private boolean isCaptchaEnabled() {
- String value = sysParamService.getCachedParamValue(SysParamKeys.CAPTCHA_ENABLED, "true");
- return Boolean.parseBoolean(value);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/DeviceController.java b/backend/src/main/java/com/imeeting/controller/DeviceController.java
deleted file mode 100644
index 6c78616..0000000
--- a/backend/src/main/java/com/imeeting/controller/DeviceController.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.common.ApiResponse;
-import com.imeeting.entity.Device;
-import com.imeeting.service.DeviceService;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/devices")
-public class DeviceController {
- private final DeviceService deviceService;
-
- public DeviceController(DeviceService deviceService) {
- this.deviceService = deviceService;
- }
-
- @GetMapping
- public ApiResponse> list() {
- return ApiResponse.ok(deviceService.list());
- }
-
- @GetMapping("/{id}")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(deviceService.getById(id));
- }
-
- @PostMapping
- public ApiResponse create(@RequestBody Device device) {
- return ApiResponse.ok(deviceService.save(device));
- }
-
- @PutMapping("/{id}")
- public ApiResponse update(@PathVariable Long id, @RequestBody Device device) {
- device.setDeviceId(id);
- return ApiResponse.ok(deviceService.updateById(device));
- }
-
- @DeleteMapping("/{id}")
- public ApiResponse delete(@PathVariable Long id) {
- return ApiResponse.ok(deviceService.removeById(id));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/DictItemController.java b/backend/src/main/java/com/imeeting/controller/DictItemController.java
deleted file mode 100644
index a2eb120..0000000
--- a/backend/src/main/java/com/imeeting/controller/DictItemController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.entity.SysDictItem;
-import com.imeeting.service.SysDictItemService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/dict-items")
-public class DictItemController {
- private final SysDictItemService sysDictItemService;
-
- public DictItemController(SysDictItemService sysDictItemService) {
- this.sysDictItemService = sysDictItemService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys_dict:list')")
- public ApiResponse> list(@RequestParam(required = false) String typeCode) {
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- if (typeCode != null && !typeCode.isEmpty()) {
- queryWrapper.eq(SysDictItem::getTypeCode, typeCode);
- }
- queryWrapper.orderByAsc(SysDictItem::getSortOrder);
- return ApiResponse.ok(sysDictItemService.list(queryWrapper));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(sysDictItemService.getById(id));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys_dict:create')")
- public ApiResponse create(@RequestBody SysDictItem dictItem) {
- return ApiResponse.ok(sysDictItemService.save(dictItem));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:update')")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysDictItem dictItem) {
- dictItem.setDictItemId(id);
- return ApiResponse.ok(sysDictItemService.updateById(dictItem));
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:delete')")
- public ApiResponse delete(@PathVariable Long id) {
- return ApiResponse.ok(sysDictItemService.removeById(id));
- }
-
- @GetMapping("/type/{typeCode}")
-// @PreAuthorize("@ss.hasPermi('sys_dict:query')")
- public ApiResponse> getByType(@PathVariable String typeCode) {
- return ApiResponse.ok(sysDictItemService.getItemsByTypeCode(typeCode));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/DictTypeController.java b/backend/src/main/java/com/imeeting/controller/DictTypeController.java
deleted file mode 100644
index cc26c5d..0000000
--- a/backend/src/main/java/com/imeeting/controller/DictTypeController.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.entity.SysDictType;
-import com.imeeting.service.SysDictTypeService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/dict-types")
-public class DictTypeController {
- private final SysDictTypeService sysDictTypeService;
-
- public DictTypeController(SysDictTypeService sysDictTypeService) {
- this.sysDictTypeService = sysDictTypeService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys_dict:list')")
- public ApiResponse> list(
- @RequestParam(defaultValue = "1") Integer current,
- @RequestParam(defaultValue = "10") Integer size,
- @RequestParam(required = false) String typeCode,
- @RequestParam(required = false) String typeName) {
- Page page = new Page<>(current, size);
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- if (typeCode != null && !typeCode.isEmpty()) {
- queryWrapper.like(SysDictType::getTypeCode, typeCode);
- }
- if (typeName != null && !typeName.isEmpty()) {
- queryWrapper.like(SysDictType::getTypeName, typeName);
- }
- queryWrapper.orderByAsc(SysDictType::getTypeCode);
- return ApiResponse.ok(sysDictTypeService.page(page, queryWrapper));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(sysDictTypeService.getById(id));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys_dict:create')")
- public ApiResponse create(@RequestBody SysDictType dictType) {
- return ApiResponse.ok(sysDictTypeService.save(dictType));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:update')")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysDictType dictType) {
- dictType.setDictTypeId(id);
- return ApiResponse.ok(sysDictTypeService.updateById(dictType));
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_dict:delete')")
- public ApiResponse delete(@PathVariable Long id) {
- return ApiResponse.ok(sysDictTypeService.removeById(id));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/PermissionController.java b/backend/src/main/java/com/imeeting/controller/PermissionController.java
deleted file mode 100644
index e00c3c5..0000000
--- a/backend/src/main/java/com/imeeting/controller/PermissionController.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.common.ApiResponse;
-import com.imeeting.dto.PermissionNode;
-import com.imeeting.entity.SysPermission;
-import com.imeeting.entity.SysRole;
-import com.imeeting.mapper.SysRolePermissionMapper;
-import com.imeeting.mapper.SysUserRoleMapper;
-import com.imeeting.service.AuthVersionService;
-import com.imeeting.service.SysPermissionService;
-import com.imeeting.service.SysRoleService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@RestController
-@RequestMapping("/api/permissions")
-public class PermissionController {
- private final SysPermissionService sysPermissionService;
- private final SysRolePermissionMapper sysRolePermissionMapper;
- private final SysUserRoleMapper sysUserRoleMapper;
- private final SysRoleService sysRoleService;
- private final AuthVersionService authVersionService;
-
- public PermissionController(SysPermissionService sysPermissionService,
- SysRolePermissionMapper sysRolePermissionMapper, SysUserRoleMapper sysUserRoleMapper,
- SysRoleService sysRoleService, AuthVersionService authVersionService) {
- this.sysPermissionService = sysPermissionService;
- this.sysRolePermissionMapper = sysRolePermissionMapper;
- this.sysUserRoleMapper = sysUserRoleMapper;
- this.sysRoleService = sysRoleService;
- this.authVersionService = authVersionService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys:permission:list')")
- public ApiResponse> list() {
- Long tenantId = getCurrentTenantId();
- // 平台管理员查询所有
- if (Long.valueOf(0).equals(tenantId)) {
- return ApiResponse.ok(sysPermissionService.list());
- }
- // 非平台管理员只能查询自己拥有的权限
- return ApiResponse.ok(sysPermissionService.listByUserId(getCurrentUserId(), tenantId));
- }
-
- @GetMapping("/me")
- public ApiResponse> myPermissions() {
- return ApiResponse.ok(sysPermissionService.listByUserId(getCurrentUserId(), getCurrentTenantId()));
- }
-
- @GetMapping("/tree")
- @PreAuthorize("@ss.hasPermi('sys:permission:list')")
- public ApiResponse> tree() {
- Long tenantId = getCurrentTenantId();
- List list;
- if (Long.valueOf(0).equals(tenantId)) {
- list = sysPermissionService.list();
- } else {
- list = sysPermissionService.listByUserId(getCurrentUserId(), tenantId);
- }
- return ApiResponse.ok(buildTree(list));
- }
-
- @GetMapping("/tree/me")
- public ApiResponse> myTree() {
- return ApiResponse.ok(buildTree(sysPermissionService.listByUserId(getCurrentUserId(), getCurrentTenantId())));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:permission:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(sysPermissionService.getById(id));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys:permission:create')")
- public ApiResponse create(@RequestBody SysPermission perm) {
- String error = validateParent(perm);
- if (error != null) {
- return ApiResponse.error(error);
- }
- return ApiResponse.ok(sysPermissionService.save(perm));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:permission:update')")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysPermission perm) {
- List roleIds = sysRolePermissionMapper.selectRoleIdsByPermId(id);
- perm.setPermId(id);
- String error = validateParent(perm);
- if (error != null) {
- return ApiResponse.error(error);
- }
- boolean updated = sysPermissionService.updateById(perm);
- if (perm.getLevel() != null && perm.getLevel() == 1) {
- sysPermissionService.lambdaUpdate()
- .set(SysPermission::getParentId, null)
- .eq(SysPermission::getPermId, id)
- .update();
- }
- if (updated) {
- invalidateRoleUsers(roleIds);
- }
- return ApiResponse.ok(updated);
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:permission:delete')")
- public ApiResponse delete(@PathVariable Long id) {
- List roleIds = sysRolePermissionMapper.selectRoleIdsByPermId(id);
- boolean removed = sysPermissionService.removeById(id);
- if (removed) {
- invalidateRoleUsers(roleIds);
- }
- return ApiResponse.ok(removed);
- }
-
- private Long getCurrentUserId() {
- org.springframework.security.core.Authentication authentication = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && authentication.getPrincipal() instanceof com.imeeting.security.LoginUser) {
- return ((com.imeeting.security.LoginUser) authentication.getPrincipal()).getUserId();
- }
- return null;
- }
-
- private Long getCurrentTenantId() {
- org.springframework.security.core.Authentication authentication = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && authentication.getPrincipal() instanceof com.imeeting.security.LoginUser) {
- return ((com.imeeting.security.LoginUser) authentication.getPrincipal()).getTenantId();
- }
- return null;
- }
-
- private String validateParent(SysPermission perm) {
- if (perm.getLevel() == null) {
- return null;
- }
- if (perm.getPermType() != null && "button".equalsIgnoreCase(perm.getPermType())) {
- if (perm.getCode() == null || perm.getCode().trim().isEmpty()) {
- return "Code required for button permission";
- }
- }
- if (perm.getLevel() == 1) {
- perm.setParentId(null);
- return null;
- }
- if (perm.getLevel() == 2) {
- if (perm.getParentId() == null) {
- return "ParentId required for level 2";
- }
- SysPermission parent = sysPermissionService.getById(perm.getParentId());
- if (parent == null) {
- return "Parent not found";
- }
- if (parent.getLevel() == null || parent.getLevel() != 1) {
- return "Parent must be level 1";
- }
- }
- return null;
- }
-
- private List buildTree(List list) {
- Map map = new HashMap<>();
- List roots = new ArrayList<>();
- for (SysPermission p : list) {
- PermissionNode node = toNode(p);
- map.put(node.getPermId(), node);
- }
- for (PermissionNode node : map.values()) {
- Long parentId = node.getParentId();
- if (parentId != null && map.containsKey(parentId)) {
- map.get(parentId).getChildren().add(node);
- } else {
- roots.add(node);
- }
- }
- sortTree(roots);
- return roots;
- }
-
- private void sortTree(List nodes) {
- nodes.sort(Comparator.comparingInt(n -> n.getSortOrder() == null ? 0 : n.getSortOrder()));
- for (PermissionNode node : nodes) {
- if (node.getChildren() != null && !node.getChildren().isEmpty()) {
- sortTree(node.getChildren());
- }
- }
- }
-
- private PermissionNode toNode(SysPermission p) {
- PermissionNode node = new PermissionNode();
- node.setPermId(p.getPermId());
- node.setParentId(p.getParentId());
- node.setName(p.getName());
- node.setCode(p.getCode());
- node.setPermType(p.getPermType());
- node.setLevel(p.getLevel());
- node.setPath(p.getPath());
- node.setComponent(p.getComponent());
- node.setIcon(p.getIcon());
- node.setSortOrder(p.getSortOrder());
- node.setIsVisible(p.getIsVisible());
- node.setStatus(p.getStatus());
- node.setDescription(p.getDescription());
- node.setMeta(p.getMeta());
- return node;
- }
-
- private void invalidateRoleUsers(List roleIds) {
- if (roleIds == null || roleIds.isEmpty()) {
- return;
- }
- for (Long roleId : roleIds) {
- if (roleId == null) {
- continue;
- }
- SysRole role = sysRoleService.getById(roleId);
- if (role == null || role.getTenantId() == null) {
- continue;
- }
- List userIds = sysUserRoleMapper.selectUserIdsByRoleId(roleId);
- authVersionService.invalidateUsersTenantAuth(userIds, role.getTenantId());
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/PlatformConfigController.java b/backend/src/main/java/com/imeeting/controller/PlatformConfigController.java
deleted file mode 100644
index 986feea..0000000
--- a/backend/src/main/java/com/imeeting/controller/PlatformConfigController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.common.ApiResponse;
-import com.imeeting.dto.PlatformConfigVO;
-import com.imeeting.entity.SysPlatformConfig;
-import com.imeeting.service.SysPlatformConfigService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-@RestController
-@RequestMapping("/api")
-public class PlatformConfigController {
-
- private final SysPlatformConfigService platformConfigService;
-
- public PlatformConfigController(SysPlatformConfigService platformConfigService) {
- this.platformConfigService = platformConfigService;
- }
-
- /**
- * 公开配置接口 (用于登录页、favicon等)
- */
- @GetMapping("/open/platform/config")
- public ApiResponse getOpenConfig() {
- return ApiResponse.ok(platformConfigService.getConfig());
- }
-
- /**
- * 获取管理配置 (需要登录)
- */
- @GetMapping("/admin/platform/config")
- @PreAuthorize("isAuthenticated()")
- public ApiResponse getAdminConfig() {
- return ApiResponse.ok(platformConfigService.getConfig());
- }
-
- /**
- * 更新配置 (仅限平台管理员)
- */
- @PutMapping("/admin/platform/config")
- @PreAuthorize("hasRole('ADMIN') or @ss.hasPermi('sys_platform:config:update')")
- public ApiResponse updateConfig(@RequestBody SysPlatformConfig config) {
- return ApiResponse.ok(platformConfigService.updateConfig(config));
- }
-
- /**
- * 上传资源 (仅限平台管理员)
- */
- @PostMapping("/admin/platform/config/upload")
- @PreAuthorize("hasRole('ADMIN') or @ss.hasPermi('sys_platform:config:update')")
- public ApiResponse upload(@RequestParam("file") MultipartFile file) {
- return ApiResponse.ok(platformConfigService.uploadAsset(file));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/RoleController.java b/backend/src/main/java/com/imeeting/controller/RoleController.java
deleted file mode 100644
index 5a80bbc..0000000
--- a/backend/src/main/java/com/imeeting/controller/RoleController.java
+++ /dev/null
@@ -1,344 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.annotation.Log;
-import com.imeeting.entity.SysRole;
-import com.imeeting.entity.SysRolePermission;
-import com.imeeting.entity.SysUser;
-import com.imeeting.entity.SysUserRole;
-import com.imeeting.mapper.SysRolePermissionMapper;
-import com.imeeting.mapper.SysUserRoleMapper;
-import com.imeeting.service.AuthScopeService;
-import com.imeeting.service.AuthVersionService;
-import com.imeeting.service.SysRoleService;
-import com.imeeting.service.SysUserService;
-import com.imeeting.service.SysPermissionService;
-import com.imeeting.service.SysTenantUserService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.Set;
-
-@RestController
-@RequestMapping("/api/roles")
-public class RoleController {
- private final SysRoleService sysRoleService;
- private final SysUserService sysUserService;
- private final SysRolePermissionMapper sysRolePermissionMapper;
- private final SysUserRoleMapper sysUserRoleMapper;
- private final SysPermissionService sysPermissionService;
- private final AuthScopeService authScopeService;
- private final AuthVersionService authVersionService;
- private final SysTenantUserService sysTenantUserService;
-
- public RoleController(SysRoleService sysRoleService, SysUserService sysUserService,
- SysRolePermissionMapper sysRolePermissionMapper, SysUserRoleMapper sysUserRoleMapper,
- SysPermissionService sysPermissionService,
- AuthScopeService authScopeService,
- AuthVersionService authVersionService,
- SysTenantUserService sysTenantUserService) {
- this.sysRoleService = sysRoleService;
- this.sysUserService = sysUserService;
- this.sysRolePermissionMapper = sysRolePermissionMapper;
- this.sysUserRoleMapper = sysUserRoleMapper;
- this.sysPermissionService = sysPermissionService;
- this.authScopeService = authScopeService;
- this.authVersionService = authVersionService;
- this.sysTenantUserService = sysTenantUserService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys:role:list')")
- public ApiResponse> list(@RequestParam(required = false) Long tenantId) {
- QueryWrapper wrapper = new QueryWrapper<>();
-
- if (authScopeService.isCurrentPlatformAdmin()) {
- if (tenantId != null) {
- wrapper.eq("tenant_id", tenantId);
- }
- } else {
- Long currentTenantId = getCurrentTenantId();
- wrapper.eq("tenant_id", currentTenantId);
- }
-
- return ApiResponse.ok(sysRoleService.list(wrapper));
- }
-
- @GetMapping("/{id}/users")
- @PreAuthorize("@ss.hasPermi('sys:role:query')")
- public ApiResponse> listUsers(@PathVariable Long id) {
- SysRole role = sysRoleService.getById(id);
- if (role == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(role.getTenantId())) {
- return ApiResponse.error("禁止跨租户查看角色用户");
- }
- return ApiResponse.ok(sysUserService.listUsersByRoleId(id));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:role:query')")
- public ApiResponse get(@PathVariable Long id) {
- SysRole role = sysRoleService.getById(id);
- if (role == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(role.getTenantId())) {
- return ApiResponse.error("禁止跨租户查看角色");
- }
- return ApiResponse.ok(role);
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys:role:create')")
- @Log(value = "新增角色", type = "角色管理")
- public ApiResponse create(@RequestBody SysRole role) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- if (!authScopeService.isCurrentPlatformAdmin()) {
- role.setTenantId(currentTenantId);
- } else if (role.getTenantId() == null) {
- return ApiResponse.error("tenantId required for platform role creation");
- }
- return ApiResponse.ok(sysRoleService.save(role));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:role:update')")
- @Log(value = "修改角色", type = "角色管理")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysRole role) {
- SysRole existing = sysRoleService.getById(id);
- if (existing == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(existing.getTenantId())) {
- return ApiResponse.error("禁止跨租户修改角色");
- }
- role.setRoleId(id);
- role.setTenantId(existing.getTenantId());
- return ApiResponse.ok(sysRoleService.updateById(role));
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:role:delete')")
- @Log(value = "删除角色", type = "角色管理")
- public ApiResponse delete(@PathVariable Long id) {
- SysRole existing = sysRoleService.getById(id);
- if (existing == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(existing.getTenantId())) {
- return ApiResponse.error("禁止跨租户删除角色");
- }
- if ("TENANT_ADMIN".equalsIgnoreCase(existing.getRoleCode()) && !authScopeService.isCurrentPlatformAdmin()) {
- return ApiResponse.error("租户管理员角色只能由平台管理员删除");
- }
- List userIds = sysUserRoleMapper.selectUserIdsByRoleId(id);
- boolean removed = sysRoleService.removeById(id);
- if (removed) {
- authVersionService.invalidateUsersTenantAuth(userIds, existing.getTenantId());
- }
- return ApiResponse.ok(removed);
- }
-
- @GetMapping("/{id}/permissions")
- @PreAuthorize("@ss.hasPermi('sys:role:permission:list')")
- public ApiResponse> listRolePermissions(@PathVariable Long id) {
- SysRole targetRole = sysRoleService.getById(id);
- if (targetRole == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(targetRole.getTenantId())) {
- return ApiResponse.error("禁止跨租户查看角色权限");
- }
- List rows = sysRolePermissionMapper.selectList(
- new QueryWrapper().eq("role_id", id)
- );
- List permIds = new ArrayList<>();
- for (SysRolePermission row : rows) {
- if (row.getPermId() != null) {
- permIds.add(row.getPermId());
- }
- }
- return ApiResponse.ok(permIds);
- }
-
- @PostMapping("/{id}/permissions")
- @PreAuthorize("@ss.hasPermi('sys:role:permission:save')")
- @Transactional(rollbackFor = Exception.class)
- public ApiResponse saveRolePermissions(@PathVariable Long id, @RequestBody PermissionBindingPayload payload) {
- List permIds = payload == null ? null : payload.getPermIds();
-
- // 权限越权校验
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- SysRole targetRole = sysRoleService.getById(id);
- if (targetRole == null) {
- return ApiResponse.error("角色不存在");
- }
-
- // 关键校验:只有平台管理员可以修改 TENANT_ADMIN 角色的权限
- if ("TENANT_ADMIN".equalsIgnoreCase(targetRole.getRoleCode())) {
- if (!authScopeService.isCurrentPlatformAdmin()) {
- return ApiResponse.error("租户管理员角色的权限只能由平台管理员修改");
- }
- }
- if (!canAccessTenant(targetRole.getTenantId())) {
- return ApiResponse.error("禁止跨租户修改角色权限");
- }
-
- if (!authScopeService.isCurrentPlatformAdmin()) {
- List myPerms = sysPermissionService.listByUserId(getCurrentUserId(), currentTenantId);
-
- Set myPermIds = myPerms.stream()
- .map(com.imeeting.entity.SysPermission::getPermId)
- .collect(Collectors.toSet());
-
- if (permIds != null) {
- for (Long pId : permIds) {
- if (!myPermIds.contains(pId)) {
- return ApiResponse.error("越权分配权限:" + pId);
- }
- }
- }
- }
-
- sysRolePermissionMapper.delete(new QueryWrapper().eq("role_id", id));
- if (permIds == null || permIds.isEmpty()) {
- authVersionService.invalidateUsersTenantAuth(sysUserRoleMapper.selectUserIdsByRoleId(id), targetRole.getTenantId());
- return ApiResponse.ok(true);
- }
- for (Long permId : permIds) {
- if (permId == null) {
- continue;
- }
- SysRolePermission item = new SysRolePermission();
- item.setRoleId(id);
- item.setPermId(permId);
- sysRolePermissionMapper.insert(item);
- }
- authVersionService.invalidateUsersTenantAuth(sysUserRoleMapper.selectUserIdsByRoleId(id), targetRole.getTenantId());
- return ApiResponse.ok(true);
- }
-
- @PostMapping("/{id}/users")
- @PreAuthorize("@ss.hasPermi('sys:role:update')")
- @Log(value = "角色关联用户", type = "角色管理")
- @Transactional(rollbackFor = Exception.class)
- public ApiResponse bindUsers(@PathVariable Long id, @RequestBody UserBindingPayload payload) {
- if (payload == null || payload.getUserIds() == null) {
- return ApiResponse.ok(true);
- }
- SysRole role = sysRoleService.getById(id);
- if (role == null || role.getRoleId() == null || role.getTenantId() == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(role.getTenantId())) {
- return ApiResponse.error("禁止跨租户绑定用户");
- }
-
- List toInsertUserIds = new ArrayList<>();
- for (Long userId : payload.getUserIds()) {
- if (userId == null) {
- continue;
- }
-
- // 修复:处理逻辑删除导致的唯一键冲突
- // 执行物理删除,彻底清除旧记录(包括已逻辑删除的)
- sysUserRoleMapper.physicalDelete(id, userId, role.getTenantId());
-
- // 确保该用户属于该租户
- boolean hasMembership = sysTenantUserService.count(
- new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper()
- .eq(com.imeeting.entity.SysTenantUser::getUserId, userId)
- .eq(com.imeeting.entity.SysTenantUser::getTenantId, role.getTenantId())
- ) > 0;
- if (!hasMembership) {
- return ApiResponse.error("用户不属于角色所在租户:" + role.getTenantId());
- }
- toInsertUserIds.add(userId);
- }
-
- for (Long userId : toInsertUserIds) {
- SysUserRole ur = new SysUserRole();
- ur.setTenantId(role.getTenantId());
- ur.setRoleId(id);
- ur.setUserId(userId);
- sysUserRoleMapper.insert(ur);
- authVersionService.invalidateUserTenantAuth(userId, role.getTenantId());
- }
- return ApiResponse.ok(true);
- }
-
- @DeleteMapping("/{id}/users/{userId}")
- @PreAuthorize("@ss.hasPermi('sys:role:update')")
- @Log(value = "角色取消关联用户", type = "角色管理")
- @Transactional(rollbackFor = Exception.class)
- public ApiResponse unbindUser(@PathVariable Long id, @PathVariable Long userId) {
- SysRole role = sysRoleService.getById(id);
- if (role == null || role.getRoleId() == null || role.getTenantId() == null) {
- return ApiResponse.error("角色不存在");
- }
- if (!canAccessTenant(role.getTenantId())) {
- return ApiResponse.error("禁止跨租户解绑用户");
- }
- sysUserRoleMapper.physicalDelete(id, userId, role.getTenantId());
- authVersionService.invalidateUserTenantAuth(userId, role.getTenantId());
- return ApiResponse.ok(true);
- }
-
- private Long getCurrentUserId() {
- org.springframework.security.core.Authentication authentication = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && authentication.getPrincipal() instanceof com.imeeting.security.LoginUser) {
- return ((com.imeeting.security.LoginUser) authentication.getPrincipal()).getUserId();
- }
- return null;
- }
-
- private Long getCurrentTenantId() {
- org.springframework.security.core.Authentication authentication = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && authentication.getPrincipal() instanceof com.imeeting.security.LoginUser) {
- return ((com.imeeting.security.LoginUser) authentication.getPrincipal()).getTenantId();
- }
- return null;
- }
-
- private boolean canAccessTenant(Long targetTenantId) {
- if (targetTenantId == null) {
- return false;
- }
- if (authScopeService.isCurrentPlatformAdmin()) {
- return true;
- }
- Long currentTenantId = getCurrentTenantId();
- return currentTenantId != null && currentTenantId.equals(targetTenantId);
- }
-
- public static class UserBindingPayload {
- private List userIds;
- public List getUserIds() { return userIds; }
- public void setUserIds(List userIds) { this.userIds = userIds; }
- }
-
- public static class PermissionBindingPayload {
- private List permIds;
-
- public List getPermIds() {
- return permIds;
- }
-
- public void setPermIds(List permIds) {
- this.permIds = permIds;
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/SysLogController.java b/backend/src/main/java/com/imeeting/controller/SysLogController.java
deleted file mode 100644
index 88bdf08..0000000
--- a/backend/src/main/java/com/imeeting/controller/SysLogController.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.entity.SysLog;
-import com.imeeting.security.LoginUser;
-import com.imeeting.service.SysLogService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/logs")
-public class SysLogController {
- private final SysLogService sysLogService;
-
- public SysLogController(SysLogService sysLogService) {
- this.sysLogService = sysLogService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys_log:list')")
- public ApiResponse> list(
- @RequestParam(defaultValue = "1") Integer current,
- @RequestParam(defaultValue = "10") Integer size,
- @RequestParam(required = false) String username,
- @RequestParam(required = false) String logType,
- @RequestParam(required = false) String operation,
- @RequestParam(required = false) Integer status,
- @RequestParam(required = false) String startDate,
- @RequestParam(required = false) String endDate,
- @RequestParam(required = false) String sortField,
- @RequestParam(required = false) String sortOrder
- ) {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- LoginUser loginUser = (LoginUser) auth.getPrincipal();
-
- // 判定平台管理员: isPlatformAdmin=true 且 tenantId=0
- boolean isPlatformAdmin = Boolean.TRUE.equals(loginUser.getIsPlatformAdmin()) && Long.valueOf(0).equals(loginUser.getTenantId());
-
- QueryWrapper query = new QueryWrapper<>();
- // 只有联表查询才需要前缀 'l.'
- String prefix = isPlatformAdmin ? "l." : "";
-
- if (logType != null && !logType.isEmpty()) {
- query.eq(prefix + "log_type", logType);
- }
- if (username != null && !username.isEmpty()) {
- query.like(prefix + "username", username);
- }
- if (operation != null && !operation.isEmpty()) {
- query.like(prefix + "operation", operation);
- }
- if (status != null) {
- query.eq(prefix + "status", status);
- }
- if (startDate != null && !startDate.isEmpty()) {
- query.ge(prefix + "created_at", startDate + " 00:00:00");
- }
- if (endDate != null && !endDate.isEmpty()) {
- query.le(prefix + "created_at", endDate + " 23:59:59");
- }
-
- // 动态排序逻辑
- if (sortField != null && !sortField.isEmpty()) {
- String column = "created_at";
- if ("duration".equals(sortField)) column = "duration";
-
- if ("ascend".equals(sortOrder)) {
- query.orderByAsc(prefix + column);
- } else {
- query.orderByDesc(prefix + column);
- }
- } else {
- query.orderByDesc(prefix + "created_at");
- }
-
- if (isPlatformAdmin) {
- return ApiResponse.ok(sysLogService.selectPageWithTenant(new Page<>(current, size), query));
- } else {
- return ApiResponse.ok(sysLogService.page(new Page<>(current, size), query));
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/SysOrgController.java b/backend/src/main/java/com/imeeting/controller/SysOrgController.java
deleted file mode 100644
index a63efc1..0000000
--- a/backend/src/main/java/com/imeeting/controller/SysOrgController.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.annotation.Log;
-import com.imeeting.entity.SysOrg;
-import com.imeeting.service.SysOrgService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/orgs")
-public class SysOrgController {
- private final SysOrgService sysOrgService;
-
- public SysOrgController(SysOrgService sysOrgService) {
- this.sysOrgService = sysOrgService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys:org:list')")
- public ApiResponse> list(@RequestParam(required = false) Long tenantId) {
- return ApiResponse.ok(sysOrgService.listTree(tenantId));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:org:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(sysOrgService.getById(id));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys:org:create')")
- @Log(value = "新增组织", type = "组织管理")
- public ApiResponse create(@RequestBody SysOrg org) {
- return ApiResponse.ok(sysOrgService.save(org));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:org:update')")
- @Log(value = "修改组织", type = "组织管理")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysOrg org) {
- org.setId(id);
- return ApiResponse.ok(sysOrgService.updateById(org));
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:org:delete')")
- @Log(value = "删除组织", type = "组织管理")
- public ApiResponse delete(@PathVariable Long id) {
- // Check if has children
- long count = sysOrgService.count(new LambdaQueryWrapper().eq(SysOrg::getParentId, id));
- if (count > 0) {
- return ApiResponse.error("存在下级组织,无法删除");
- }
- return ApiResponse.ok(sysOrgService.removeById(id));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/SysParamController.java b/backend/src/main/java/com/imeeting/controller/SysParamController.java
deleted file mode 100644
index 733137c..0000000
--- a/backend/src/main/java/com/imeeting/controller/SysParamController.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.PageResult;
-import com.imeeting.dto.SysParamQueryDTO;
-import com.imeeting.dto.SysParamVO;
-import com.imeeting.entity.SysParam;
-import com.imeeting.service.SysParamService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RestController
-@RequestMapping("/api/params")
-public class SysParamController {
- private final SysParamService sysParamService;
-
- public SysParamController(SysParamService sysParamService) {
- this.sysParamService = sysParamService;
- }
-
- @GetMapping("/page")
- @PreAuthorize("@ss.hasPermi('sys_param:list')")
- public ApiResponse>> page(SysParamQueryDTO query) {
- return ApiResponse.ok(sysParamService.page(query));
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys_param:list')")
- public ApiResponse> list() {
- return ApiResponse.ok(sysParamService.list().stream().map(this::toVO).collect(Collectors.toList()));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_param:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(toVO(sysParamService.getById(id)));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys_param:create')")
- public ApiResponse create(@RequestBody SysParam param) {
- boolean saved = sysParamService.save(param);
- if (saved) {
- sysParamService.syncParamToCache(param);
- }
- return ApiResponse.ok(saved);
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_param:update')")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysParam param) {
- param.setParamId(id);
- boolean updated = sysParamService.updateById(param);
- if (updated) {
- sysParamService.syncParamToCache(param);
- }
- return ApiResponse.ok(updated);
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_param:delete')")
- public ApiResponse delete(@PathVariable Long id) {
- SysParam param = sysParamService.getById(id);
- boolean removed = sysParamService.removeById(id);
- if (removed && param != null) {
- sysParamService.deleteParamCache(param.getParamKey());
- }
- return ApiResponse.ok(removed);
- }
-
- @GetMapping("/value")
- public ApiResponse getValue(@RequestParam("key") String key,
- @RequestParam(value = "defaultValue", required = false) String defaultValue) {
- return ApiResponse.ok(sysParamService.getCachedParamValue(key, defaultValue));
- }
-
- private SysParamVO toVO(SysParam entity) {
- if (entity == null) return null;
- SysParamVO vo = new SysParamVO();
- vo.setParamId(entity.getParamId());
- vo.setParamKey(entity.getParamKey());
- vo.setParamValue(entity.getParamValue());
- vo.setParamType(entity.getParamType());
- vo.setIsSystem(entity.getIsSystem());
- vo.setDescription(entity.getDescription());
- vo.setStatus(entity.getStatus());
- vo.setCreatedAt(entity.getCreatedAt());
- vo.setUpdatedAt(entity.getUpdatedAt());
- return vo;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/SysTenantController.java b/backend/src/main/java/com/imeeting/controller/SysTenantController.java
deleted file mode 100644
index 79e4562..0000000
--- a/backend/src/main/java/com/imeeting/controller/SysTenantController.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.imeeting.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.annotation.Log;
-import com.imeeting.entity.SysTenant;
-import com.imeeting.service.SysTenantService;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/tenants")
-public class SysTenantController {
- private final SysTenantService sysTenantService;
-
- public SysTenantController(SysTenantService sysTenantService) {
- this.sysTenantService = sysTenantService;
- }
-
- @GetMapping
- @PreAuthorize("@ss.hasPermi('sys_tenant:list')")
- public ApiResponse> list(
- @RequestParam(defaultValue = "1") Integer current,
- @RequestParam(defaultValue = "10") Integer size,
- @RequestParam(required = false) String name,
- @RequestParam(required = false) String code
- ) {
- LambdaQueryWrapper query = new LambdaQueryWrapper<>();
- if (name != null && !name.isEmpty()) {
- query.like(SysTenant::getTenantName, name);
- }
- if (code != null && !code.isEmpty()) {
- query.like(SysTenant::getTenantCode, code);
- }
- query.orderByDesc(SysTenant::getCreatedAt);
- return ApiResponse.ok(sysTenantService.page(new Page<>(current, size), query));
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_tenant:query')")
- public ApiResponse get(@PathVariable Long id) {
- return ApiResponse.ok(sysTenantService.getById(id));
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys_tenant:create')")
- @Log(value = "新增租户", type = "租户管理")
- public ApiResponse create(@RequestBody com.imeeting.dto.CreateTenantDTO tenantDto) {
- return ApiResponse.ok(sysTenantService.createTenantWithAdmin(tenantDto));
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_tenant:update')")
- @Log(value = "修改租户", type = "租户管理")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysTenant tenant) {
- tenant.setId(id);
- return ApiResponse.ok(sysTenantService.updateById(tenant));
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys_tenant:delete')")
- @Log(value = "删除租户", type = "租户管理")
- public ApiResponse delete(@PathVariable Long id) {
- return ApiResponse.ok(sysTenantService.removeById(id));
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/UserController.java b/backend/src/main/java/com/imeeting/controller/UserController.java
deleted file mode 100644
index f4594e9..0000000
--- a/backend/src/main/java/com/imeeting/controller/UserController.java
+++ /dev/null
@@ -1,371 +0,0 @@
-package com.imeeting.controller;
-
-import com.imeeting.common.ApiResponse;
-import com.imeeting.dto.PasswordUpdateDTO;
-import com.imeeting.dto.UserProfile;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.imeeting.security.LoginUser;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.imeeting.entity.SysUser;
-import com.imeeting.entity.SysUserRole;
-import com.imeeting.mapper.SysUserRoleMapper;
-import com.imeeting.service.AuthScopeService;
-import com.imeeting.service.AuthVersionService;
-import com.imeeting.service.SysUserService;
-import com.imeeting.common.annotation.Log;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/users")
-public class UserController {
- private final SysUserService sysUserService;
- private final PasswordEncoder passwordEncoder;
- private final SysUserRoleMapper sysUserRoleMapper;
- private final com.imeeting.service.SysTenantUserService sysTenantUserService;
- private final com.imeeting.service.SysRoleService sysRoleService;
- private final AuthScopeService authScopeService;
- private final AuthVersionService authVersionService;
-
- public UserController(SysUserService sysUserService, PasswordEncoder passwordEncoder,
- SysUserRoleMapper sysUserRoleMapper,
- com.imeeting.service.SysTenantUserService sysTenantUserService,
- com.imeeting.service.SysRoleService sysRoleService,
- AuthScopeService authScopeService,
- AuthVersionService authVersionService) {
- this.sysUserService = sysUserService;
- this.passwordEncoder = passwordEncoder;
- this.sysUserRoleMapper = sysUserRoleMapper;
- this.sysTenantUserService = sysTenantUserService;
- this.sysRoleService = sysRoleService;
- this.authScopeService = authScopeService;
- this.authVersionService = authVersionService;
- }
-
- @GetMapping
-// @PreAuthorize("@ss.hasPermi('sys:user:list')")
- public ApiResponse> list(@RequestParam(required = false) Long tenantId, @RequestParam(required = false) Long orgId) {
- Long currentTenantId = getCurrentTenantId();
- List users;
- Long targetTenantId = null;
-
- if (Long.valueOf(0).equals(currentTenantId) && tenantId == null) {
- users = sysUserService.list();
- } else {
- targetTenantId = tenantId != null ? tenantId : currentTenantId;
- if (targetTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- users = sysUserService.listUsersByTenant(targetTenantId, orgId);
- }
-
- if (users != null && !users.isEmpty()) {
- for (SysUser user : users) {
- // 加载租户关系
- user.setMemberships(sysTenantUserService.listByUserId(user.getUserId()));
-
- // 加载角色信息
- QueryWrapper roleQuery = new QueryWrapper().eq("user_id", user.getUserId());
- if (targetTenantId != null) {
- roleQuery.eq("tenant_id", targetTenantId);
- }
- List userRoles = sysUserRoleMapper.selectList(roleQuery);
- if (userRoles != null && !userRoles.isEmpty()) {
- List roleIds = userRoles.stream()
- .map(SysUserRole::getRoleId)
- .collect(java.util.stream.Collectors.toList());
- user.setRoles(sysRoleService.listByIds(roleIds));
- }
- }
- }
- return ApiResponse.ok(users);
- }
-
- @GetMapping("/me")
- public ApiResponse me() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
- return ApiResponse.error("Unauthorized");
- }
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
- Long userId = loginUser.getUserId();
-
- SysUser user = sysUserService.getByIdIgnoreTenant(userId);
- if (user == null) {
- return ApiResponse.error("User not found");
- }
- UserProfile profile = new UserProfile();
- profile.setUserId(user.getUserId());
- profile.setUsername(user.getUsername());
- profile.setDisplayName(user.getDisplayName());
- profile.setEmail(user.getEmail());
- profile.setPhone(user.getPhone());
- profile.setStatus(user.getStatus());
- profile.setAdmin(userId == 1L);
- profile.setIsPlatformAdmin(user.getIsPlatformAdmin());
- profile.setIsTenantAdmin(loginUser.getIsTenantAdmin());
- profile.setPwdResetRequired(user.getPwdResetRequired());
- return ApiResponse.ok(profile);
- }
-
- @GetMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:user:query')")
- public ApiResponse get(@PathVariable Long id) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- if (!authScopeService.isCurrentPlatformAdmin() && !isUserInTenant(id, currentTenantId)) {
- return ApiResponse.error("禁止跨租户查看用户");
- }
- SysUser user = sysUserService.getByIdIgnoreTenant(id);
- if (user != null) {
- user.setMemberships(sysTenantUserService.listByUserId(id));
- }
- return ApiResponse.ok(user);
- }
-
- private Long getCurrentTenantId() {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- return ((LoginUser) auth.getPrincipal()).getTenantId();
- }
- return null;
- }
-
- @PostMapping
- @PreAuthorize("@ss.hasPermi('sys:user:create')")
- @Log(value = "新增用户", type = "用户管理")
- public ApiResponse create(@RequestBody SysUser user) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- // 非平台管理员强制设置为当前租户
- if (!Long.valueOf(0).equals(currentTenantId)) {
- if (user.getMemberships() != null && !user.getMemberships().isEmpty()) {
- user.getMemberships().forEach(m -> m.setTenantId(currentTenantId));
- } else {
- // 如果没传身份,补齐当前租户身份
- List memberships = new java.util.ArrayList<>();
- com.imeeting.entity.SysTenantUser m = new com.imeeting.entity.SysTenantUser();
- m.setTenantId(currentTenantId);
- memberships.add(m);
- user.setMemberships(memberships);
- }
- }
-
- if (user.getPasswordHash() != null && !user.getPasswordHash().isEmpty()) {
- user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash()));
- }
- boolean saved = sysUserService.save(user);
- if (saved) {
- sysTenantUserService.syncMemberships(user.getUserId(), user.getMemberships());
- }
- return ApiResponse.ok(saved);
- }
-
- @PutMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:user:update')")
- @Log(value = "修改用户", type = "用户管理")
- public ApiResponse update(@PathVariable Long id, @RequestBody SysUser user) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- user.setUserId(id);
- if (!authScopeService.isCurrentPlatformAdmin() && !isUserInTenant(id, currentTenantId)) {
- return ApiResponse.error("禁止跨租户修改用户");
- }
-
- // 非平台管理员强制约束租户身份
- if (!Long.valueOf(0).equals(currentTenantId)) {
- if (user.getMemberships() != null) {
- user.getMemberships().forEach(m -> m.setTenantId(currentTenantId));
- }
- }
-
- if (user.getPasswordHash() != null && !user.getPasswordHash().isEmpty()) {
- user.setPasswordHash(passwordEncoder.encode(user.getPasswordHash()));
- }
- boolean updated = sysUserService.updateById(user);
- if (updated) {
- sysTenantUserService.syncMemberships(id, user.getMemberships());
- }
- return ApiResponse.ok(updated);
- }
-
- @DeleteMapping("/{id}")
- @PreAuthorize("@ss.hasPermi('sys:user:delete')")
- @Log(value = "删除用户", type = "用户管理")
- public ApiResponse delete(@PathVariable Long id) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- if (!authScopeService.isCurrentPlatformAdmin() && !isUserInTenant(id, currentTenantId)) {
- return ApiResponse.error("禁止跨租户删除用户");
- }
- return ApiResponse.ok(sysUserService.removeById(id));
- }
-
- @PutMapping("/profile")
- public ApiResponse updateProfile(@RequestBody SysUser user) {
- Long userId = getCurrentUserId();
- SysUser existing = sysUserService.getByIdIgnoreTenant(userId);
- if (existing == null) return ApiResponse.error("用户不存在");
-
- existing.setDisplayName(user.getDisplayName());
- existing.setEmail(user.getEmail());
- existing.setPhone(user.getPhone());
- return ApiResponse.ok(sysUserService.updateById(existing));
- }
-
- @PutMapping("/password")
- public ApiResponse updatePassword(@RequestBody PasswordUpdateDTO dto) {
- Long userId = getCurrentUserId();
- SysUser user = sysUserService.getByIdIgnoreTenant(userId);
- if (user == null) return ApiResponse.error("用户不存在");
-
- if (!passwordEncoder.matches(dto.getOldPassword(), user.getPasswordHash())) {
- return ApiResponse.error("旧密码不正确");
- }
-
- user.setPasswordHash(passwordEncoder.encode(dto.getNewPassword()));
- user.setPwdResetRequired(0); // 重置标志位
- return ApiResponse.ok(sysUserService.updateById(user));
- }
-
- private Long getCurrentUserId() {
- Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- if (auth != null && auth.getPrincipal() instanceof LoginUser) {
- return ((LoginUser) auth.getPrincipal()).getUserId();
- }
- return null;
- }
-
- @GetMapping("/{id}/roles")
- @PreAuthorize("@ss.hasPermi('sys:user:role:list')")
- public ApiResponse> listUserRoles(@PathVariable Long id) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- if (!authScopeService.isCurrentPlatformAdmin() && !isUserInTenant(id, currentTenantId)) {
- return ApiResponse.error("禁止跨租户查看用户角色");
- }
- QueryWrapper query = new QueryWrapper().eq("user_id", id);
- if (!authScopeService.isCurrentPlatformAdmin()) {
- query.eq("tenant_id", currentTenantId);
- }
- List rows = sysUserRoleMapper.selectList(query);
- List roleIds = new ArrayList<>();
- for (SysUserRole row : rows) {
- if (row.getRoleId() != null) {
- roleIds.add(row.getRoleId());
- }
- }
- return ApiResponse.ok(roleIds);
- }
-
- @PostMapping("/{id}/roles")
- @PreAuthorize("@ss.hasPermi('sys:user:role:save')")
- @Transactional(rollbackFor = Exception.class)
- public ApiResponse saveUserRoles(@PathVariable Long id, @RequestBody RoleBindingPayload payload) {
- Long currentTenantId = getCurrentTenantId();
- if (currentTenantId == null) {
- return ApiResponse.error("Tenant ID required");
- }
- if (!authScopeService.isCurrentPlatformAdmin() && !isUserInTenant(id, currentTenantId)) {
- return ApiResponse.error("禁止跨租户分配角色");
- }
-
- List roleIds = payload == null ? null : payload.getRoleIds();
-
- List rolesToBind = new ArrayList<>();
- if (roleIds != null) {
- for (Long roleId : roleIds) {
- if (roleId == null) {
- continue;
- }
- com.imeeting.entity.SysRole role = sysRoleService.getById(roleId);
- if (role == null || role.getRoleId() == null || role.getTenantId() == null) {
- return ApiResponse.error("角色不存在:" + roleId);
- }
- Long roleTenantId = role.getTenantId();
- if (!authScopeService.isCurrentPlatformAdmin() && !currentTenantId.equals(roleTenantId)) {
- return ApiResponse.error("禁止跨租户分配角色:" + roleId);
- }
- boolean hasMembership = sysTenantUserService.count(
- new LambdaQueryWrapper()
- .eq(com.imeeting.entity.SysTenantUser::getUserId, id)
- .eq(com.imeeting.entity.SysTenantUser::getTenantId, roleTenantId)
- ) > 0;
- if (!hasMembership) {
- return ApiResponse.error("用户不属于角色所在租户:" + roleTenantId);
- }
- rolesToBind.add(role);
- }
- }
-
- QueryWrapper scopeQuery = new QueryWrapper().eq("user_id", id);
- if (!authScopeService.isCurrentPlatformAdmin()) {
- scopeQuery.eq("tenant_id", currentTenantId);
- }
- List existingRows = sysUserRoleMapper.selectList(scopeQuery);
- java.util.Set affectedTenantIds = new java.util.HashSet<>();
- for (SysUserRole row : existingRows) {
- if (row.getTenantId() != null) {
- affectedTenantIds.add(row.getTenantId());
- }
- }
- for (com.imeeting.entity.SysRole role : rolesToBind) {
- if (role.getTenantId() != null) {
- affectedTenantIds.add(role.getTenantId());
- }
- }
-
- sysUserRoleMapper.delete(scopeQuery);
- for (com.imeeting.entity.SysRole role : rolesToBind) {
- SysUserRole item = new SysUserRole();
- item.setTenantId(role.getTenantId());
- item.setUserId(id);
- item.setRoleId(role.getRoleId());
- sysUserRoleMapper.insert(item);
- }
- for (Long tenantId : affectedTenantIds) {
- authVersionService.invalidateUserTenantAuth(id, tenantId);
- }
- return ApiResponse.ok(true);
- }
-
- private boolean isUserInTenant(Long userId, Long tenantId) {
- if (userId == null || tenantId == null) {
- return false;
- }
- return sysTenantUserService.count(
- new LambdaQueryWrapper()
- .eq(com.imeeting.entity.SysTenantUser::getUserId, userId)
- .eq(com.imeeting.entity.SysTenantUser::getTenantId, tenantId)
- ) > 0;
- }
-
- public static class RoleBindingPayload {
- private List roleIds;
-
- public List getRoleIds() {
- return roleIds;
- }
-
- public void setRoleIds(List roleIds) {
- this.roleIds = roleIds;
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/controller/biz/AiModelController.java b/backend/src/main/java/com/imeeting/controller/biz/AiModelController.java
index ef47514..431efcb 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/AiModelController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/AiModelController.java
@@ -1,11 +1,13 @@
package com.imeeting.controller.biz;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.AiModelDTO;
import com.imeeting.dto.biz.AiModelVO;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.AiModelService;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.dto.PageResult;
+import com.unisbase.security.LoginUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
diff --git a/backend/src/main/java/com/imeeting/controller/biz/DashboardController.java b/backend/src/main/java/com/imeeting/controller/biz/DashboardController.java
index 42645f8..a4a022f 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/DashboardController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/DashboardController.java
@@ -1,9 +1,11 @@
package com.imeeting.controller.biz;
-import com.imeeting.common.ApiResponse;
+
import com.imeeting.dto.biz.MeetingVO;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.MeetingService;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.security.LoginUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
diff --git a/backend/src/main/java/com/imeeting/controller/biz/HotWordController.java b/backend/src/main/java/com/imeeting/controller/biz/HotWordController.java
index a7cd3dd..91f9982 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/HotWordController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/HotWordController.java
@@ -2,13 +2,15 @@ package com.imeeting.controller.biz;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.HotWordDTO;
import com.imeeting.dto.biz.HotWordVO;
import com.imeeting.entity.biz.HotWord;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.HotWordService;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.dto.PageResult;
+import com.unisbase.security.LoginUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
diff --git a/backend/src/main/java/com/imeeting/controller/biz/MeetingController.java b/backend/src/main/java/com/imeeting/controller/biz/MeetingController.java
index 3286dbd..d9d3e41 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/MeetingController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/MeetingController.java
@@ -1,7 +1,6 @@
package com.imeeting.controller.biz;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.PageResult;
+
import com.imeeting.common.RedisKeys;
import com.imeeting.dto.biz.MeetingDTO;
import com.imeeting.dto.biz.MeetingTranscriptVO;
@@ -10,11 +9,14 @@ import com.imeeting.dto.biz.RealtimeMeetingCompleteDTO;
import com.imeeting.dto.biz.RealtimeTranscriptItemDTO;
import com.imeeting.entity.biz.AiTask;
import com.imeeting.entity.biz.Meeting;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.AiTaskService;
import com.imeeting.service.biz.MeetingService;
import com.imeeting.service.biz.PromptTemplateService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.dto.PageResult;
+import com.unisbase.security.LoginUser;
import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -67,17 +69,20 @@ public class MeetingController {
private final PromptTemplateService promptTemplateService;
private final StringRedisTemplate redisTemplate;
private final String uploadPath;
+ private final String resourcePrefix;
public MeetingController(MeetingService meetingService,
AiTaskService aiTaskService,
PromptTemplateService promptTemplateService,
StringRedisTemplate redisTemplate,
- @Value("${app.upload-path}") String uploadPath) {
+ @Value("${unisbase.app.upload-path}") String uploadPath,
+ @Value("${unisbase.app.resource-prefix}") String resourcePrefix) {
this.meetingService = meetingService;
this.aiTaskService = aiTaskService;
this.promptTemplateService = promptTemplateService;
this.redisTemplate = redisTemplate;
this.uploadPath = uploadPath;
+ this.resourcePrefix = resourcePrefix;
}
@GetMapping("/{id}/progress")
@@ -120,8 +125,8 @@ public class MeetingController {
String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
file.transferTo(new File(uploadDir + fileName));
-
- return ApiResponse.ok("/api/static/audio/" + fileName);
+ String baseResourcePrefix = resourcePrefix.endsWith("/") ? resourcePrefix : resourcePrefix + "/";
+ return ApiResponse.ok(baseResourcePrefix+"audio/" + fileName);
}
@PostMapping
diff --git a/backend/src/main/java/com/imeeting/controller/biz/PromptTemplateController.java b/backend/src/main/java/com/imeeting/controller/biz/PromptTemplateController.java
index 4ac0c41..7d1c7a5 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/PromptTemplateController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/PromptTemplateController.java
@@ -1,12 +1,14 @@
package com.imeeting.controller.biz;
-import com.imeeting.common.ApiResponse;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.PromptTemplateDTO;
import com.imeeting.dto.biz.PromptTemplateVO;
import com.imeeting.entity.biz.PromptTemplate;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.PromptTemplateService;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.dto.PageResult;
+import com.unisbase.security.LoginUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
diff --git a/backend/src/main/java/com/imeeting/controller/biz/SpeakerController.java b/backend/src/main/java/com/imeeting/controller/biz/SpeakerController.java
index d7ca022..26b9389 100644
--- a/backend/src/main/java/com/imeeting/controller/biz/SpeakerController.java
+++ b/backend/src/main/java/com/imeeting/controller/biz/SpeakerController.java
@@ -1,12 +1,14 @@
package com.imeeting.controller.biz;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.imeeting.common.ApiResponse;
+
import com.imeeting.dto.biz.SpeakerRegisterDTO;
import com.imeeting.dto.biz.SpeakerVO;
import com.imeeting.entity.biz.Speaker;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.SpeakerService;
+import com.unisbase.common.ApiResponse;
+import com.unisbase.security.LoginUser;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
diff --git a/backend/src/main/java/com/imeeting/dto/CreateTenantDTO.java b/backend/src/main/java/com/imeeting/dto/CreateTenantDTO.java
deleted file mode 100644
index 0853c9a..0000000
--- a/backend/src/main/java/com/imeeting/dto/CreateTenantDTO.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-import java.time.LocalDateTime;
-
-@Data
-public class CreateTenantDTO {
- private String tenantCode;
- private String tenantName;
- private String contactName;
- private String contactPhone;
- private String remark;
- private LocalDateTime expireTime;
-}
diff --git a/backend/src/main/java/com/imeeting/dto/PasswordUpdateDTO.java b/backend/src/main/java/com/imeeting/dto/PasswordUpdateDTO.java
deleted file mode 100644
index cdba6fd..0000000
--- a/backend/src/main/java/com/imeeting/dto/PasswordUpdateDTO.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-
-@Data
-public class PasswordUpdateDTO {
- private String oldPassword;
- private String newPassword;
-}
diff --git a/backend/src/main/java/com/imeeting/dto/PermissionNode.java b/backend/src/main/java/com/imeeting/dto/PermissionNode.java
deleted file mode 100644
index 4ef177f..0000000
--- a/backend/src/main/java/com/imeeting/dto/PermissionNode.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Data
-public class PermissionNode {
- private Long permId;
- private Long parentId;
- private String name;
- private String code;
- private String permType;
- private Integer level;
- private String path;
- private String component;
- private String icon;
- private Integer sortOrder;
- private Integer isVisible;
- private Integer status;
- private String description;
- private String meta;
- private List children = new ArrayList<>();
-}
diff --git a/backend/src/main/java/com/imeeting/dto/PlatformConfigVO.java b/backend/src/main/java/com/imeeting/dto/PlatformConfigVO.java
deleted file mode 100644
index 68d08e5..0000000
--- a/backend/src/main/java/com/imeeting/dto/PlatformConfigVO.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-import java.time.LocalDateTime;
-
-@Data
-public class PlatformConfigVO {
- private String projectName;
- private String logoUrl;
- private String iconUrl;
- private String loginBgUrl;
- private String icpInfo;
- private String copyrightInfo;
- private String systemDescription;
-}
diff --git a/backend/src/main/java/com/imeeting/dto/SysParamQueryDTO.java b/backend/src/main/java/com/imeeting/dto/SysParamQueryDTO.java
deleted file mode 100644
index 1a098c5..0000000
--- a/backend/src/main/java/com/imeeting/dto/SysParamQueryDTO.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-
-@Data
-public class SysParamQueryDTO {
- private String paramKey;
- private String paramType;
- private String description;
- private Integer pageNum = 1;
- private Integer pageSize = 10;
-}
diff --git a/backend/src/main/java/com/imeeting/dto/SysParamVO.java b/backend/src/main/java/com/imeeting/dto/SysParamVO.java
deleted file mode 100644
index b00587a..0000000
--- a/backend/src/main/java/com/imeeting/dto/SysParamVO.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.imeeting.dto;
-
-import lombok.Data;
-import java.time.LocalDateTime;
-
-@Data
-public class SysParamVO {
- private Long paramId;
- private String paramKey;
- private String paramValue;
- private String paramType;
- private Integer isSystem;
- private String description;
- private Integer status;
- private LocalDateTime createdAt;
- private LocalDateTime updatedAt;
-}
diff --git a/backend/src/main/java/com/imeeting/dto/UserProfile.java b/backend/src/main/java/com/imeeting/dto/UserProfile.java
deleted file mode 100644
index 5211756..0000000
--- a/backend/src/main/java/com/imeeting/dto/UserProfile.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.imeeting.dto;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-@Data
-public class UserProfile {
- private Long userId;
- private String username;
- private String displayName;
- private String email;
- private String phone;
- private Integer status;
- @JsonProperty("isAdmin")
- private boolean isAdmin;
- private Boolean isPlatformAdmin;
- private Boolean isTenantAdmin;
- private Integer pwdResetRequired;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/BaseEntity.java b/backend/src/main/java/com/imeeting/entity/BaseEntity.java
deleted file mode 100644
index 31ab02c..0000000
--- a/backend/src/main/java/com/imeeting/entity/BaseEntity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Data
-public class BaseEntity {
- @TableField(fill = FieldFill.INSERT)
- private Long tenantId;
-
- private Integer status;
-
- @TableLogic(value = "0", delval = "1")
- private Integer isDeleted;
-
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createdAt;
-
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private LocalDateTime updatedAt;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/Device.java b/backend/src/main/java/com/imeeting/entity/Device.java
deleted file mode 100644
index 86bc039..0000000
--- a/backend/src/main/java/com/imeeting/entity/Device.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-@Data
-@TableName("device_info")
-public class Device extends BaseEntity {
- @TableId(value = "device_id", type = IdType.AUTO)
- private Long deviceId;
- private Long userId;
- private String deviceCode;
- private String deviceName;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysDictItem.java b/backend/src/main/java/com/imeeting/entity/SysDictItem.java
deleted file mode 100644
index 8c42b16..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysDictItem.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_dict_item")
-public class SysDictItem extends BaseEntity {
- @TableId(value = "dict_item_id", type = IdType.AUTO)
- private Long dictItemId;
- private String typeCode;
- private String itemLabel;
- private String itemValue;
- private Integer sortOrder;
- private String remark;
-
- @TableField(exist = false)
- private Long tenantId;
- @TableField(exist = false)
- private Integer isDeleted;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysDictType.java b/backend/src/main/java/com/imeeting/entity/SysDictType.java
deleted file mode 100644
index c4a285d..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysDictType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_dict_type")
-public class SysDictType extends BaseEntity {
- @TableId(value = "dict_type_id", type = IdType.AUTO)
- private Long dictTypeId;
- private String typeCode;
- private String typeName;
- private String remark;
-
- @TableField(exist = false)
- private Long tenantId;
- @TableField(exist = false)
- private Integer isDeleted;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysLog.java b/backend/src/main/java/com/imeeting/entity/SysLog.java
deleted file mode 100644
index a0c31d7..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysLog.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import java.time.LocalDateTime;
-
-@Data
-@TableName("sys_log")
-public class SysLog {
- @TableId(type = IdType.AUTO)
- private Long id;
- private Long tenantId;
- private Long userId;
- private String username;
- private String logType; // LOGIN, OPERATION
- private String operation;
- private String method;
- private String params;
- private Integer status;
- private String ip;
- private Long duration;
- private LocalDateTime createdAt;
-
- @TableField(exist = false)
- private String tenantName;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysOrg.java b/backend/src/main/java/com/imeeting/entity/SysOrg.java
deleted file mode 100644
index 603048d..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysOrg.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_org")
-public class SysOrg extends BaseEntity {
- @TableId(type = IdType.AUTO)
- private Long id;
-
- private Long tenantId;
- private Long parentId;
- private String orgName;
- private String orgCode;
- private String orgPath;
- private Integer sortOrder;
-
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysParam.java b/backend/src/main/java/com/imeeting/entity/SysParam.java
deleted file mode 100644
index b353014..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysParam.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_param")
-public class SysParam extends BaseEntity {
- @TableId(value = "param_id", type = IdType.AUTO)
- private Long paramId;
- private String paramKey;
- private String paramValue;
- private String paramType;
- private Integer isSystem;
- private String description;
-
- @TableField(exist = false)
- private Long tenantId;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysPermission.java b/backend/src/main/java/com/imeeting/entity/SysPermission.java
deleted file mode 100644
index a5b0d4c..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysPermission.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Data
-@TableName("sys_permission")
-public class SysPermission {
- @TableId(value = "perm_id", type = IdType.AUTO)
- private Long permId;
- private Long parentId;
- private String name;
- private String code;
- private String permType;
- private Integer level;
- private String path;
- private String component;
- private String icon;
- private Integer sortOrder;
- private Integer isVisible;
- private String description;
- private String meta;
- private Integer status;
-
- @TableLogic
- private Boolean isDeleted;
-
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createdAt;
-
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private LocalDateTime updatedAt;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysPlatformConfig.java b/backend/src/main/java/com/imeeting/entity/SysPlatformConfig.java
deleted file mode 100644
index 4eaaad3..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysPlatformConfig.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.annotation.TableField;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-
-@TableName("sys_platform_config")
-public class SysPlatformConfig {
- @TableId
- private Long id;
- private String projectName;
- private String logoUrl;
- private String iconUrl;
- private String loginBgUrl;
- private String icpInfo;
- private String copyrightInfo;
- private String systemDescription;
-
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysRole.java b/backend/src/main/java/com/imeeting/entity/SysRole.java
deleted file mode 100644
index fba0134..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysRole.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-@Data
-@TableName("sys_role")
-public class SysRole extends BaseEntity {
- @TableId(value = "role_id", type = IdType.AUTO)
- private Long roleId;
- private String roleCode;
- private String roleName;
- private String remark;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysRolePermission.java b/backend/src/main/java/com/imeeting/entity/SysRolePermission.java
deleted file mode 100644
index 09fd594..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysRolePermission.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Data
-@TableName("sys_role_permission")
-public class SysRolePermission {
- @TableId(value = "id", type = IdType.AUTO)
- private Long id;
- private Long roleId;
- private Long permId;
-
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createdAt;
-
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private LocalDateTime updatedAt;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysTenant.java b/backend/src/main/java/com/imeeting/entity/SysTenant.java
deleted file mode 100644
index c6ff789..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysTenant.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.time.LocalDateTime;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_tenant")
-public class SysTenant extends BaseEntity {
- @TableId(type = IdType.AUTO)
- private Long id;
- private String tenantCode;
- private String tenantName;
- private LocalDateTime expireTime;
- private String contactName;
- private String contactPhone;
- private String remark;
-
- @TableField(exist = false)
- private Long tenantId;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysTenantUser.java b/backend/src/main/java/com/imeeting/entity/SysTenantUser.java
deleted file mode 100644
index 2804114..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysTenantUser.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("sys_tenant_user")
-public class SysTenantUser extends BaseEntity {
- @TableId(type = IdType.AUTO)
- private Long id;
- private Long userId;
- private Long tenantId;
- private Long orgId;
-
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private String orgName;
-
- @com.baomidou.mybatisplus.annotation.TableLogic(value = "0", delval = "0")
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private Integer isDeleted;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysUser.java b/backend/src/main/java/com/imeeting/entity/SysUser.java
deleted file mode 100644
index 8ee5cd8..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysUser.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-@Data
-@TableName("sys_user")
-public class SysUser extends BaseEntity {
- @TableId(value = "user_id", type = IdType.AUTO)
- private Long userId;
- private String username;
- private String displayName;
- private String email;
- private String phone;
- private String passwordHash;
- private Integer pwdResetRequired;
-
- private Boolean isPlatformAdmin;
-
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private Long tenantId;
-
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private Long orgId;
-
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private java.util.List memberships;
-
- @com.baomidou.mybatisplus.annotation.TableField(exist = false)
- private java.util.List roles;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/SysUserRole.java b/backend/src/main/java/com/imeeting/entity/SysUserRole.java
deleted file mode 100644
index d417af3..0000000
--- a/backend/src/main/java/com/imeeting/entity/SysUserRole.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.imeeting.entity;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Data
-@TableName("sys_user_role")
-public class SysUserRole {
- @TableId(value = "id", type = IdType.AUTO)
- private Long id;
- private Long tenantId;
- private Long userId;
- private Long roleId;
- @TableLogic(value = "0", delval = "1")
- private Integer isDeleted;
-
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createdAt;
-
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private LocalDateTime updatedAt;
-}
diff --git a/backend/src/main/java/com/imeeting/entity/biz/AsrModel.java b/backend/src/main/java/com/imeeting/entity/biz/AsrModel.java
index 3aafd38..a562027 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/AsrModel.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/AsrModel.java
@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/entity/biz/HotWord.java b/backend/src/main/java/com/imeeting/entity/biz/HotWord.java
index 88a3efb..6a819f3 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/HotWord.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/HotWord.java
@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/entity/biz/LlmModel.java b/backend/src/main/java/com/imeeting/entity/biz/LlmModel.java
index ea375ca..b11486f 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/LlmModel.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/LlmModel.java
@@ -3,7 +3,7 @@ package com.imeeting.entity.biz;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/entity/biz/Meeting.java b/backend/src/main/java/com/imeeting/entity/biz/Meeting.java
index 32799dc..bd14bb1 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/Meeting.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/Meeting.java
@@ -4,13 +4,11 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
-import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
diff --git a/backend/src/main/java/com/imeeting/entity/biz/PromptTemplate.java b/backend/src/main/java/com/imeeting/entity/biz/PromptTemplate.java
index 37fd5df..8beaa33 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/PromptTemplate.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/PromptTemplate.java
@@ -3,7 +3,7 @@ package com.imeeting.entity.biz;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/entity/biz/PromptTemplateUserConfig.java b/backend/src/main/java/com/imeeting/entity/biz/PromptTemplateUserConfig.java
index 3655e41..6ed7ab7 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/PromptTemplateUserConfig.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/PromptTemplateUserConfig.java
@@ -3,7 +3,7 @@ package com.imeeting.entity.biz;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/entity/biz/Speaker.java b/backend/src/main/java/com/imeeting/entity/biz/Speaker.java
index 3f67416..cee54af 100644
--- a/backend/src/main/java/com/imeeting/entity/biz/Speaker.java
+++ b/backend/src/main/java/com/imeeting/entity/biz/Speaker.java
@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
-import com.imeeting.entity.BaseEntity;
+import com.unisbase.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/backend/src/main/java/com/imeeting/mapper/DeviceMapper.java b/backend/src/main/java/com/imeeting/mapper/DeviceMapper.java
deleted file mode 100644
index 0ef7005..0000000
--- a/backend/src/main/java/com/imeeting/mapper/DeviceMapper.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.Device;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface DeviceMapper extends BaseMapper {}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysDictItemMapper.java b/backend/src/main/java/com/imeeting/mapper/SysDictItemMapper.java
deleted file mode 100644
index 7cb3786..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysDictItemMapper.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysDictItem;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysDictItemMapper extends BaseMapper {
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysDictTypeMapper.java b/backend/src/main/java/com/imeeting/mapper/SysDictTypeMapper.java
deleted file mode 100644
index 0dad502..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysDictTypeMapper.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysDictType;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysDictTypeMapper extends BaseMapper {
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysLogMapper.java b/backend/src/main/java/com/imeeting/mapper/SysLogMapper.java
deleted file mode 100644
index f175016..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysLogMapper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.imeeting.entity.SysLog;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-
-@Mapper
-public interface SysLogMapper extends BaseMapper {
-
- @Override
- @InterceptorIgnore(tenantLine = "true")
- int insert(SysLog entity);
-
- @Select("SELECT l.*, t.tenant_name FROM sys_log l " +
- "LEFT JOIN sys_tenant t ON l.tenant_id = t.id " +
- "${ew.customSqlSegment}")
- IPage selectPageWithTenant(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysOrgMapper.java b/backend/src/main/java/com/imeeting/mapper/SysOrgMapper.java
deleted file mode 100644
index ffb6951..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysOrgMapper.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysOrg;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysOrgMapper extends BaseMapper {
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysParamMapper.java b/backend/src/main/java/com/imeeting/mapper/SysParamMapper.java
deleted file mode 100644
index 46722c3..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysParamMapper.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysParam;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysParamMapper extends BaseMapper {}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysPermissionMapper.java b/backend/src/main/java/com/imeeting/mapper/SysPermissionMapper.java
deleted file mode 100644
index d9c1490..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysPermissionMapper.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysPermission;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-
-import java.util.List;
-
-@Mapper
-public interface SysPermissionMapper extends BaseMapper {
- @com.baomidou.mybatisplus.annotation.InterceptorIgnore(tenantLine = "true")
- @Select("""
- SELECT DISTINCT p.*
- FROM sys_permission p
- JOIN sys_role_permission rp ON rp.perm_id = p.perm_id
- JOIN sys_role r ON r.role_id = rp.role_id
- JOIN sys_user_role ur ON ur.role_id = r.role_id
- WHERE p.is_deleted = 0
- AND r.is_deleted = 0
- AND ur.is_deleted = 0
- AND ur.user_id = #{userId}
- AND r.tenant_id = #{tenantId}
- AND (ur.tenant_id = #{tenantId} OR ur.tenant_id IS NULL)
- """)
- List selectByUserId(@Param("userId") Long userId, @Param("tenantId") Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysPlatformConfigMapper.java b/backend/src/main/java/com/imeeting/mapper/SysPlatformConfigMapper.java
deleted file mode 100644
index 1c6874f..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysPlatformConfigMapper.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysPlatformConfig;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysPlatformConfigMapper extends BaseMapper {
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysRoleMapper.java b/backend/src/main/java/com/imeeting/mapper/SysRoleMapper.java
deleted file mode 100644
index 8394c1e..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysRoleMapper.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysRole;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysRoleMapper extends BaseMapper {}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysRolePermissionMapper.java b/backend/src/main/java/com/imeeting/mapper/SysRolePermissionMapper.java
deleted file mode 100644
index 087169d..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysRolePermissionMapper.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysRolePermission;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-@Mapper
-public interface SysRolePermissionMapper extends BaseMapper {
- @Select("""
- SELECT DISTINCT role_id
- FROM sys_role_permission
- WHERE perm_id = #{permId}
- """)
- List selectRoleIdsByPermId(@Param("permId") Long permId);
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysTenantMapper.java b/backend/src/main/java/com/imeeting/mapper/SysTenantMapper.java
deleted file mode 100644
index 24a4e5d..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysTenantMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysTenant;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Param;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-
-@Mapper
-public interface SysTenantMapper extends BaseMapper {
- @InterceptorIgnore(tenantLine = "true")
- @Select("SELECT * FROM sys_tenant WHERE id = #{id}")
- SysTenant selectByIdIgnoreTenant(@Param("id") Long id);
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysTenantUserMapper.java b/backend/src/main/java/com/imeeting/mapper/SysTenantUserMapper.java
deleted file mode 100644
index bfd653b..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysTenantUserMapper.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysTenantUser;
-import org.apache.ibatis.annotations.Mapper;
-
-@Mapper
-public interface SysTenantUserMapper extends BaseMapper {
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysUserMapper.java b/backend/src/main/java/com/imeeting/mapper/SysUserMapper.java
deleted file mode 100644
index bf1a932..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysUserMapper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysUser;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Param;
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import java.util.List;
-
-@Mapper
-public interface SysUserMapper extends BaseMapper {
- @Select("""
- SELECT u.*
- FROM sys_user u
- JOIN sys_user_role ur ON u.user_id = ur.user_id
- WHERE ur.role_id = #{roleId}
- AND ur.is_deleted = 0
- AND u.is_deleted = 0
- """)
- List selectUsersByRoleId(@Param("roleId") Long roleId);
-
- @InterceptorIgnore(tenantLine = "true")
- @Select("SELECT * FROM sys_user WHERE username = #{username} AND is_deleted = 0")
- SysUser selectByUsernameIgnoreTenant(@Param("username") String username);
-
- @InterceptorIgnore(tenantLine = "true")
- @Select("SELECT * FROM sys_user WHERE user_id = #{userId} AND is_deleted = 0")
- SysUser selectByIdIgnoreTenant(@Param("userId") Long userId);
-
- @InterceptorIgnore(tenantLine = "true")
- @Select("")
- List selectUsersByTenant(@Param("tenantId") Long tenantId, @Param("orgId") Long orgId);
-
- @InterceptorIgnore(tenantLine = "true")
- @Select("""
- SELECT t.id as tenantId, t.tenant_code as tenantCode, t.tenant_name as tenantName
- FROM sys_tenant t
- JOIN sys_tenant_user tu ON t.id = tu.tenant_id
- JOIN sys_user u ON u.user_id = tu.user_id
- WHERE u.username = #{username} AND u.is_deleted = 0 AND t.is_deleted = 0
- ORDER BY t.id ASC
- """)
- List selectTenantsByUsername(@Param("username") String username);
-}
diff --git a/backend/src/main/java/com/imeeting/mapper/SysUserRoleMapper.java b/backend/src/main/java/com/imeeting/mapper/SysUserRoleMapper.java
deleted file mode 100644
index 611ee2e..0000000
--- a/backend/src/main/java/com/imeeting/mapper/SysUserRoleMapper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.imeeting.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.imeeting.entity.SysUserRole;
-import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import org.apache.ibatis.annotations.Delete;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-@Mapper
-public interface SysUserRoleMapper extends BaseMapper {
- @Delete("""
- DELETE FROM sys_user_role
- WHERE role_id = #{roleId} AND user_id = #{userId} AND tenant_id = #{tenantId}
- """)
- int physicalDelete(@Param("roleId") Long roleId, @Param("userId") Long userId, @Param("tenantId") Long tenantId);
-
- @InterceptorIgnore(tenantLine = "true")
- @Select("""
- SELECT COUNT(1)
- FROM sys_user_role ur
- JOIN sys_role r ON r.role_id = ur.role_id
- WHERE ur.user_id = #{userId}
- AND (ur.tenant_id = #{tenantId} OR ur.tenant_id IS NULL)
- AND ur.is_deleted = 0
- AND r.is_deleted = 0
- AND r.tenant_id = #{tenantId}
- AND r.role_code = 'TENANT_ADMIN'
- """)
- Long countTenantAdminRole(@Param("userId") Long userId, @Param("tenantId") Long tenantId);
-
- @Select("""
- SELECT DISTINCT ur.user_id
- FROM sys_user_role ur
- WHERE ur.role_id = #{roleId}
- AND ur.is_deleted = 0
- """)
- List selectUserIdsByRoleId(@Param("roleId") Long roleId);
-
- @Select("""
- SELECT ur.role_id
- FROM sys_user_role ur
- WHERE ur.user_id = #{userId}
- AND ur.tenant_id = #{tenantId}
- AND ur.is_deleted = 0
- """)
- List selectRoleIdsByUserIdAndTenantId(@Param("userId") Long userId, @Param("tenantId") Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/security/LoginUser.java b/backend/src/main/java/com/imeeting/security/LoginUser.java
deleted file mode 100644
index 34ba21b..0000000
--- a/backend/src/main/java/com/imeeting/security/LoginUser.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.imeeting.security;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Collection;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class LoginUser implements UserDetails {
- private Long userId;
- private Long tenantId;
- private String username;
- private String displayName;
- private Boolean isPlatformAdmin;
- private Boolean isTenantAdmin;
- private Set permissions;
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- if (permissions == null) return null;
- return permissions.stream()
- .map(SimpleGrantedAuthority::new)
- .collect(Collectors.toList());
- }
-
- @Override
- public String getPassword() {
- return null;
- }
-
- @Override
- public String getUsername() {
- return username;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return true;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/security/PermissionService.java b/backend/src/main/java/com/imeeting/security/PermissionService.java
deleted file mode 100644
index 814558e..0000000
--- a/backend/src/main/java/com/imeeting/security/PermissionService.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.imeeting.security;
-
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Set;
-
-@Service("ss")
-public class PermissionService {
-
- /**
- * 验证用户是否具备某权限
- *
- * @param permission 权限字符串
- * @return 用户是否具备某权限
- */
- public boolean hasPermi(String permission) {
- if (permission == null || permission.isEmpty()) {
- return false;
- }
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
- return false;
- }
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
- // 平台管理员在系统租户(0)下放行全部权限点
- if (Boolean.TRUE.equals(loginUser.getIsPlatformAdmin())
- && Long.valueOf(0L).equals(loginUser.getTenantId())) {
- return true;
- }
-
- Set permissions = loginUser.getPermissions();
- if (CollectionUtils.isEmpty(permissions)) {
- return false;
- }
-
- return permissions.contains(permission);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/AuthScopeService.java b/backend/src/main/java/com/imeeting/service/AuthScopeService.java
deleted file mode 100644
index 7a2f7ed..0000000
--- a/backend/src/main/java/com/imeeting/service/AuthScopeService.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.service;
-
-public interface AuthScopeService {
- boolean isCurrentPlatformAdmin();
-
- boolean isCurrentTenantAdmin();
-
- boolean isTenantAdmin(Long userId, Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/service/AuthService.java b/backend/src/main/java/com/imeeting/service/AuthService.java
deleted file mode 100644
index c409bf5..0000000
--- a/backend/src/main/java/com/imeeting/service/AuthService.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.imeeting.service;
-
-import com.imeeting.auth.dto.LoginRequest;
-import com.imeeting.auth.dto.TokenResponse;
-
-public interface AuthService {
- TokenResponse login(LoginRequest request);
- TokenResponse refresh(String refreshToken);
- void logout(Long userId, String deviceCode);
- String createDeviceCode(LoginRequest request, String deviceName);
- TokenResponse switchTenant(Long userId, Long targetTenantId, String deviceCode);
-}
diff --git a/backend/src/main/java/com/imeeting/service/AuthVersionService.java b/backend/src/main/java/com/imeeting/service/AuthVersionService.java
deleted file mode 100644
index b357393..0000000
--- a/backend/src/main/java/com/imeeting/service/AuthVersionService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.imeeting.service;
-
-import java.util.Collection;
-
-public interface AuthVersionService {
- long getVersion(Long userId, Long tenantId);
-
- void invalidateUserTenantAuth(Long userId, Long tenantId);
-
- void invalidateUsersTenantAuth(Collection userIds, Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/service/DeviceService.java b/backend/src/main/java/com/imeeting/service/DeviceService.java
deleted file mode 100644
index 7ba6150..0000000
--- a/backend/src/main/java/com/imeeting/service/DeviceService.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.Device;
-
-public interface DeviceService extends IService {}
diff --git a/backend/src/main/java/com/imeeting/service/SysDictItemService.java b/backend/src/main/java/com/imeeting/service/SysDictItemService.java
deleted file mode 100644
index fe012ac..0000000
--- a/backend/src/main/java/com/imeeting/service/SysDictItemService.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysDictItem;
-
-import java.util.List;
-
-public interface SysDictItemService extends IService {
- List getItemsByTypeCode(String typeCode);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysDictTypeService.java b/backend/src/main/java/com/imeeting/service/SysDictTypeService.java
deleted file mode 100644
index 734ee0f..0000000
--- a/backend/src/main/java/com/imeeting/service/SysDictTypeService.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysDictType;
-
-public interface SysDictTypeService extends IService {
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysLogService.java b/backend/src/main/java/com/imeeting/service/SysLogService.java
deleted file mode 100644
index dc7525a..0000000
--- a/backend/src/main/java/com/imeeting/service/SysLogService.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysLog;
-
-public interface SysLogService extends IService {
- void recordLog(SysLog log);
-
- IPage selectPageWithTenant(IPage page, Wrapper queryWrapper);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysOrgService.java b/backend/src/main/java/com/imeeting/service/SysOrgService.java
deleted file mode 100644
index f79b9e8..0000000
--- a/backend/src/main/java/com/imeeting/service/SysOrgService.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysOrg;
-import java.util.List;
-
-public interface SysOrgService extends IService {
- List listTree(Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysParamService.java b/backend/src/main/java/com/imeeting/service/SysParamService.java
deleted file mode 100644
index 8c04695..0000000
--- a/backend/src/main/java/com/imeeting/service/SysParamService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.common.PageResult;
-import com.imeeting.dto.SysParamQueryDTO;
-import com.imeeting.dto.SysParamVO;
-import com.imeeting.entity.SysParam;
-
-import java.util.List;
-
-public interface SysParamService extends IService {
- PageResult> page(SysParamQueryDTO query);
-
- String getParamValue(String key, String defaultValue);
-
- String getCachedParamValue(String key, String defaultValue);
-
- void syncParamToCache(SysParam param);
-
- void deleteParamCache(String key);
-
- void syncAllToCache();
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysPermissionService.java b/backend/src/main/java/com/imeeting/service/SysPermissionService.java
deleted file mode 100644
index e25eb54..0000000
--- a/backend/src/main/java/com/imeeting/service/SysPermissionService.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysPermission;
-
-import java.util.List;
-import java.util.Set;
-
-public interface SysPermissionService extends IService {
- List listByUserId(Long userId, Long tenantId);
-
- Set listPermissionCodesByUserId(Long userId, Long tenantId);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysPlatformConfigService.java b/backend/src/main/java/com/imeeting/service/SysPlatformConfigService.java
deleted file mode 100644
index 20d9fe5..0000000
--- a/backend/src/main/java/com/imeeting/service/SysPlatformConfigService.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysPlatformConfig;
-import com.imeeting.dto.PlatformConfigVO;
-import org.springframework.web.multipart.MultipartFile;
-
-public interface SysPlatformConfigService extends IService {
- PlatformConfigVO getConfig();
- boolean updateConfig(SysPlatformConfig config);
- String uploadAsset(MultipartFile file);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysRoleService.java b/backend/src/main/java/com/imeeting/service/SysRoleService.java
deleted file mode 100644
index e517220..0000000
--- a/backend/src/main/java/com/imeeting/service/SysRoleService.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysRole;
-
-public interface SysRoleService extends IService {}
diff --git a/backend/src/main/java/com/imeeting/service/SysTenantService.java b/backend/src/main/java/com/imeeting/service/SysTenantService.java
deleted file mode 100644
index 01b851f..0000000
--- a/backend/src/main/java/com/imeeting/service/SysTenantService.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.dto.CreateTenantDTO;
-import com.imeeting.entity.SysTenant;
-
-public interface SysTenantService extends IService {
- /**
- * 创建租户并自动初始化管理员、角色、组织及权限
- * @param dto 租户创建信息
- * @return 租户ID
- */
- Long createTenantWithAdmin(CreateTenantDTO dto);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysTenantUserService.java b/backend/src/main/java/com/imeeting/service/SysTenantUserService.java
deleted file mode 100644
index 7e869fc..0000000
--- a/backend/src/main/java/com/imeeting/service/SysTenantUserService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.entity.SysTenantUser;
-import java.util.List;
-
-public interface SysTenantUserService extends IService {
- List listByUserId(Long userId);
- void saveTenantUser(Long userId, Long tenantId, Long orgId);
- void syncMemberships(Long userId, List memberships);
-}
diff --git a/backend/src/main/java/com/imeeting/service/SysUserService.java b/backend/src/main/java/com/imeeting/service/SysUserService.java
deleted file mode 100644
index d01cae2..0000000
--- a/backend/src/main/java/com/imeeting/service/SysUserService.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-
-import com.imeeting.entity.SysUser;
-
-import java.util.List;
-
-
-
-public interface SysUserService extends IService {
-
- List listUsersByRoleId(Long roleId);
-
- SysUser getByIdIgnoreTenant(Long userId);
-
- List listUsersByTenant(Long tenantId, Long orgId);
-
- }
-
-
-
-
-
-
diff --git a/backend/src/main/java/com/imeeting/service/biz/AiModelService.java b/backend/src/main/java/com/imeeting/service/biz/AiModelService.java
index 63ba0e8..af9c0b1 100644
--- a/backend/src/main/java/com/imeeting/service/biz/AiModelService.java
+++ b/backend/src/main/java/com/imeeting/service/biz/AiModelService.java
@@ -1,8 +1,9 @@
package com.imeeting.service.biz;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.AiModelDTO;
import com.imeeting.dto.biz.AiModelVO;
+import com.unisbase.dto.PageResult;
import java.util.List;
diff --git a/backend/src/main/java/com/imeeting/service/biz/MeetingService.java b/backend/src/main/java/com/imeeting/service/biz/MeetingService.java
index 166a002..b9d286f 100644
--- a/backend/src/main/java/com/imeeting/service/biz/MeetingService.java
+++ b/backend/src/main/java/com/imeeting/service/biz/MeetingService.java
@@ -1,12 +1,13 @@
package com.imeeting.service.biz;
import com.baomidou.mybatisplus.extension.service.IService;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.MeetingDTO;
import com.imeeting.dto.biz.RealtimeTranscriptItemDTO;
import com.imeeting.dto.biz.MeetingTranscriptVO;
import com.imeeting.dto.biz.MeetingVO;
import com.imeeting.entity.biz.Meeting;
+import com.unisbase.dto.PageResult;
import java.util.List;
diff --git a/backend/src/main/java/com/imeeting/service/biz/PromptTemplateService.java b/backend/src/main/java/com/imeeting/service/biz/PromptTemplateService.java
index 9d1ae45..aa59449 100644
--- a/backend/src/main/java/com/imeeting/service/biz/PromptTemplateService.java
+++ b/backend/src/main/java/com/imeeting/service/biz/PromptTemplateService.java
@@ -4,15 +4,16 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.imeeting.dto.biz.PromptTemplateDTO;
import com.imeeting.dto.biz.PromptTemplateVO;
import com.imeeting.entity.biz.PromptTemplate;
-import com.imeeting.common.PageResult;
+import com.unisbase.dto.PageResult;
+
import java.util.List;
public interface PromptTemplateService extends IService {
PromptTemplateVO saveTemplate(PromptTemplateDTO dto, Long userId, Long tenantId);
PromptTemplateVO updateTemplate(PromptTemplateDTO dto);
- PageResult> pageTemplates(Integer current, Integer size, String name, String category,
- Long tenantId, Long userId, Boolean isPlatformAdmin, Boolean isTenantAdmin);
+ PageResult> pageTemplates(Integer current, Integer size, String name, String category,
+ Long tenantId, Long userId, Boolean isPlatformAdmin, Boolean isTenantAdmin);
boolean updateUserTemplateStatus(Long templateId, Integer status, Long tenantId, Long userId, Boolean isPlatformAdmin, Boolean isTenantAdmin);
boolean isTemplateEnabledForUser(Long templateId, Long tenantId, Long userId, Boolean isPlatformAdmin, Boolean isTenantAdmin);
}
diff --git a/backend/src/main/java/com/imeeting/service/biz/impl/AiModelServiceImpl.java b/backend/src/main/java/com/imeeting/service/biz/impl/AiModelServiceImpl.java
index 6205b4b..9a9ce84 100644
--- a/backend/src/main/java/com/imeeting/service/biz/impl/AiModelServiceImpl.java
+++ b/backend/src/main/java/com/imeeting/service/biz/impl/AiModelServiceImpl.java
@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.imeeting.common.PageResult;
+
import com.imeeting.dto.biz.AiModelDTO;
import com.imeeting.dto.biz.AiModelVO;
import com.imeeting.entity.biz.AsrModel;
@@ -13,6 +13,7 @@ import com.imeeting.entity.biz.LlmModel;
import com.imeeting.mapper.biz.AsrModelMapper;
import com.imeeting.mapper.biz.LlmModelMapper;
import com.imeeting.service.biz.AiModelService;
+import com.unisbase.dto.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
diff --git a/backend/src/main/java/com/imeeting/service/biz/impl/AiTaskServiceImpl.java b/backend/src/main/java/com/imeeting/service/biz/impl/AiTaskServiceImpl.java
index c209fe0..6605db0 100644
--- a/backend/src/main/java/com/imeeting/service/biz/impl/AiTaskServiceImpl.java
+++ b/backend/src/main/java/com/imeeting/service/biz/impl/AiTaskServiceImpl.java
@@ -4,20 +4,22 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+
import com.imeeting.common.RedisKeys;
import com.imeeting.dto.biz.AiModelVO;
-import com.imeeting.entity.SysUser;
import com.imeeting.entity.biz.AiTask;
import com.imeeting.entity.biz.HotWord;
import com.imeeting.entity.biz.Meeting;
import com.imeeting.entity.biz.MeetingTranscript;
-import com.imeeting.mapper.SysUserMapper;
import com.imeeting.mapper.biz.AiTaskMapper;
import com.imeeting.mapper.biz.MeetingMapper;
import com.imeeting.mapper.biz.MeetingTranscriptMapper;
import com.imeeting.service.biz.AiModelService;
import com.imeeting.service.biz.AiTaskService;
import com.imeeting.service.biz.HotWordService;
+
+import com.unisbase.entity.SysUser;
+import com.unisbase.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -54,10 +56,10 @@ public class AiTaskServiceImpl extends ServiceImpl impleme
private final HotWordService hotWordService;
private final StringRedisTemplate redisTemplate;
- @Value("${app.server-base-url}")
+ @Value("${unisbase.app.server-base-url}")
private String serverBaseUrl;
- @Value("${app.upload-path}")
+ @Value("${unisbase.app.upload-path}")
private String uploadPath;
private final HttpClient httpClient = HttpClient.newBuilder()
diff --git a/backend/src/main/java/com/imeeting/service/biz/impl/MeetingServiceImpl.java b/backend/src/main/java/com/imeeting/service/biz/impl/MeetingServiceImpl.java
index c202dd6..0467d4a 100644
--- a/backend/src/main/java/com/imeeting/service/biz/impl/MeetingServiceImpl.java
+++ b/backend/src/main/java/com/imeeting/service/biz/impl/MeetingServiceImpl.java
@@ -4,19 +4,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.common.PageResult;
+import com.unisbase.dto.PageResult;
import com.imeeting.dto.biz.MeetingDTO;
import com.imeeting.dto.biz.MeetingTranscriptVO;
import com.imeeting.dto.biz.MeetingVO;
import com.imeeting.dto.biz.RealtimeTranscriptItemDTO;
-import com.imeeting.entity.SysUser;
import com.imeeting.entity.biz.AiTask;
import com.imeeting.entity.biz.HotWord;
import com.imeeting.entity.biz.Meeting;
import com.imeeting.entity.biz.MeetingTranscript;
import com.imeeting.entity.biz.PromptTemplate;
import com.imeeting.event.MeetingCreatedEvent;
-import com.imeeting.mapper.SysUserMapper;
import com.imeeting.mapper.biz.AiTaskMapper;
import com.imeeting.mapper.biz.MeetingMapper;
import com.imeeting.mapper.biz.MeetingTranscriptMapper;
@@ -25,6 +23,8 @@ import com.imeeting.service.biz.AiTaskService;
import com.imeeting.service.biz.HotWordService;
import com.imeeting.service.biz.MeetingService;
import com.imeeting.service.biz.PromptTemplateService;
+import com.unisbase.entity.SysUser;
+import com.unisbase.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -59,7 +59,7 @@ public class MeetingServiceImpl extends ServiceImpl impl
private final SysUserMapper sysUserMapper;
private final ApplicationEventPublisher eventPublisher;
- @Value("${app.upload-path}")
+ @Value("${unisbase.app.upload-path}")
private String uploadPath;
@Override
diff --git a/backend/src/main/java/com/imeeting/service/biz/impl/PromptTemplateServiceImpl.java b/backend/src/main/java/com/imeeting/service/biz/impl/PromptTemplateServiceImpl.java
index 7ff6efb..94da8df 100644
--- a/backend/src/main/java/com/imeeting/service/biz/impl/PromptTemplateServiceImpl.java
+++ b/backend/src/main/java/com/imeeting/service/biz/impl/PromptTemplateServiceImpl.java
@@ -3,7 +3,7 @@ package com.imeeting.service.biz.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.common.PageResult;
+import com.unisbase.dto.PageResult;
import com.imeeting.dto.biz.PromptTemplateDTO;
import com.imeeting.dto.biz.PromptTemplateVO;
import com.imeeting.entity.biz.PromptTemplate;
diff --git a/backend/src/main/java/com/imeeting/service/biz/impl/SpeakerServiceImpl.java b/backend/src/main/java/com/imeeting/service/biz/impl/SpeakerServiceImpl.java
index 574e015..73f9316 100644
--- a/backend/src/main/java/com/imeeting/service/biz/impl/SpeakerServiceImpl.java
+++ b/backend/src/main/java/com/imeeting/service/biz/impl/SpeakerServiceImpl.java
@@ -7,9 +7,10 @@ import com.imeeting.dto.biz.SpeakerRegisterDTO;
import com.imeeting.dto.biz.SpeakerVO;
import com.imeeting.entity.biz.Speaker;
import com.imeeting.mapper.biz.SpeakerMapper;
-import com.imeeting.security.LoginUser;
+
import com.imeeting.service.biz.AiModelService;
import com.imeeting.service.biz.SpeakerService;
+import com.unisbase.security.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -35,13 +36,13 @@ import java.util.UUID;
@Service
public class SpeakerServiceImpl extends ServiceImpl implements SpeakerService {
- @Value("${app.upload-path}")
+ @Value("${unisbase.app.upload-path}")
private String uploadPath;
- @Value("${app.server-base-url}")
+ @Value("${unisbase.app.server-base-url}")
private String serverBaseUrl;
- @Value("${app.resource-prefix}")
+ @Value("${unisbase.app.resource-prefix}")
private String resourcePrefix;
private final AiModelService aiModelService;
diff --git a/backend/src/main/java/com/imeeting/service/impl/AuthScopeServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/AuthScopeServiceImpl.java
deleted file mode 100644
index 1d7b1f1..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/AuthScopeServiceImpl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.imeeting.mapper.SysUserRoleMapper;
-import com.imeeting.security.LoginUser;
-import com.imeeting.service.AuthScopeService;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Service;
-
-@Service
-public class AuthScopeServiceImpl implements AuthScopeService {
- private final SysUserRoleMapper sysUserRoleMapper;
-
- public AuthScopeServiceImpl(SysUserRoleMapper sysUserRoleMapper) {
- this.sysUserRoleMapper = sysUserRoleMapper;
- }
-
- @Override
- public boolean isCurrentPlatformAdmin() {
- LoginUser loginUser = getCurrentLoginUser();
- if (loginUser == null) {
- return false;
- }
- return Boolean.TRUE.equals(loginUser.getIsPlatformAdmin())
- && Long.valueOf(0L).equals(loginUser.getTenantId());
- }
-
- @Override
- public boolean isCurrentTenantAdmin() {
- LoginUser loginUser = getCurrentLoginUser();
- if (loginUser == null) {
- return false;
- }
- return isTenantAdmin(loginUser.getUserId(), loginUser.getTenantId());
- }
-
- @Override
- public boolean isTenantAdmin(Long userId, Long tenantId) {
- if (userId == null || tenantId == null || tenantId <= 0) {
- return false;
- }
- Long count = sysUserRoleMapper.countTenantAdminRole(userId, tenantId);
- return count != null && count > 0;
- }
-
- private LoginUser getCurrentLoginUser() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication == null || !(authentication.getPrincipal() instanceof LoginUser)) {
- return null;
- }
- return (LoginUser) authentication.getPrincipal();
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/AuthServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/AuthServiceImpl.java
deleted file mode 100644
index 639113c..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/AuthServiceImpl.java
+++ /dev/null
@@ -1,349 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.imeeting.auth.JwtTokenProvider;
-import com.imeeting.auth.dto.LoginRequest;
-import com.imeeting.auth.dto.TokenResponse;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.common.SysParamKeys;
-import com.imeeting.entity.Device;
-import com.imeeting.entity.SysLog;
-import com.imeeting.entity.SysUser;
-import com.imeeting.mapper.SysUserMapper;
-import com.imeeting.service.*;
-import io.jsonwebtoken.Claims;
-import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-@Service
-public class AuthServiceImpl implements AuthService {
- private final SysUserService sysUserService;
- private final SysUserMapper sysUserMapper;
- private final DeviceService deviceService;
- private final SysParamService sysParamService;
- private final StringRedisTemplate stringRedisTemplate;
- private final PasswordEncoder passwordEncoder;
- private final JwtTokenProvider jwtTokenProvider;
- private final AuthVersionService authVersionService;
- private final SysLogService sysLogService;
- private final HttpServletRequest httpServletRequest;
-
- @Value("${app.token.access-default-minutes:30}")
- private long accessDefaultMinutes;
- @Value("${app.token.refresh-default-days:7}")
- private long refreshDefaultDays;
- @Value("${app.captcha.max-attempts:5}")
- private int captchaMaxAttempts;
-
- public AuthServiceImpl(SysUserService sysUserService,
- SysUserMapper sysUserMapper,
- DeviceService deviceService,
- SysParamService sysParamService,
- StringRedisTemplate stringRedisTemplate,
- PasswordEncoder passwordEncoder,
- JwtTokenProvider jwtTokenProvider,
- AuthVersionService authVersionService,
- SysLogService sysLogService,
- HttpServletRequest httpServletRequest) {
- this.sysUserService = sysUserService;
- this.sysUserMapper = sysUserMapper;
- this.deviceService = deviceService;
- this.sysParamService = sysParamService;
- this.stringRedisTemplate = stringRedisTemplate;
- this.passwordEncoder = passwordEncoder;
- this.jwtTokenProvider = jwtTokenProvider;
- this.authVersionService = authVersionService;
- this.sysLogService = sysLogService;
- this.httpServletRequest = httpServletRequest;
- }
-
- @Override
- public TokenResponse login(LoginRequest request) {
- long start = System.currentTimeMillis();
- try {
- if (isCaptchaEnabled()) {
- validateCaptcha(request.getCaptchaId(), request.getCaptchaCode());
- }
-
- SysUser user = sysUserMapper.selectByUsernameIgnoreTenant(request.getUsername());
-
- if (user == null || user.getStatus() != 1 || !passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
- throw new IllegalArgumentException("用户名或密码错误");
- }
-
- // 获取该用户关联的所有租户
- java.util.List availableTenants = sysUserMapper.selectTenantsByUsername(user.getUsername());
-
- // 如果是平台管理员,且没有在租户列表中,手动添加系统租户(ID=0)
- if (Boolean.TRUE.equals(user.getIsPlatformAdmin())) {
- boolean hasSystemTenant = availableTenants.stream().anyMatch(t -> t.getTenantId() == 0L);
- if (!hasSystemTenant) {
- availableTenants.add(0, TokenResponse.TenantInfo.builder()
- .tenantId(0L).tenantCode("SYSTEM").tenantName("系统平台").build());
- }
- }
-
- if (availableTenants.isEmpty()) {
- throw new IllegalArgumentException("该账号未关联任何租户");
- }
-
- // 确定当前租户:
- // 1. 如果请求指定了租户,且用户属于该租户,则使用该租户
- // 2. 否则,如果用户是平台管理员,默认进入系统租户(0)
- // 3. 否则,使用第一个非0的业务租户
- Long activeTenantId = null;
- if (request.getTenantCode() != null && !request.getTenantCode().trim().isEmpty()) {
- String tc = request.getTenantCode().trim();
- activeTenantId = availableTenants.stream()
- .filter(t -> t.getTenantCode().equals(tc))
- .map(TokenResponse.TenantInfo::getTenantId)
- .findFirst()
- .orElseThrow(() -> new IllegalArgumentException("您不属于指定的租户: " + tc));
- } else {
- if (Boolean.TRUE.equals(user.getIsPlatformAdmin())) {
- activeTenantId = 0L;
- } else {
- // 优先选择非0的租户
- activeTenantId = availableTenants.stream()
- .map(TokenResponse.TenantInfo::getTenantId)
- .filter(id -> id != 0L)
- .findFirst()
- .orElse(availableTenants.get(0).getTenantId());
- }
- }
-
- String deviceCode = request.getDeviceCode();
- if (deviceCode != null && !deviceCode.isEmpty()) {
- Device device = deviceService.getOne(new LambdaQueryWrapper()
- .eq(Device::getUserId, user.getUserId())
- .eq(Device::getDeviceCode, deviceCode)
- .eq(Device::getIsDeleted, 0)
- .eq(Device::getStatus, 1));
- if (device == null) {
- throw new IllegalArgumentException("设备码无效");
- }
- }
-
- long accessMinutes = parseLong(sysParamService.getParamValue("security.token.access_ttl_minutes",
- String.valueOf(accessDefaultMinutes)), accessDefaultMinutes);
- long refreshDays = parseLong(sysParamService.getParamValue("security.token.refresh_ttl_days",
- String.valueOf(refreshDefaultDays)), refreshDefaultDays);
-
- if (deviceCode == null || deviceCode.isEmpty()) {
- deviceCode = "default";
- }
- TokenResponse tokens = issueTokens(user, activeTenantId, deviceCode, accessMinutes, refreshDays);
- tokens.setAvailableTenants(availableTenants);
- cacheRefreshToken(user.getUserId(), deviceCode, tokens.getRefreshToken(), refreshDays);
-
- recordLoginLog(user.getUserId(), activeTenantId, user.getUsername(), 1, "登录成功", System.currentTimeMillis() - start);
- return tokens;
- } catch (Exception e) {
- recordLoginLog(null, null, request.getUsername(), 0, e.getMessage(), System.currentTimeMillis() - start);
- throw e;
- }
- }
-
- private void recordLoginLog(Long userId, Long tenantId, String username, Integer status, String msg, long duration) {
- SysLog sysLog = new SysLog();
- sysLog.setUserId(userId);
- sysLog.setTenantId(tenantId);
- sysLog.setUsername(username);
- sysLog.setLogType("LOGIN");
- sysLog.setOperation("用户登录: " + username);
- sysLog.setMethod("POST /api/auth/login");
- sysLog.setDuration(duration);
- sysLog.setStatus(status);
- sysLog.setIp(httpServletRequest.getRemoteAddr());
- sysLog.setCreatedAt(LocalDateTime.now());
- sysLogService.recordLog(sysLog);
- }
-
- @Override
- public TokenResponse refresh(String refreshToken) {
- Claims claims = jwtTokenProvider.parseToken(refreshToken);
- String tokenType = claims.get("tokenType", String.class);
- if (!"refresh".equals(tokenType)) {
- throw new IllegalArgumentException("无效的刷新令牌");
- }
- Long userId = claims.get("userId", Long.class);
- Long tenantId = claims.get("tenantId", Long.class);
- String deviceCode = claims.get("deviceCode", String.class);
- Number tokenAuthVersionNum = claims.get("authVersion", Number.class);
- long currentAuthVersion = authVersionService.getVersion(userId, tenantId);
- if (currentAuthVersion != (tokenAuthVersionNum == null ? 0L : tokenAuthVersionNum.longValue())) {
- throw new IllegalArgumentException("刷新令牌已失效");
- }
- String cached = stringRedisTemplate.opsForValue().get(RedisKeys.refreshTokenKey(userId, deviceCode));
- if (cached == null || !cached.equals(refreshToken)) {
- throw new IllegalArgumentException("刷新令牌已失效");
- }
-
- long accessMinutes = parseLong(sysParamService.getParamValue("security.token.access_ttl_minutes",
- String.valueOf(accessDefaultMinutes)), accessDefaultMinutes);
- long refreshDays = parseLong(sysParamService.getParamValue("security.token.refresh_ttl_days",
- String.valueOf(refreshDefaultDays)), refreshDefaultDays);
-
- SysUser user = sysUserMapper.selectByIdIgnoreTenant(userId);
- TokenResponse tokens = issueTokens(user, tenantId, deviceCode, accessMinutes, refreshDays);
- cacheRefreshToken(userId, deviceCode, tokens.getRefreshToken(), refreshDays);
- return tokens;
- }
-
- @Override
- public TokenResponse switchTenant(Long userId, Long targetTenantId, String deviceCode) {
- SysUser user = sysUserMapper.selectByIdIgnoreTenant(userId);
- if (user == null) {
- throw new IllegalArgumentException("用户不存在");
- }
-
- // 校验权限:平台管理员可以直接进入租户0,或者用户确实关联了目标租户
- boolean hasAccess = false;
- if (targetTenantId == 0L && Boolean.TRUE.equals(user.getIsPlatformAdmin())) {
- hasAccess = true;
- } else {
- java.util.List tenants = sysUserMapper.selectTenantsByUsername(user.getUsername());
- hasAccess = tenants.stream().anyMatch(t -> t.getTenantId().equals(targetTenantId));
- }
-
- if (!hasAccess) {
- throw new IllegalArgumentException("您不属于目标租户");
- }
-
- long accessMinutes = parseLong(sysParamService.getParamValue("security.token.access_ttl_minutes",
- String.valueOf(accessDefaultMinutes)), accessDefaultMinutes);
- long refreshDays = parseLong(sysParamService.getParamValue("security.token.refresh_ttl_days",
- String.valueOf(refreshDefaultDays)), refreshDefaultDays);
-
- TokenResponse tokens = issueTokens(user, targetTenantId, deviceCode, accessMinutes, refreshDays);
- cacheRefreshToken(userId, deviceCode, tokens.getRefreshToken(), refreshDays);
-
- // 重新获取该用户关联的所有租户信息返回
- java.util.List availableTenants = sysUserMapper.selectTenantsByUsername(user.getUsername());
- if (Boolean.TRUE.equals(user.getIsPlatformAdmin())) {
- boolean hasSystemTenant = availableTenants.stream().anyMatch(t -> t.getTenantId() == 0L);
- if (!hasSystemTenant) {
- availableTenants.add(0, TokenResponse.TenantInfo.builder()
- .tenantId(0L).tenantCode("SYSTEM").tenantName("系统平台").build());
- }
- }
- tokens.setAvailableTenants(availableTenants);
-
- return tokens;
- }
-
- @Override
- public void logout(Long userId, String deviceCode) {
- stringRedisTemplate.delete(RedisKeys.refreshTokenKey(userId, deviceCode));
- }
-
- @Override
- public String createDeviceCode(LoginRequest request, String deviceName) {
- if (isCaptchaEnabled()) {
- validateCaptcha(request.getCaptchaId(), request.getCaptchaCode());
- }
-
- SysUser user = sysUserMapper.selectByUsernameIgnoreTenant(request.getUsername());
-
- if (user == null || user.getStatus() != 1 || !passwordEncoder.matches(request.getPassword(), user.getPasswordHash())) {
- throw new IllegalArgumentException("用户名或密码错误");
- }
-
- String deviceCode = UUID.randomUUID().toString().replace("-", "");
- Device device = new Device();
- device.setUserId(user.getUserId());
- device.setDeviceCode(deviceCode);
- device.setDeviceName(deviceName == null ? "default" : deviceName);
- deviceService.save(device);
- return deviceCode;
- }
-
- private void validateCaptcha(String captchaId, String captchaCode) {
- if (captchaId == null || captchaId.isEmpty()) {
- throw new IllegalArgumentException("验证码不能为空");
- }
- if (captchaCode == null || captchaCode.isEmpty()) {
- throw new IllegalArgumentException("验证码不能为空");
- }
- String key = RedisKeys.captchaKey(captchaId);
- String stored = stringRedisTemplate.opsForValue().get(key);
- if (stored == null) {
- throw new IllegalArgumentException("验证码已过期");
- }
-
- String attemptsKey = RedisKeys.captchaAttemptsKey(captchaId);
- long attempts = 0;
- String attemptsStr = stringRedisTemplate.opsForValue().get(attemptsKey);
- if (attemptsStr != null) {
- attempts = Long.parseLong(attemptsStr);
- }
- if (attempts >= captchaMaxAttempts) {
- throw new IllegalArgumentException("验证码已失效");
- }
-
- if (!stored.equalsIgnoreCase(captchaCode)) {
- stringRedisTemplate.opsForValue().increment(attemptsKey);
- stringRedisTemplate.expire(attemptsKey, Duration.ofMinutes(2));
- throw new IllegalArgumentException("验证码错误");
- }
-
- stringRedisTemplate.delete(key);
- stringRedisTemplate.delete(attemptsKey);
- }
-
- private boolean isCaptchaEnabled() {
- String value = sysParamService.getCachedParamValue(SysParamKeys.CAPTCHA_ENABLED, "true");
- return Boolean.parseBoolean(value);
- }
-
- private TokenResponse issueTokens(SysUser user, Long tenantId, String deviceCode, long accessMinutes, long refreshDays) {
- long authVersion = authVersionService.getVersion(user.getUserId(), tenantId);
- Map accessClaims = new HashMap<>();
- accessClaims.put("tokenType", "access");
- accessClaims.put("userId", user.getUserId());
- accessClaims.put("tenantId", tenantId);
- accessClaims.put("username", user.getUsername());
- accessClaims.put("displayName", user.getDisplayName());
- accessClaims.put("deviceCode", deviceCode);
- accessClaims.put("authVersion", authVersion);
-
- Map refreshClaims = new HashMap<>();
- refreshClaims.put("tokenType", "refresh");
- refreshClaims.put("userId", user.getUserId());
- refreshClaims.put("tenantId", tenantId);
- refreshClaims.put("deviceCode", deviceCode);
- refreshClaims.put("authVersion", authVersion);
-
- String access = jwtTokenProvider.createToken(accessClaims, Duration.ofMinutes(accessMinutes).toMillis());
- String refresh = jwtTokenProvider.createToken(refreshClaims, Duration.ofDays(refreshDays).toMillis());
- return TokenResponse.builder()
- .accessToken(access)
- .refreshToken(refresh)
- .accessExpiresInMinutes(accessMinutes)
- .refreshExpiresInDays(refreshDays)
- .pwdResetRequired(user.getPwdResetRequired())
- .build();
- }
-
- private void cacheRefreshToken(Long userId, String deviceCode, String refreshToken, long refreshDays) {
- stringRedisTemplate.opsForValue().set(RedisKeys.refreshTokenKey(userId, deviceCode),
- refreshToken, Duration.ofDays(refreshDays));
- }
-
- private long parseLong(String value, long defaultValue) {
- try {
- return Long.parseLong(value);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/AuthVersionServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/AuthVersionServiceImpl.java
deleted file mode 100644
index 6de6307..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/AuthVersionServiceImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.imeeting.common.RedisKeys;
-import com.imeeting.service.AuthVersionService;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.time.Duration;
-import java.util.Collection;
-
-@Service
-public class AuthVersionServiceImpl implements AuthVersionService {
- private static final Duration VERSION_TTL = Duration.ofDays(30);
- private final StringRedisTemplate stringRedisTemplate;
-
- public AuthVersionServiceImpl(StringRedisTemplate stringRedisTemplate) {
- this.stringRedisTemplate = stringRedisTemplate;
- }
-
- @Override
- public long getVersion(Long userId, Long tenantId) {
- if (userId == null || tenantId == null) {
- return 0L;
- }
- String value = stringRedisTemplate.opsForValue().get(RedisKeys.authVersionKey(userId, tenantId));
- if (value == null || value.trim().isEmpty()) {
- return 0L;
- }
- try {
- return Long.parseLong(value);
- } catch (NumberFormatException e) {
- return 0L;
- }
- }
-
- @Override
- public void invalidateUserTenantAuth(Long userId, Long tenantId) {
- if (userId == null || tenantId == null) {
- return;
- }
- String versionKey = RedisKeys.authVersionKey(userId, tenantId);
- Long newVersion = stringRedisTemplate.opsForValue().increment(versionKey);
- if (newVersion == null) {
- return;
- }
- stringRedisTemplate.expire(versionKey, VERSION_TTL);
- long previousVersion = Math.max(newVersion - 1, 0);
- stringRedisTemplate.delete(RedisKeys.authPermKey(userId, tenantId, previousVersion));
- stringRedisTemplate.delete(RedisKeys.authPermKey(userId, tenantId, newVersion));
- }
-
- @Override
- public void invalidateUsersTenantAuth(Collection userIds, Long tenantId) {
- if (userIds == null || userIds.isEmpty() || tenantId == null) {
- return;
- }
- for (Long userId : userIds) {
- invalidateUserTenantAuth(userId, tenantId);
- }
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/DeviceServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/DeviceServiceImpl.java
deleted file mode 100644
index 31ca4f1..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/DeviceServiceImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.Device;
-import com.imeeting.mapper.DeviceMapper;
-import com.imeeting.service.DeviceService;
-import org.springframework.stereotype.Service;
-
-@Service
-public class DeviceServiceImpl extends ServiceImpl implements DeviceService {}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysDictItemServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysDictItemServiceImpl.java
deleted file mode 100644
index 944162a..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysDictItemServiceImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.entity.SysDictItem;
-import com.imeeting.mapper.SysDictItemMapper;
-import com.imeeting.service.SysDictItemService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.Serializable;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Random;
-
-@Slf4j
-@Service
-public class SysDictItemServiceImpl extends ServiceImpl implements SysDictItemService {
-
- private final StringRedisTemplate redisTemplate;
- private final ObjectMapper objectMapper;
- private final Random random = new Random();
-
- @Autowired
- public SysDictItemServiceImpl(StringRedisTemplate redisTemplate, ObjectMapper objectMapper) {
- this.redisTemplate = redisTemplate;
- this.objectMapper = objectMapper;
- }
-
- @Override
- public List getItemsByTypeCode(String typeCode) {
- String key = RedisKeys.sysDictKey(typeCode);
- try {
- String cached = redisTemplate.opsForValue().get(key);
- if (RedisKeys.CACHE_EMPTY_MARKER.equals(cached)) {
- return new ArrayList<>();
- }
- if (cached != null) {
- return objectMapper.readValue(cached, new TypeReference>() {});
- }
- } catch (Exception e) {
- log.error("Redis error for key {}: {}", key, e.getMessage());
- }
-
- List items = list(new LambdaQueryWrapper()
- .eq(SysDictItem::getTypeCode, typeCode)
- .eq(SysDictItem::getStatus, 1)
- .orderByAsc(SysDictItem::getSortOrder));
-
- try {
- if (items == null || items.isEmpty()) {
- redisTemplate.opsForValue().set(key, RedisKeys.CACHE_EMPTY_MARKER, Duration.ofMinutes(5));
- } else {
- int jitter = random.nextInt(120);
- redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(items), Duration.ofMinutes(1440 + jitter));
- }
- } catch (Exception e) {
- log.error("Failed to cache dictionary items for {}: {}", typeCode, e.getMessage());
- }
-
- return items;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean save(SysDictItem entity) {
- boolean success = super.save(entity);
- if (success && entity != null) {
- deleteCache(entity.getTypeCode());
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean updateById(SysDictItem entity) {
- if (entity == null || entity.getDictItemId() == null) {
- return super.updateById(entity);
- }
- SysDictItem old = getById(entity.getDictItemId());
- boolean success = super.updateById(entity);
- if (success && old != null) {
- deleteCache(old.getTypeCode());
- if (entity.getTypeCode() != null && !old.getTypeCode().equals(entity.getTypeCode())) {
- deleteCache(entity.getTypeCode());
- }
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeById(Serializable id) {
- SysDictItem old = getById(id);
- boolean success = super.removeById(id);
- if (success && old != null) {
- deleteCache(old.getTypeCode());
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeByIds(Collection> list) {
- if (list == null || list.isEmpty()) {
- return false;
- }
- boolean allSuccess = true;
- for (Object id : list) {
- if (!removeById((Serializable) id)) {
- allSuccess = false;
- }
- }
- return allSuccess;
- }
-
- private void deleteCache(String typeCode) {
- if (typeCode != null) {
- redisTemplate.delete(RedisKeys.sysDictKey(typeCode));
- }
- }
-}
\ No newline at end of file
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysDictTypeServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysDictTypeServiceImpl.java
deleted file mode 100644
index 9d90cc4..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysDictTypeServiceImpl.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.entity.SysDictType;
-import com.imeeting.mapper.SysDictTypeMapper;
-import com.imeeting.service.SysDictTypeService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-@Service
-public class SysDictTypeServiceImpl extends ServiceImpl implements SysDictTypeService {
-
- private final StringRedisTemplate redisTemplate;
-
- @Autowired
- public SysDictTypeServiceImpl(StringRedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean updateById(SysDictType entity) {
- if (entity == null || entity.getDictTypeId() == null) {
- return super.updateById(entity);
- }
- SysDictType old = getById(entity.getDictTypeId());
- boolean success = super.updateById(entity);
- if (success && old != null) {
- redisTemplate.delete(RedisKeys.sysDictKey(old.getTypeCode()));
- if (entity.getTypeCode() != null && !old.getTypeCode().equals(entity.getTypeCode())) {
- redisTemplate.delete(RedisKeys.sysDictKey(entity.getTypeCode()));
- }
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeById(Serializable id) {
- SysDictType old = getById(id);
- boolean success = super.removeById(id);
- if (success && old != null) {
- redisTemplate.delete(RedisKeys.sysDictKey(old.getTypeCode()));
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeByIds(Collection> list) {
- if (list == null || list.isEmpty()) {
- return false;
- }
- boolean allSuccess = true;
- for (Object id : list) {
- if (!removeById((Serializable) id)) {
- allSuccess = false;
- }
- }
- return allSuccess;
- }
-}
\ No newline at end of file
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysLogServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysLogServiceImpl.java
deleted file mode 100644
index 6f3929d..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysLogServiceImpl.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.SysLog;
-import com.imeeting.mapper.SysLogMapper;
-import com.imeeting.service.SysLogService;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-
-@Service
-public class SysLogServiceImpl extends ServiceImpl implements SysLogService {
-
- @Async
- @Override
- public void recordLog(SysLog log) {
- save(log);
- }
-
- @Override
- public IPage selectPageWithTenant(IPage page, Wrapper queryWrapper) {
- return baseMapper.selectPageWithTenant(page, queryWrapper);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysOrgServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysOrgServiceImpl.java
deleted file mode 100644
index 28d66d0..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysOrgServiceImpl.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.SysOrg;
-import com.imeeting.mapper.SysOrgMapper;
-import com.imeeting.service.SysOrgService;
-import org.springframework.stereotype.Service;
-import java.util.List;
-
-@Service
-public class SysOrgServiceImpl extends ServiceImpl implements SysOrgService {
- @Override
- public List listTree(Long tenantId) {
- LambdaQueryWrapper query = new LambdaQueryWrapper<>();
- if (tenantId != null) {
- query.eq(SysOrg::getTenantId, tenantId);
- }
- query.orderByAsc(SysOrg::getSortOrder);
- return list(query);
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysParamServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysParamServiceImpl.java
deleted file mode 100644
index f7ff1f2..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysParamServiceImpl.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.common.PageResult;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.dto.SysParamQueryDTO;
-import com.imeeting.dto.SysParamVO;
-import com.imeeting.entity.SysParam;
-import com.imeeting.mapper.SysParamMapper;
-import com.imeeting.service.SysParamService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.Serializable;
-import java.time.Duration;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class SysParamServiceImpl extends ServiceImpl implements SysParamService {
- private final StringRedisTemplate redisTemplate;
-
- public SysParamServiceImpl(StringRedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- }
-
- @Override
- public PageResult> page(SysParamQueryDTO query) {
- Page page = new Page<>(query.getPageNum(), query.getPageSize());
- LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
- if (query.getParamKey() != null && !query.getParamKey().isEmpty()) {
- wrapper.like(SysParam::getParamKey, query.getParamKey());
- }
- if (query.getParamType() != null && !query.getParamType().isEmpty()) {
- wrapper.eq(SysParam::getParamType, query.getParamType());
- }
- if (query.getDescription() != null && !query.getDescription().isEmpty()) {
- wrapper.like(SysParam::getDescription, query.getDescription());
- }
- wrapper.orderByDesc(SysParam::getCreatedAt);
-
- Page result = this.baseMapper.selectPage(page, wrapper);
-
- PageResult> pageResult = new PageResult<>();
- pageResult.setTotal(result.getTotal());
- pageResult.setRecords(result.getRecords().stream().map(this::toVO).collect(Collectors.toList()));
- return pageResult;
- }
-
- private SysParamVO toVO(SysParam entity) {
- if (entity == null) return null;
- SysParamVO vo = new SysParamVO();
- vo.setParamId(entity.getParamId());
- vo.setParamKey(entity.getParamKey());
- vo.setParamValue(entity.getParamValue());
- vo.setParamType(entity.getParamType());
- vo.setIsSystem(entity.getIsSystem());
- vo.setDescription(entity.getDescription());
- vo.setStatus(entity.getStatus());
- vo.setCreatedAt(entity.getCreatedAt());
- vo.setUpdatedAt(entity.getUpdatedAt());
- return vo;
- }
-
- @Override
- public String getParamValue(String key, String defaultValue) {
- if (key == null || key.isEmpty()) {
- return defaultValue;
- }
-
- String redisKey = RedisKeys.sysParamKey(key);
- try {
- // 1. 尝试从 Redis 获取
- String cachedValue = redisTemplate.opsForValue().get(redisKey);
- if (cachedValue != null) {
- // 如果是空标记,返回默认值
- if (RedisKeys.CACHE_EMPTY_MARKER.equals(cachedValue)) {
- return defaultValue;
- }
- return cachedValue;
- }
- } catch (Exception e) {
- log.error("Redis read error for key {}: {}", redisKey, e.getMessage());
- }
-
- // 2. Redis 未命中,查数据库
- log.info("Cache miss for param key: {}, fetching from DB", key);
- SysParam param = getOne(new LambdaQueryWrapper().eq(SysParam::getParamKey, key));
-
- if (param != null) {
- String val = param.getParamValue();
- // 3. 回写 Redis
- try {
- redisTemplate.opsForValue().set(redisKey, val == null ? "" : val, Duration.ofHours(24));
- } catch (Exception e) {
- log.error("Redis write error for key {}: {}", redisKey, e.getMessage());
- }
- return val;
- } else {
- // 4. 数据库也无数据,设置空标记防止穿透
- try {
- // Use default value or empty marker if needed
- redisTemplate.opsForValue().set(redisKey, RedisKeys.CACHE_EMPTY_MARKER, Duration.ofMinutes(5));
- } catch (Exception e) {
- log.error("Redis write empty marker error for key {}: {}", redisKey, e.getMessage());
- }
- return defaultValue;
- }
- }
-
- @Override
- public String getCachedParamValue(String key, String defaultValue) {
- return getParamValue(key, defaultValue);
- }
-
- @Override
- public void syncParamToCache(SysParam param) {
- if (param != null && param.getParamKey() != null) {
- redisTemplate.opsForValue().set(RedisKeys.sysParamKey(param.getParamKey()),
- param.getParamValue() == null ? "" : param.getParamValue(), Duration.ofHours(24));
- }
- }
-
- @Override
- public void deleteParamCache(String key) {
- if (key != null) {
- redisTemplate.delete(RedisKeys.sysParamKey(key));
- }
- }
-
- @Override
- public void syncAllToCache() {
- log.info("Syncing all system parameters to Redis");
- List params = list();
- for (SysParam param : params) {
- syncParamToCache(param);
- }
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean save(SysParam entity) {
- boolean success = super.save(entity);
- if (success && entity.getParamKey() != null) {
- deleteParamCache(entity.getParamKey());
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean updateById(SysParam entity) {
- // 先查出旧的 Key 确保缓存被清理
- SysParam old = getById(entity.getParamId());
- boolean success = super.updateById(entity);
- if (success && old != null) {
- deleteParamCache(old.getParamKey());
- if (entity.getParamKey() != null && !entity.getParamKey().equals(old.getParamKey())) {
- deleteParamCache(entity.getParamKey());
- }
- }
- return success;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeById(Serializable id) {
- SysParam old = getById(id);
- boolean success = super.removeById(id);
- if (success && old != null) {
- deleteParamCache(old.getParamKey());
- }
- return success;
- }
-}
\ No newline at end of file
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysPermissionServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysPermissionServiceImpl.java
deleted file mode 100644
index 84503ee..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysPermissionServiceImpl.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.SysPermission;
-import com.imeeting.entity.SysUser;
-import com.imeeting.mapper.SysPermissionMapper;
-import com.imeeting.service.SysPermissionService;
-import com.imeeting.service.SysUserService;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-@Service
-public class SysPermissionServiceImpl extends ServiceImpl implements SysPermissionService {
-
- private final SysUserService sysUserService;
-
- public SysPermissionServiceImpl(@Lazy SysUserService sysUserService) {
- this.sysUserService = sysUserService;
- }
-
- @Override
- public List listByUserId(Long userId, Long tenantId) {
- if (userId == null) {
- return List.of();
- }
-
- SysUser user = sysUserService.getByIdIgnoreTenant(userId);
- if (user != null && Boolean.TRUE.equals(user.getIsPlatformAdmin()) && Long.valueOf(0).equals(tenantId)) {
- return list();
- }
-
- // 如果没有指定租户,或者租户为0但用户不是平台管理员,则返回空或按默认逻辑(通常需要指定租户)
- if (tenantId == null) return List.of();
-
- return baseMapper.selectByUserId(userId, tenantId);
- }
-
- @Override
- public Set listPermissionCodesByUserId(Long userId, Long tenantId) {
- List perms = listByUserId(userId, tenantId);
- return perms.stream()
- .map(SysPermission::getCode)
- .filter(code -> code != null && !code.isEmpty())
- .collect(Collectors.toSet());
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysPlatformConfigServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysPlatformConfigServiceImpl.java
deleted file mode 100644
index 8a6fca7..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysPlatformConfigServiceImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.imeeting.common.RedisKeys;
-import com.imeeting.dto.PlatformConfigVO;
-import com.imeeting.entity.SysPlatformConfig;
-import com.imeeting.mapper.SysPlatformConfigMapper;
-import com.imeeting.service.SysPlatformConfigService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.Duration;
-import java.util.UUID;
-
-@Slf4j
-@Service
-public class SysPlatformConfigServiceImpl extends ServiceImpl implements SysPlatformConfigService {
-
- private final StringRedisTemplate redisTemplate;
- private final ObjectMapper objectMapper;
-
- @Value("${app.upload-path}")
- private String uploadPath;
-
- @Value("${app.resource-prefix}")
- private String resourcePrefix;
-
- public SysPlatformConfigServiceImpl(StringRedisTemplate redisTemplate, ObjectMapper objectMapper) {
- this.redisTemplate = redisTemplate;
- this.objectMapper = objectMapper;
- }
-
- @Override
- public PlatformConfigVO getConfig() {
- String key = RedisKeys.platformConfigKey();
- try {
- String cached = redisTemplate.opsForValue().get(key);
- if (cached != null) {
- return objectMapper.readValue(cached, PlatformConfigVO.class);
- }
- } catch (Exception e) {
- log.error("Read platform config from redis error", e);
- }
-
- SysPlatformConfig config = getById(1L);
- if (config == null) {
- return new PlatformConfigVO();
- }
-
- PlatformConfigVO vo = toVO(config);
- try {
- redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(vo), Duration.ofDays(1));
- } catch (Exception e) {
- log.error("Write platform config to redis error", e);
- }
- return vo;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean updateConfig(SysPlatformConfig config) {
- config.setId(1L);
- SysPlatformConfig old = getById(1L);
-
- boolean success = updateById(config);
- if (success) {
- redisTemplate.delete(RedisKeys.platformConfigKey());
- // 物理文件清理逻辑可以在这里根据需要扩展(例如对比 old 和 config 的 URL)
- }
- return success;
- }
-
- @Override
- public String uploadAsset(MultipartFile file) {
- if (file.isEmpty()) {
- throw new RuntimeException("File is empty");
- }
-
- String originalFilename = file.getOriginalFilename();
- String extension = "";
- if (originalFilename != null && originalFilename.contains(".")) {
- extension = originalFilename.substring(originalFilename.lastIndexOf("."));
- }
-
- String fileName = UUID.randomUUID().toString() + extension;
- Path path = Paths.get(uploadPath, fileName);
-
- try {
- Files.copy(file.getInputStream(), path);
- String prefix = resourcePrefix.endsWith("/") ? resourcePrefix : resourcePrefix + "/";
- return prefix + fileName;
- } catch (IOException e) {
- log.error("Upload asset error", e);
- throw new RuntimeException("Failed to store file");
- }
- }
-
- private PlatformConfigVO toVO(SysPlatformConfig entity) {
- PlatformConfigVO vo = new PlatformConfigVO();
- vo.setProjectName(entity.getProjectName());
- vo.setLogoUrl(entity.getLogoUrl());
- vo.setIconUrl(entity.getIconUrl());
- vo.setLoginBgUrl(entity.getLoginBgUrl());
- vo.setIcpInfo(entity.getIcpInfo());
- vo.setCopyrightInfo(entity.getCopyrightInfo());
- vo.setSystemDescription(entity.getSystemDescription());
- return vo;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysRoleServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysRoleServiceImpl.java
deleted file mode 100644
index cdfbbc9..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysRoleServiceImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.SysRole;
-import com.imeeting.mapper.SysRoleMapper;
-import com.imeeting.service.SysRoleService;
-import org.springframework.stereotype.Service;
-
-@Service
-public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService {}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysTenantServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysTenantServiceImpl.java
deleted file mode 100644
index 3fd3462..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysTenantServiceImpl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.dto.CreateTenantDTO;
-import com.imeeting.entity.*;
-import com.imeeting.mapper.SysRolePermissionMapper;
-import com.imeeting.mapper.SysTenantMapper;
-import com.imeeting.mapper.SysUserRoleMapper;
-import com.imeeting.service.*;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Service
-public class SysTenantServiceImpl extends ServiceImpl implements SysTenantService {
-
- private final SysUserService sysUserService;
- private final SysRoleService sysRoleService;
- private final SysOrgService sysOrgService;
- private final SysPermissionService sysPermissionService;
- private final SysParamService sysParamService;
- private final SysUserRoleMapper sysUserRoleMapper;
- private final SysRolePermissionMapper sysRolePermissionMapper;
- private final SysTenantUserService sysTenantUserService;
- private final PasswordEncoder passwordEncoder;
- private final com.imeeting.mapper.DeviceMapper deviceMapper;
-
- public SysTenantServiceImpl(SysUserService sysUserService, SysRoleService sysRoleService,
- SysOrgService sysOrgService, SysPermissionService sysPermissionService,
- SysParamService sysParamService, SysUserRoleMapper sysUserRoleMapper,
- SysRolePermissionMapper sysRolePermissionMapper,
- SysTenantUserService sysTenantUserService, PasswordEncoder passwordEncoder,
- com.imeeting.mapper.DeviceMapper deviceMapper) {
- this.sysUserService = sysUserService;
- this.sysRoleService = sysRoleService;
- this.sysOrgService = sysOrgService;
- this.sysPermissionService = sysPermissionService;
- this.sysParamService = sysParamService;
- this.sysUserRoleMapper = sysUserRoleMapper;
- this.sysRolePermissionMapper = sysRolePermissionMapper;
- this.sysTenantUserService = sysTenantUserService;
- this.passwordEncoder = passwordEncoder;
- this.deviceMapper = deviceMapper;
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean removeById(java.io.Serializable id) {
- Long tenantId = (Long) id;
-
- // 1. 获取该租户下的所有用户 ID 和角色 ID
- List tenantUsers = sysTenantUserService.list(
- new LambdaQueryWrapper().eq(SysTenantUser::getTenantId, tenantId)
- );
- List userIds = tenantUsers.stream().map(SysTenantUser::getUserId).collect(Collectors.toList());
-
- List roles = sysRoleService.list(
- new LambdaQueryWrapper().eq(SysRole::getTenantId, tenantId)
- );
- List roleIds = roles.stream().map(SysRole::getRoleId).collect(Collectors.toList());
-
- // 2. 逻辑删除角色权限关联
- if (roleIds != null && !roleIds.isEmpty()) {
- sysRolePermissionMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().in("role_id", roleIds));
- }
-
- // 3. 逻辑删除租户下的角色
- sysRoleService.lambdaUpdate()
- .set(SysRole::getIsDeleted, 1)
- .eq(SysRole::getTenantId, tenantId)
- .update();
-
- // 4. 逻辑删除租户下的组织
- sysOrgService.lambdaUpdate()
- .set(SysOrg::getIsDeleted, 1)
- .eq(SysOrg::getTenantId, tenantId)
- .update();
-
- // 4. 逻辑删除用户与租户的关联
- sysTenantUserService.remove(new LambdaQueryWrapper().eq(SysTenantUser::getTenantId, tenantId));
-
- // 5. 逻辑删除用户与角色的关联 (带租户隔离的)
- sysUserRoleMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().eq("tenant_id", tenantId));
-
- // 6. 清理孤立用户:如果用户不再属于任何租户,则逻辑删除该用户
- if (userIds != null && !userIds.isEmpty()) {
- for (Long userId : userIds) {
- long count = sysTenantUserService.count(
- new LambdaQueryWrapper().eq(SysTenantUser::getUserId, userId)
- );
- if (count == 0) {
- sysUserService.removeById(userId);
- }
- }
- }
-
- // 7. 逻辑删除租户下的设备
- if (deviceMapper != null) {
- deviceMapper.delete(new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper().eq("tenant_id", tenantId));
- }
-
- // 8. 最后逻辑删除租户记录本身
- return super.removeById(id);
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Long createTenantWithAdmin(CreateTenantDTO dto) {
- // 1. 校验租户编码唯一性
- if (count(new LambdaQueryWrapper().eq(SysTenant::getTenantCode, dto.getTenantCode())) > 0) {
- throw new RuntimeException("租户编码已存在:" + dto.getTenantCode());
- }
-
- // 2. 创建租户
- SysTenant tenant = new SysTenant();
- tenant.setTenantCode(dto.getTenantCode());
- tenant.setTenantName(dto.getTenantName());
- tenant.setContactName(dto.getContactName());
- tenant.setContactPhone(dto.getContactPhone());
- tenant.setRemark(dto.getRemark());
- tenant.setExpireTime(dto.getExpireTime());
- tenant.setStatus(1);
- save(tenant);
- Long tenantId = tenant.getId();
-
- // 3. 初始化根组织
- SysOrg rootOrg = new SysOrg();
- rootOrg.setTenantId(tenantId);
- rootOrg.setOrgName(dto.getTenantName());
- rootOrg.setOrgCode(dto.getTenantCode() + "_ROOT");
- rootOrg.setParentId(null);
- rootOrg.setStatus(1);
- sysOrgService.save(rootOrg);
- Long orgId = rootOrg.getId();
-
- // 4. 创建租户管理员角色
- SysRole adminRole = new SysRole();
- adminRole.setTenantId(tenantId);
- adminRole.setRoleCode("TENANT_ADMIN");
- adminRole.setRoleName("租户管理员");
- adminRole.setStatus(1);
- adminRole.setRemark("系统自动初始化的租户管理员角色");
- sysRoleService.save(adminRole);
- Long roleId = adminRole.getRoleId();
-
- // 5. 分配默认菜单权限
- String menuCodes = sysParamService.getParamValue("tenant.init.default.menu.codes", "");
- if (menuCodes != null && !menuCodes.trim().isEmpty()) {
- List codes = Arrays.asList(menuCodes.split(","));
- List perms = sysPermissionService.list(
- new LambdaQueryWrapper().in(SysPermission::getCode, codes)
- );
- if (!perms.isEmpty()) {
- for (SysPermission p : perms) {
- SysRolePermission rp = new SysRolePermission();
- rp.setRoleId(roleId);
- rp.setPermId(p.getPermId());
- sysRolePermissionMapper.insert(rp);
- }
- }
- }
-
- // 6. 创建管理员用户
- String username = "admin_" + dto.getTenantCode();
- if (sysUserService.count(new LambdaQueryWrapper().eq(SysUser::getUsername, username)) > 0) {
- throw new RuntimeException("管理员用户名已存在:" + username);
- }
-
- String defaultPwd = sysParamService.getParamValue("tenant.init.default.password", "123456");
- SysUser user = new SysUser();
- user.setUsername(username);
- user.setDisplayName(dto.getTenantName() + "管理员");
- user.setPasswordHash(passwordEncoder.encode(defaultPwd));
- user.setPwdResetRequired(1);
- user.setStatus(1);
- user.setIsPlatformAdmin(false);
- sysUserService.save(user);
- Long userId = user.getUserId();
-
- // 7. 绑定用户与角色 (sys_user_role)
- SysUserRole ur = new SysUserRole();
- ur.setTenantId(tenantId);
- ur.setUserId(userId);
- ur.setRoleId(roleId);
- sysUserRoleMapper.insert(ur);
-
- // 8. 绑定用户与租户/组织 (sys_tenant_user)
- SysTenantUser tu = new SysTenantUser();
- tu.setUserId(userId);
- tu.setTenantId(tenantId);
- tu.setOrgId(orgId);
- tu.setStatus(1);
- sysTenantUserService.save(tu);
-
- return tenantId;
- }
-}
diff --git a/backend/src/main/java/com/imeeting/service/impl/SysTenantUserServiceImpl.java b/backend/src/main/java/com/imeeting/service/impl/SysTenantUserServiceImpl.java
deleted file mode 100644
index ba54cf1..0000000
--- a/backend/src/main/java/com/imeeting/service/impl/SysTenantUserServiceImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.imeeting.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.imeeting.entity.SysTenantUser;
-import com.imeeting.mapper.SysTenantUserMapper;
-import com.imeeting.service.SysTenantUserService;
-import org.springframework.stereotype.Service;
-import java.util.List;
-
-@Service
-public class SysTenantUserServiceImpl extends ServiceImpl implements SysTenantUserService {
-
- private final com.imeeting.service.SysOrgService sysOrgService;
-
- public SysTenantUserServiceImpl(com.imeeting.service.SysOrgService sysOrgService) {
- this.sysOrgService = sysOrgService;
- }
-
- @Override
- public List listByUserId(Long userId) {
- List list = list(new LambdaQueryWrapper