feat: 添加请求日志记录并优化前端样式

- 在多个 Android 控制器中引入 `AndroidRequestLogHelper` 以记录请求日志
- 优化 `index.less` 和 `index.tsx` 文件,确保表格滚动和高度限制生效
dev_na
chenhao 2026-05-28 14:11:20 +08:00
parent 47ebeade20
commit 7f9c080bf7
17 changed files with 122 additions and 3 deletions

View File

@ -5,6 +5,7 @@ import com.unisbase.dto.LoginRequest;
import com.unisbase.dto.RefreshRequest; import com.unisbase.dto.RefreshRequest;
import com.unisbase.dto.TokenResponse; import com.unisbase.dto.TokenResponse;
import com.unisbase.service.AuthService; import com.unisbase.service.AuthService;
import com.imeeting.support.AndroidRequestLogHelper;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -12,6 +13,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -23,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/android/auth") @RequestMapping("/api/android/auth")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidAuthController { public class AndroidAuthController {
private final AuthService authService; private final AuthService authService;
@ -37,6 +40,7 @@ public class AndroidAuthController {
}) })
@PostMapping("/login") @PostMapping("/login")
public ApiResponse<TokenResponse> login(@Valid @RequestBody LoginRequest request) { public ApiResponse<TokenResponse> login(@Valid @RequestBody LoginRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android认证", "登录接口", "request", request);
return ApiResponse.ok(authService.login(request, true)); return ApiResponse.ok(authService.login(request, true));
} }
@ -52,6 +56,10 @@ public class AndroidAuthController {
public ApiResponse<TokenResponse> refresh(@RequestBody(required = false) RefreshRequest request, public ApiResponse<TokenResponse> refresh(@RequestBody(required = false) RefreshRequest request,
@RequestHeader(value = "Authorization", required = false) String authorization, @RequestHeader(value = "Authorization", required = false) String authorization,
@RequestHeader(value = "X-Android-Access-Token", required = false) String androidAccessToken) { @RequestHeader(value = "X-Android-Access-Token", required = false) String androidAccessToken) {
AndroidRequestLogHelper.logRequest(log, "Android认证", "刷新令牌接口",
"request", request,
"authorization", authorization,
"androidAccessToken", androidAccessToken);
return ApiResponse.ok(authService.refresh(resolveRefreshToken(request, authorization, androidAccessToken))); return ApiResponse.ok(authService.refresh(resolveRefreshToken(request, authorization, androidAccessToken)));
} }

View File

@ -1,6 +1,7 @@
package com.imeeting.controller.android; package com.imeeting.controller.android;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.imeeting.support.AndroidRequestLogHelper;
import com.imeeting.entity.biz.ClientDownload; import com.imeeting.entity.biz.ClientDownload;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
import com.imeeting.service.biz.ClientDownloadService; import com.imeeting.service.biz.ClientDownloadService;
@ -41,6 +42,10 @@ public class AndroidClientController {
@RequestParam(value = "platform_code", required = false) String platformCode, @RequestParam(value = "platform_code", required = false) String platformCode,
@RequestParam(value = "platform_type", required = false) String platformType, @RequestParam(value = "platform_type", required = false) String platformType,
@RequestParam(value = "platform_name", required = false) String platformName) { @RequestParam(value = "platform_name", required = false) String platformName) {
AndroidRequestLogHelper.logRequest(log, "Android客户端", "查询平台最新客户端接口",
"platformCode", platformCode,
"platformType", platformType,
"platformName", platformName);
androidAuthService.authenticateHttp(request); androidAuthService.authenticateHttp(request);
if ((platformCode == null || platformCode.isBlank()) if ((platformCode == null || platformCode.isBlank())
&& ((platformType == null || platformType.isBlank()) || (platformName == null || platformName.isBlank()))) { && ((platformType == null || platformType.isBlank()) || (platformName == null || platformName.isBlank()))) {

View File

@ -1,5 +1,6 @@
package com.imeeting.controller.android; package com.imeeting.controller.android;
import com.imeeting.support.AndroidRequestLogHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.imeeting.entity.biz.ExternalApp; import com.imeeting.entity.biz.ExternalApp;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
@ -13,6 +14,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -24,6 +26,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/android/external-apps") @RequestMapping("/api/android/external-apps")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidExternalAppController { public class AndroidExternalAppController {
private final AndroidAuthService androidAuthService; private final AndroidAuthService androidAuthService;
@ -40,6 +43,7 @@ public class AndroidExternalAppController {
@GetMapping("/active") @GetMapping("/active")
public ApiResponse<List<ExternalApp>> active(HttpServletRequest request, public ApiResponse<List<ExternalApp>> active(HttpServletRequest request,
@RequestParam(value = "is_active", required = false) Integer ignoredIsActive) { @RequestParam(value = "is_active", required = false) Integer ignoredIsActive) {
AndroidRequestLogHelper.logRequest(log, "Android外部应用", "查询启用外部应用接口", "isActive", ignoredIsActive);
androidAuthService.authenticateHttp(request); androidAuthService.authenticateHttp(request);
List<ExternalApp> apps = externalAppService.list(new LambdaQueryWrapper<ExternalApp>() List<ExternalApp> apps = externalAppService.list(new LambdaQueryWrapper<ExternalApp>()
.eq(ExternalApp::getStatus, 1) .eq(ExternalApp::getStatus, 1)

View File

@ -4,6 +4,7 @@ import com.imeeting.dto.android.AndroidAuthContext;
import com.imeeting.dto.biz.AiModelVO; import com.imeeting.dto.biz.AiModelVO;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
import com.imeeting.service.biz.AiModelService; import com.imeeting.service.biz.AiModelService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.common.ApiResponse; import com.unisbase.common.ApiResponse;
import com.unisbase.dto.PageResult; import com.unisbase.dto.PageResult;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -25,6 +27,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/android/llm-models") @RequestMapping("/api/android/llm-models")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidLlmModelController { public class AndroidLlmModelController {
private final AndroidAuthService androidAuthService; private final AndroidAuthService androidAuthService;
@ -40,6 +43,7 @@ public class AndroidLlmModelController {
}) })
@GetMapping("/active") @GetMapping("/active")
public ApiResponse<List<AiModelVO>> activeModels(HttpServletRequest request) { public ApiResponse<List<AiModelVO>> activeModels(HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android模型", "查询启用大模型列表接口");
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
PageResult<List<AiModelVO>> result = aiModelService.pageModels(1, 1000, null, "LLM", loginUser.getTenantId()); PageResult<List<AiModelVO>> result = aiModelService.pageModels(1, 1000, null, "LLM", loginUser.getTenantId());

View File

@ -23,6 +23,7 @@ import com.imeeting.entity.biz.Meeting;
import com.imeeting.entity.biz.PromptTemplate; import com.imeeting.entity.biz.PromptTemplate;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
import com.imeeting.service.android.legacy.LegacyMeetingAdapterService; import com.imeeting.service.android.legacy.LegacyMeetingAdapterService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.imeeting.service.biz.*; import com.imeeting.service.biz.*;
import com.imeeting.service.biz.impl.RedisOnlyMeetingProgressServiceAdapter; import com.imeeting.service.biz.impl.RedisOnlyMeetingProgressServiceAdapter;
import com.unisbase.common.ApiResponse; import com.unisbase.common.ApiResponse;
@ -41,6 +42,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -68,6 +70,7 @@ import java.util.stream.Collectors;
@Tag(name = "Android会议接口") @Tag(name = "Android会议接口")
@RestController @RestController
@RequestMapping("/api/android/meetings") @RequestMapping("/api/android/meetings")
@Slf4j
public class AndroidMeetingController { public class AndroidMeetingController {
private static final String STAGE_DATA_INITIALIZATION = "data_initialization"; private static final String STAGE_DATA_INITIALIZATION = "data_initialization";
@ -164,6 +167,7 @@ public class AndroidMeetingController {
@PostMapping @PostMapping
@Log(value = "新增Android会议", type = "Android会议管理") @Log(value = "新增Android会议", type = "Android会议管理")
public ApiResponse<MeetingVO> create(HttpServletRequest request, @RequestBody LegacyMeetingCreateRequest command) { public ApiResponse<MeetingVO> create(HttpServletRequest request, @RequestBody LegacyMeetingCreateRequest command) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "创建离线会议接口", "request", command);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
return ApiResponse.ok(legacyMeetingAdapterService.createMeeting(command, loginUser)); return ApiResponse.ok(legacyMeetingAdapterService.createMeeting(command, loginUser));
@ -184,6 +188,12 @@ public class AndroidMeetingController {
@RequestParam(value = "model_code", required = false) String modelCode, @RequestParam(value = "model_code", required = false) String modelCode,
@RequestParam(value = "force_replace", defaultValue = "false") boolean forceReplace, @RequestParam(value = "force_replace", defaultValue = "false") boolean forceReplace,
@RequestParam("audio_file") MultipartFile audioFile) throws IOException { @RequestParam("audio_file") MultipartFile audioFile) throws IOException {
AndroidRequestLogHelper.logRequest(log, "Android会议", "上传会议音频接口",
"meetingId", meetingId,
"promptId", promptId,
"modelCode", modelCode,
"forceReplace", forceReplace,
"audioFile", audioFile);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
return ApiResponse.ok(legacyMeetingAdapterService.uploadAndTriggerOfflineProcess( return ApiResponse.ok(legacyMeetingAdapterService.uploadAndTriggerOfflineProcess(
@ -210,6 +220,11 @@ public class AndroidMeetingController {
@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "1") Integer page,
@RequestParam(value = "page_size", defaultValue = "10") Integer pageSize, @RequestParam(value = "page_size", defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String title) { @RequestParam(required = false) String title) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "分页查询会议接口",
"userId", ignoredUserId,
"page", page,
"pageSize", pageSize,
"title", title);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
return ApiResponse.ok(meetingQueryService.pageMeetings( return ApiResponse.ok(meetingQueryService.pageMeetings(
@ -235,6 +250,7 @@ public class AndroidMeetingController {
}) })
@GetMapping("/{meetingId}/preview-data") @GetMapping("/{meetingId}/preview-data")
public ApiResponse<LegacyMeetingPreviewDataResponse> previewData(HttpServletRequest request, @PathVariable Long meetingId) { public ApiResponse<LegacyMeetingPreviewDataResponse> previewData(HttpServletRequest request, @PathVariable Long meetingId) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "查询会议预览数据接口", "meetingId", meetingId);
androidAuthService.authenticateHttp(request); androidAuthService.authenticateHttp(request);
LegacyMeetingPreviewResult result = buildPreviewResult(meetingId); LegacyMeetingPreviewResult result = buildPreviewResult(meetingId);
return new ApiResponse<>(result.getCode(), result.getMessage(), result.getData()); return new ApiResponse<>(result.getCode(), result.getMessage(), result.getData());
@ -253,6 +269,9 @@ public class AndroidMeetingController {
public ApiResponse<String> updateAccessPassword(HttpServletRequest request, public ApiResponse<String> updateAccessPassword(HttpServletRequest request,
@PathVariable Long meetingId, @PathVariable Long meetingId,
@RequestBody(required = false) LegacyMeetingAccessPasswordRequest command) { @RequestBody(required = false) LegacyMeetingAccessPasswordRequest command) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "更新会议访问密码接口",
"meetingId", meetingId,
"request", command);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
Meeting meeting = meetingAccessService.requireMeeting(meetingId); Meeting meeting = meetingAccessService.requireMeeting(meetingId);
@ -277,6 +296,7 @@ public class AndroidMeetingController {
@DeleteMapping("/{meetingId}") @DeleteMapping("/{meetingId}")
@Log(value = "删除Android会议", type = "Android会议管理") @Log(value = "删除Android会议", type = "Android会议管理")
public ApiResponse<Boolean> delete(HttpServletRequest request, @PathVariable Long meetingId) { public ApiResponse<Boolean> delete(HttpServletRequest request, @PathVariable Long meetingId) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "删除会议接口", "meetingId", meetingId);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
Meeting meeting = meetingAccessService.requireMeeting(meetingId); Meeting meeting = meetingAccessService.requireMeeting(meetingId);
@ -288,6 +308,7 @@ public class AndroidMeetingController {
@Log(value = "获取会议配置", type = "Android会议管理") @Log(value = "获取会议配置", type = "Android会议管理")
@Operation(summary = "获取会议配置") @Operation(summary = "获取会议配置")
public ApiResponse<AndroidMeetingConfigVo> config(HttpServletRequest request) { public ApiResponse<AndroidMeetingConfigVo> config(HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android会议", "获取会议配置接口");
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext); LoginUser loginUser = AndroidLoginUserSupport.requireLoginUser(authContext);
AndroidMeetingConfigVo resultVo = new AndroidMeetingConfigVo(); AndroidMeetingConfigVo resultVo = new AndroidMeetingConfigVo();

View File

@ -19,6 +19,7 @@ import com.imeeting.service.biz.MeetingCommandService;
import com.imeeting.service.biz.MeetingQueryService; import com.imeeting.service.biz.MeetingQueryService;
import com.imeeting.service.biz.MeetingRuntimeProfileResolver; import com.imeeting.service.biz.MeetingRuntimeProfileResolver;
import com.imeeting.service.biz.RealtimeMeetingSessionStateService; import com.imeeting.service.biz.RealtimeMeetingSessionStateService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.common.ApiResponse; import com.unisbase.common.ApiResponse;
import com.unisbase.common.annotation.Log; import com.unisbase.common.annotation.Log;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -29,6 +30,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -44,6 +46,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/android/meeting") @RequestMapping("/api/android/meeting")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidMeetingRealtimeController { public class AndroidMeetingRealtimeController {
private static final DateTimeFormatter TITLE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter TITLE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -69,6 +72,7 @@ public class AndroidMeetingRealtimeController {
@Log(value = "新增Android实时会议", type = "Android实时会议") @Log(value = "新增Android实时会议", type = "Android实时会议")
public ApiResponse<AndroidCreateRealtimeMeetingVO> createRealtimeMeeting(HttpServletRequest request, public ApiResponse<AndroidCreateRealtimeMeetingVO> createRealtimeMeeting(HttpServletRequest request,
@RequestBody(required = false) AndroidCreateRealtimeMeetingCommand command) { @RequestBody(required = false) AndroidCreateRealtimeMeetingCommand command) {
AndroidRequestLogHelper.logRequest(log, "Android实时会议", "创建实时会议接口", "command", command);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
meetingAuthorizationService.assertCanCreateMeeting(authContext); meetingAuthorizationService.assertCanCreateMeeting(authContext);
RealtimeMeetingRuntimeProfile runtimeProfile = meetingRuntimeProfileResolver.resolve( RealtimeMeetingRuntimeProfile runtimeProfile = meetingRuntimeProfileResolver.resolve(
@ -125,6 +129,7 @@ public class AndroidMeetingRealtimeController {
}) })
@GetMapping("/{id}/realtime/session-status") @GetMapping("/{id}/realtime/session-status")
public ApiResponse<RealtimeMeetingSessionStatusVO> getRealtimeSessionStatus(@PathVariable Long id, HttpServletRequest request) { public ApiResponse<RealtimeMeetingSessionStatusVO> getRealtimeSessionStatus(@PathVariable Long id, HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android实时会议", "查询实时会议状态接口", "meetingId", id);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
Meeting meeting = meetingAccessService.requireMeeting(id); Meeting meeting = meetingAccessService.requireMeeting(id);
meetingAuthorizationService.assertCanManageRealtimeMeeting(meeting, authContext); meetingAuthorizationService.assertCanManageRealtimeMeeting(meeting, authContext);
@ -141,6 +146,7 @@ public class AndroidMeetingRealtimeController {
}) })
@GetMapping("/{id}/transcripts") @GetMapping("/{id}/transcripts")
public ApiResponse<List<MeetingTranscriptVO>> getTranscripts(@PathVariable Long id, HttpServletRequest request) { public ApiResponse<List<MeetingTranscriptVO>> getTranscripts(@PathVariable Long id, HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android实时会议", "查询会议转写接口", "meetingId", id);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
Meeting meeting = meetingAccessService.requireMeeting(id); Meeting meeting = meetingAccessService.requireMeeting(id);
meetingAuthorizationService.assertCanViewMeeting(meeting, authContext); meetingAuthorizationService.assertCanViewMeeting(meeting, authContext);
@ -157,6 +163,7 @@ public class AndroidMeetingRealtimeController {
}) })
@PostMapping("/{id}/realtime/pause") @PostMapping("/{id}/realtime/pause")
public ApiResponse<RealtimeMeetingSessionStatusVO> pauseRealtimeMeeting(@PathVariable Long id, HttpServletRequest request) { public ApiResponse<RealtimeMeetingSessionStatusVO> pauseRealtimeMeeting(@PathVariable Long id, HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android实时会议", "暂停实时会议接口", "meetingId", id);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
Meeting meeting = meetingAccessService.requireMeeting(id); Meeting meeting = meetingAccessService.requireMeeting(id);
meetingAuthorizationService.assertCanControlRealtimeMeeting(meeting, authContext, MeetingConstants.SOURCE_ANDROID); meetingAuthorizationService.assertCanControlRealtimeMeeting(meeting, authContext, MeetingConstants.SOURCE_ANDROID);
@ -175,6 +182,7 @@ public class AndroidMeetingRealtimeController {
public ApiResponse<Boolean> completeRealtimeMeeting(@PathVariable Long id, public ApiResponse<Boolean> completeRealtimeMeeting(@PathVariable Long id,
HttpServletRequest request, HttpServletRequest request,
@RequestBody(required = false) RealtimeMeetingCompleteDTO dto) { @RequestBody(required = false) RealtimeMeetingCompleteDTO dto) {
AndroidRequestLogHelper.logRequest(log, "Android实时会议", "完成实时会议接口", "meetingId", id, "request", dto);
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
Meeting meeting = meetingAccessService.requireMeeting(id); Meeting meeting = meetingAccessService.requireMeeting(id);
meetingAuthorizationService.assertCanControlRealtimeMeeting(meeting, authContext, MeetingConstants.SOURCE_ANDROID); meetingAuthorizationService.assertCanControlRealtimeMeeting(meeting, authContext, MeetingConstants.SOURCE_ANDROID);

View File

@ -4,6 +4,7 @@ import com.imeeting.dto.android.AndroidAuthContext;
import com.imeeting.dto.biz.PromptTemplateVO; import com.imeeting.dto.biz.PromptTemplateVO;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
import com.imeeting.service.biz.PromptTemplateService; import com.imeeting.service.biz.PromptTemplateService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.common.ApiResponse; import com.unisbase.common.ApiResponse;
import com.unisbase.dto.PageResult; import com.unisbase.dto.PageResult;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -26,6 +28,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/android/prompts") @RequestMapping("/api/android/prompts")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidPromptController { public class AndroidPromptController {
private static final String LEGACY_MEETING_SCENE = "MEETING_TASK"; private static final String LEGACY_MEETING_SCENE = "MEETING_TASK";
@ -43,6 +46,7 @@ public class AndroidPromptController {
}) })
@GetMapping("/active/{scene}") @GetMapping("/active/{scene}")
public ApiResponse<List<PromptTemplateVO>> activePrompts(HttpServletRequest request, @PathVariable String scene) { public ApiResponse<List<PromptTemplateVO>> activePrompts(HttpServletRequest request, @PathVariable String scene) {
AndroidRequestLogHelper.logRequest(log, "Android提示词", "查询场景提示词接口", "scene", scene);
if (!LEGACY_MEETING_SCENE.equals(scene)) { if (!LEGACY_MEETING_SCENE.equals(scene)) {
return ApiResponse.error("scene 仅支持 MEETING_TASK"); return ApiResponse.error("scene 仅支持 MEETING_TASK");
} }

View File

@ -6,6 +6,7 @@ import com.imeeting.dto.android.AndroidScreenSaverItemVO;
import com.imeeting.dto.biz.ScreenSaverSelectionResult; import com.imeeting.dto.biz.ScreenSaverSelectionResult;
import com.imeeting.service.android.AndroidAuthService; import com.imeeting.service.android.AndroidAuthService;
import com.imeeting.service.biz.ScreenSaverService; import com.imeeting.service.biz.ScreenSaverService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.imeeting.support.TaskSecurityContextRunner; import com.imeeting.support.TaskSecurityContextRunner;
import com.unisbase.common.ApiResponse; import com.unisbase.common.ApiResponse;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -23,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/android/screensavers") @RequestMapping("/api/android/screensavers")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class AndroidScreenSaverController { public class AndroidScreenSaverController {
private final AndroidAuthService androidAuthService; private final AndroidAuthService androidAuthService;
@ -39,6 +42,7 @@ public class AndroidScreenSaverController {
}) })
@GetMapping("/active") @GetMapping("/active")
public ApiResponse<AndroidScreenSaverCatalogVO> active(HttpServletRequest request) { public ApiResponse<AndroidScreenSaverCatalogVO> active(HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "Android屏保", "获取当前生效屏保接口");
AndroidAuthContext authContext = androidAuthService.authenticateHttp(request); AndroidAuthContext authContext = androidAuthService.authenticateHttp(request);
ScreenSaverSelectionResult selection = querySelection(authContext); ScreenSaverSelectionResult selection = querySelection(authContext);
AndroidScreenSaverCatalogVO vo = new AndroidScreenSaverCatalogVO(); AndroidScreenSaverCatalogVO vo = new AndroidScreenSaverCatalogVO();

View File

@ -5,6 +5,7 @@ import com.imeeting.dto.android.legacy.LegacyApiResponse;
import com.imeeting.dto.android.legacy.LegacyLoginResponse; import com.imeeting.dto.android.legacy.LegacyLoginResponse;
import com.imeeting.dto.android.legacy.LegacyLoginUserResponse; import com.imeeting.dto.android.legacy.LegacyLoginUserResponse;
import com.imeeting.dto.android.legacy.LegacyRefreshTokenResponse; import com.imeeting.dto.android.legacy.LegacyRefreshTokenResponse;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.dto.LoginRequest; import com.unisbase.dto.LoginRequest;
import com.unisbase.dto.RefreshRequest; import com.unisbase.dto.RefreshRequest;
import com.unisbase.dto.SysRoleDTO; import com.unisbase.dto.SysRoleDTO;
@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestHeader;
@ -28,6 +30,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/auth") @RequestMapping("/api/auth")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyAuthController { public class LegacyAuthController {
private final AuthService authService; private final AuthService authService;
@ -35,6 +38,7 @@ public class LegacyAuthController {
@Operation(summary = "兼容登录") @Operation(summary = "兼容登录")
@PostMapping("/login") @PostMapping("/login")
public LegacyApiResponse<LegacyLoginResponse> login(@Valid @RequestBody LoginRequest request) { public LegacyApiResponse<LegacyLoginResponse> login(@Valid @RequestBody LoginRequest request) {
AndroidRequestLogHelper.logRequest(log, "兼容认证", "登录接口", "request", request);
TokenResponse tokenResponse = null; TokenResponse tokenResponse = null;
try { try {
tokenResponse = authService.login(request, true); tokenResponse = authService.login(request, true);
@ -58,6 +62,10 @@ public class LegacyAuthController {
public LegacyApiResponse<LegacyRefreshTokenResponse> refresh(@RequestBody(required = false) RefreshRequest request, public LegacyApiResponse<LegacyRefreshTokenResponse> refresh(@RequestBody(required = false) RefreshRequest request,
@RequestHeader(value = "Authorization", required = false) String authorization, @RequestHeader(value = "Authorization", required = false) String authorization,
@RequestHeader(value = "X-Android-Access-Token", required = false) String androidAccessToken) { @RequestHeader(value = "X-Android-Access-Token", required = false) String androidAccessToken) {
AndroidRequestLogHelper.logRequest(log, "兼容认证", "刷新令牌接口",
"request", request,
"authorization", authorization,
"androidAccessToken", androidAccessToken);
TokenResponse tokenResponse = null; TokenResponse tokenResponse = null;
try { try {
tokenResponse = authService.refresh(resolveRefreshToken(request, authorization, androidAccessToken)); tokenResponse = authService.refresh(resolveRefreshToken(request, authorization, androidAccessToken));

View File

@ -3,9 +3,11 @@ package com.imeeting.controller.android.legacy;
import com.imeeting.dto.android.legacy.LegacyApiResponse; import com.imeeting.dto.android.legacy.LegacyApiResponse;
import com.imeeting.dto.android.legacy.LegacyClientDownloadResponse; import com.imeeting.dto.android.legacy.LegacyClientDownloadResponse;
import com.imeeting.service.android.legacy.LegacyCatalogAdapterService; import com.imeeting.service.android.legacy.LegacyCatalogAdapterService;
import com.imeeting.support.AndroidRequestLogHelper;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -15,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/clients") @RequestMapping("/api/clients")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyClientController { public class LegacyClientController {
private final LegacyCatalogAdapterService legacyCatalogAdapterService; private final LegacyCatalogAdapterService legacyCatalogAdapterService;
@ -24,6 +27,10 @@ public class LegacyClientController {
public LegacyApiResponse<LegacyClientDownloadResponse> latestByPlatform(@RequestParam(value = "platform_code", required = false) String platformCode, public LegacyApiResponse<LegacyClientDownloadResponse> latestByPlatform(@RequestParam(value = "platform_code", required = false) String platformCode,
@RequestParam(value = "platform_type", required = false) String platformType, @RequestParam(value = "platform_type", required = false) String platformType,
@RequestParam(value = "platform_name", required = false) String platformName) { @RequestParam(value = "platform_name", required = false) String platformName) {
AndroidRequestLogHelper.logRequest(log, "兼容客户端", "查询平台最新客户端接口",
"platformCode", platformCode,
"platformType", platformType,
"platformName", platformName);
if ((platformCode == null || platformCode.isBlank()) if ((platformCode == null || platformCode.isBlank())
&& ((platformType == null || platformType.isBlank()) || (platformName == null || platformName.isBlank()))) { && ((platformType == null || platformType.isBlank()) || (platformName == null || platformName.isBlank()))) {
return LegacyApiResponse.error("400", "请提供 platform_code 参数"); return LegacyApiResponse.error("400", "请提供 platform_code 参数");

View File

@ -3,9 +3,11 @@ package com.imeeting.controller.android.legacy;
import com.imeeting.dto.android.legacy.LegacyApiResponse; import com.imeeting.dto.android.legacy.LegacyApiResponse;
import com.imeeting.dto.android.legacy.LegacyExternalAppItemResponse; import com.imeeting.dto.android.legacy.LegacyExternalAppItemResponse;
import com.imeeting.service.android.legacy.LegacyCatalogAdapterService; import com.imeeting.service.android.legacy.LegacyCatalogAdapterService;
import com.imeeting.support.AndroidRequestLogHelper;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -17,6 +19,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/external-apps") @RequestMapping("/api/external-apps")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyExternalAppController { public class LegacyExternalAppController {
private final LegacyCatalogAdapterService legacyCatalogAdapterService; private final LegacyCatalogAdapterService legacyCatalogAdapterService;
@ -24,6 +27,7 @@ public class LegacyExternalAppController {
@Operation(summary = "查询启用的外部应用") @Operation(summary = "查询启用的外部应用")
@GetMapping("/active") @GetMapping("/active")
public LegacyApiResponse<List<LegacyExternalAppItemResponse>> active(@RequestParam(value = "is_active", required = false) Integer ignoredIsActive) { public LegacyApiResponse<List<LegacyExternalAppItemResponse>> active(@RequestParam(value = "is_active", required = false) Integer ignoredIsActive) {
AndroidRequestLogHelper.logRequest(log, "兼容外部应用", "查询启用外部应用接口", "isActive", ignoredIsActive);
return LegacyApiResponse.ok(legacyCatalogAdapterService.listActiveExternalApps()); return LegacyApiResponse.ok(legacyCatalogAdapterService.listActiveExternalApps());
} }
} }

View File

@ -4,11 +4,13 @@ import com.imeeting.dto.android.legacy.LegacyApiResponse;
import com.imeeting.dto.android.legacy.LegacyLlmModelItemResponse; import com.imeeting.dto.android.legacy.LegacyLlmModelItemResponse;
import com.imeeting.dto.biz.AiModelVO; import com.imeeting.dto.biz.AiModelVO;
import com.imeeting.service.biz.AiModelService; import com.imeeting.service.biz.AiModelService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.dto.PageResult; import com.unisbase.dto.PageResult;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -22,6 +24,7 @@ import java.util.Objects;
@RestController @RestController
@RequestMapping("/api/llm-models") @RequestMapping("/api/llm-models")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyLlmModelController { public class LegacyLlmModelController {
private final AiModelService aiModelService; private final AiModelService aiModelService;
@ -30,6 +33,7 @@ public class LegacyLlmModelController {
@GetMapping("/active") @GetMapping("/active")
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
public LegacyApiResponse<List<LegacyLlmModelItemResponse>> activeModels() { public LegacyApiResponse<List<LegacyLlmModelItemResponse>> activeModels() {
AndroidRequestLogHelper.logRequest(log, "兼容模型", "查询启用大模型列表接口");
LoginUser loginUser = currentLoginUser(); LoginUser loginUser = currentLoginUser();
PageResult<List<AiModelVO>> result = aiModelService.pageModels(1, 1000, null, "LLM", loginUser.getTenantId()); PageResult<List<AiModelVO>> result = aiModelService.pageModels(1, 1000, null, "LLM", loginUser.getTenantId());
List<AiModelVO> enabledModels = result.getRecords() == null List<AiModelVO> enabledModels = result.getRecords() == null

View File

@ -23,6 +23,7 @@ import com.imeeting.entity.biz.Meeting;
import com.imeeting.mapper.biz.MeetingTranscriptMapper; import com.imeeting.mapper.biz.MeetingTranscriptMapper;
import com.imeeting.entity.biz.PromptTemplate; import com.imeeting.entity.biz.PromptTemplate;
import com.imeeting.service.android.legacy.LegacyMeetingAdapterService; import com.imeeting.service.android.legacy.LegacyMeetingAdapterService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.imeeting.service.biz.AiTaskService; import com.imeeting.service.biz.AiTaskService;
import com.imeeting.service.biz.MeetingAccessService; import com.imeeting.service.biz.MeetingAccessService;
import com.imeeting.service.biz.MeetingCommandService; import com.imeeting.service.biz.MeetingCommandService;
@ -38,6 +39,7 @@ import com.unisbase.mapper.SysUserMapper;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@ -65,7 +67,7 @@ import java.util.stream.Collectors;
@Tag(name = "兼容会议接口") @Tag(name = "兼容会议接口")
@RestController @RestController
@RequestMapping("/api/meetings") @RequestMapping("/api/meetings")
@Slf4j
public class LegacyMeetingController { public class LegacyMeetingController {
private static final String STAGE_DATA_INITIALIZATION = "data_initialization"; private static final String STAGE_DATA_INITIALIZATION = "data_initialization";
@ -163,6 +165,7 @@ public class LegacyMeetingController {
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@Log(value = "新增兼容会议", type = "兼容会议管理") @Log(value = "新增兼容会议", type = "兼容会议管理")
public LegacyApiResponse<LegacyMeetingCreateResponse> create(@RequestBody LegacyMeetingCreateRequest request) { public LegacyApiResponse<LegacyMeetingCreateResponse> create(@RequestBody LegacyMeetingCreateRequest request) {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "创建会议接口", "request", request);
MeetingVO meeting = legacyMeetingAdapterService.createMeeting(request, currentLoginUser()); MeetingVO meeting = legacyMeetingAdapterService.createMeeting(request, currentLoginUser());
return LegacyApiResponse.ok(new LegacyMeetingCreateResponse(meeting.getId())); return LegacyApiResponse.ok(new LegacyMeetingCreateResponse(meeting.getId()));
} }
@ -175,6 +178,12 @@ public class LegacyMeetingController {
@RequestParam(value = "model_code", required = false) String modelCode, @RequestParam(value = "model_code", required = false) String modelCode,
@RequestParam(value = "force_replace", defaultValue = "false") boolean forceReplace, @RequestParam(value = "force_replace", defaultValue = "false") boolean forceReplace,
@RequestParam("audio_file") MultipartFile audioFile) throws IOException { @RequestParam("audio_file") MultipartFile audioFile) throws IOException {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "上传会议音频接口",
"meetingId", meetingId,
"promptId", promptId,
"modelCode", modelCode,
"forceReplace", forceReplace,
"audioFile", audioFile);
legacyMeetingAdapterService.uploadAndTriggerOfflineProcess( legacyMeetingAdapterService.uploadAndTriggerOfflineProcess(
meetingId, meetingId,
promptId, promptId,
@ -193,6 +202,11 @@ public class LegacyMeetingController {
@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "1") Integer page,
@RequestParam(value = "page_size", defaultValue = "10") Integer pageSize, @RequestParam(value = "page_size", defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String title) { @RequestParam(required = false) String title) {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "分页查询会议接口",
"userId", ignoredUserId,
"page", page,
"pageSize", pageSize,
"title", title);
LoginUser loginUser = currentLoginUser(); LoginUser loginUser = currentLoginUser();
boolean isAdmin = Boolean.TRUE.equals(loginUser.getIsPlatformAdmin()) || Boolean.TRUE.equals(loginUser.getIsTenantAdmin()); boolean isAdmin = Boolean.TRUE.equals(loginUser.getIsPlatformAdmin()) || Boolean.TRUE.equals(loginUser.getIsTenantAdmin());
PageResult<List<MeetingVO>> result = meetingQueryService.pageMeetings( PageResult<List<MeetingVO>> result = meetingQueryService.pageMeetings(
@ -222,6 +236,7 @@ public class LegacyMeetingController {
@Operation(summary = "兼容查询会议预览数据") @Operation(summary = "兼容查询会议预览数据")
@GetMapping("/{meetingId}/preview-data") @GetMapping("/{meetingId}/preview-data")
public LegacyApiResponse<?> previewData(@PathVariable Long meetingId) { public LegacyApiResponse<?> previewData(@PathVariable Long meetingId) {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "查询会议预览数据接口", "meetingId", meetingId);
LegacyMeetingPreviewResult result = buildPreviewResult(meetingId); LegacyMeetingPreviewResult result = buildPreviewResult(meetingId);
return new LegacyApiResponse<>(result.getCode(), result.getMessage(), result.getData()); return new LegacyApiResponse<>(result.getCode(), result.getMessage(), result.getData());
} }
@ -232,6 +247,9 @@ public class LegacyMeetingController {
@Log(value = "修改兼容会议访问密码", type = "兼容会议管理") @Log(value = "修改兼容会议访问密码", type = "兼容会议管理")
public LegacyApiResponse<LegacyMeetingAccessPasswordResponse> updateAccessPassword(@PathVariable Long meetingId, public LegacyApiResponse<LegacyMeetingAccessPasswordResponse> updateAccessPassword(@PathVariable Long meetingId,
@RequestBody(required = false) LegacyMeetingAccessPasswordRequest request) { @RequestBody(required = false) LegacyMeetingAccessPasswordRequest request) {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "更新会议访问密码接口",
"meetingId", meetingId,
"request", request);
LoginUser loginUser = currentLoginUser(); LoginUser loginUser = currentLoginUser();
Meeting meeting = meetingAccessService.requireMeeting(meetingId); Meeting meeting = meetingAccessService.requireMeeting(meetingId);
if (!Objects.equals(meeting.getCreatorId(), loginUser.getUserId())) { if (!Objects.equals(meeting.getCreatorId(), loginUser.getUserId())) {
@ -249,6 +267,7 @@ public class LegacyMeetingController {
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@Log(value = "删除兼容会议", type = "兼容会议管理") @Log(value = "删除兼容会议", type = "兼容会议管理")
public LegacyApiResponse<Void> delete(@PathVariable Long meetingId) { public LegacyApiResponse<Void> delete(@PathVariable Long meetingId) {
AndroidRequestLogHelper.logRequest(log, "兼容会议", "删除会议接口", "meetingId", meetingId);
LoginUser loginUser = currentLoginUser(); LoginUser loginUser = currentLoginUser();
Meeting meeting = meetingAccessService.requireMeeting(meetingId); Meeting meeting = meetingAccessService.requireMeeting(meetingId);
meetingAccessService.assertCanEditMeeting(meeting, loginUser); meetingAccessService.assertCanEditMeeting(meeting, loginUser);

View File

@ -5,11 +5,13 @@ import com.imeeting.dto.android.legacy.LegacyPromptItemResponse;
import com.imeeting.dto.android.legacy.LegacyPromptListResponse; import com.imeeting.dto.android.legacy.LegacyPromptListResponse;
import com.imeeting.dto.biz.PromptTemplateVO; import com.imeeting.dto.biz.PromptTemplateVO;
import com.imeeting.service.biz.PromptTemplateService; import com.imeeting.service.biz.PromptTemplateService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.unisbase.dto.PageResult; import com.unisbase.dto.PageResult;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -24,6 +26,7 @@ import java.util.Objects;
@RestController @RestController
@RequestMapping("/api/prompts") @RequestMapping("/api/prompts")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyPromptController { public class LegacyPromptController {
private static final String LEGACY_MEETING_SCENE = "MEETING_TASK"; private static final String LEGACY_MEETING_SCENE = "MEETING_TASK";
@ -34,6 +37,7 @@ public class LegacyPromptController {
@GetMapping("/active/{scene}") @GetMapping("/active/{scene}")
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
public LegacyApiResponse<LegacyPromptListResponse> activePrompts(@PathVariable String scene) { public LegacyApiResponse<LegacyPromptListResponse> activePrompts(@PathVariable String scene) {
AndroidRequestLogHelper.logRequest(log, "兼容提示词", "查询场景提示词接口", "scene", scene);
if (!LEGACY_MEETING_SCENE.equals(scene)) { if (!LEGACY_MEETING_SCENE.equals(scene)) {
return LegacyApiResponse.error("400", "scene 仅支持 MEETING_TASK"); return LegacyApiResponse.error("400", "scene 仅支持 MEETING_TASK");
} }

View File

@ -3,6 +3,7 @@ package com.imeeting.controller.android.legacy;
import com.imeeting.dto.android.legacy.LegacyApiResponse; import com.imeeting.dto.android.legacy.LegacyApiResponse;
import com.imeeting.dto.android.legacy.LegacyScreenSaverCatalogResponse; import com.imeeting.dto.android.legacy.LegacyScreenSaverCatalogResponse;
import com.imeeting.service.android.legacy.LegacyScreenSaverAdapterService; import com.imeeting.service.android.legacy.LegacyScreenSaverAdapterService;
import com.imeeting.support.AndroidRequestLogHelper;
import com.imeeting.support.TaskSecurityContextRunner; import com.imeeting.support.TaskSecurityContextRunner;
import com.unisbase.dto.InternalAuthCheckResponse; import com.unisbase.dto.InternalAuthCheckResponse;
import com.unisbase.security.LoginUser; import com.unisbase.security.LoginUser;
@ -11,6 +12,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -21,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/screensavers") @RequestMapping("/api/screensavers")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class LegacyScreenSaverController { public class LegacyScreenSaverController {
private static final String HEADER_AUTHORIZATION = "Authorization"; private static final String HEADER_AUTHORIZATION = "Authorization";
@ -33,6 +36,7 @@ public class LegacyScreenSaverController {
@Operation(summary = "查询启用的屏保列表") @Operation(summary = "查询启用的屏保列表")
@GetMapping("/active") @GetMapping("/active")
public LegacyApiResponse<LegacyScreenSaverCatalogResponse> active(HttpServletRequest request) { public LegacyApiResponse<LegacyScreenSaverCatalogResponse> active(HttpServletRequest request) {
AndroidRequestLogHelper.logRequest(log, "兼容屏保", "查询启用屏保列表接口");
LoginUser loginUser = resolveLoginUser(request); LoginUser loginUser = resolveLoginUser(request);
return LegacyApiResponse.ok(queryActive(loginUser)); return LegacyApiResponse.ok(queryActive(loginUser));
} }

View File

@ -1,8 +1,13 @@
.dictionaries-page { .dictionaries-page {
padding: 24px;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
// 强制覆盖全局可能存在的 max-height: none !important 限制
// 确保 antd table 的 scroll.y 能够生效
.ant-table-wrapper .ant-table-body {
max-height: inherit !important;
}
} }
.dictionaries-header { .dictionaries-header {
@ -94,3 +99,9 @@
.h-full { .h-full {
height: 100%; height: 100%;
} }
.ant-table-wrapper .ant-spin-container {
height: calc(100vh - 410px);
display: flex;
flex-direction: column;
min-height: 0;
}

View File

@ -156,7 +156,7 @@ export default function Dictionaries() {
> >
<Row gutter={24} style={{ flex: 1, minHeight: 0, overflow: "hidden" }}> <Row gutter={24} style={{ flex: 1, minHeight: 0, overflow: "hidden" }}>
<Col span={8} className="h-full flex flex-col overflow-hidden"> <Col span={8} className="h-full flex flex-col overflow-hidden">
<Card title={<Space><BookOutlined aria-hidden="true" /><span>{t("dicts.dictType")}</span></Space>} className="app-page__panel-card flex-1 flex flex-col overflow-hidden" styles={{ body: { padding: "12px", flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" } }} extra={can("sys_dict:type:create") && <Button type="primary" size="small" icon={<PlusOutlined aria-hidden="true" />} onClick={handleAddType}>{t("common.create")}</Button>}> <Card title={<Space><BookOutlined aria-hidden="true" /><span>{t("dicts.dictType")}</span></Space>} className="app-page__panel-card flex-1 flex flex-col overflow-hidden" styles={{ body: { padding: "12px", flex: 1, display: "flex", flexDirection: "column", overflow: "hidden",maxHeight:"calc(100vh - 360px)" } }} extra={can("sys_dict:type:create") && <Button type="primary" size="small" icon={<PlusOutlined aria-hidden="true" />} onClick={handleAddType}>{t("common.create")}</Button>}>
<div style={{ marginBottom: 12 }} className="flex-shrink-0"> <div style={{ marginBottom: 12 }} className="flex-shrink-0">
<Space.Compact style={{ width: "100%" }}> <Space.Compact style={{ width: "100%" }}>
<Input <Input