From 96e1fa45348a06615c33d441b756367070b733e1 Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 29 Jan 2026 13:26:13 -0800 Subject: [PATCH] =?UTF-8?q?fix(mining-admin):=20=E9=80=82=E9=85=8D=20minin?= =?UTF-8?q?g-app=20=E7=89=88=E6=9C=AC=E6=A3=80=E6=9F=A5=20API=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CheckUpdateDto: current_version_code 改为 versionCode 匹配 mining-app 请求参数 - MobileVersionController: 响应格式改为 { hasUpdate, latestVersion: {...} } 匹配 mining-app 解析 - TransformInterceptor: 添加 @SkipTransform() 装饰器,移动端版本检查接口跳过响应包装 Co-Authored-By: Claude Opus 4.5 --- .../controllers/mobile-version.controller.ts | 42 ++++++++++--------- .../src/api/dto/version/check-update.dto.ts | 2 +- .../interceptors/transform.interceptor.ts | 17 +++++++- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/backend/services/mining-admin-service/src/api/controllers/mobile-version.controller.ts b/backend/services/mining-admin-service/src/api/controllers/mobile-version.controller.ts index ecd2cdeb..b8088644 100644 --- a/backend/services/mining-admin-service/src/api/controllers/mobile-version.controller.ts +++ b/backend/services/mining-admin-service/src/api/controllers/mobile-version.controller.ts @@ -2,12 +2,14 @@ import { Controller, Get, Query } from '@nestjs/common' import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger' import { VersionService } from '../../application/services/version.service' import { Platform } from '../../domain/version-management' -import { CheckUpdateDto, UpdateCheckResultDto } from '../dto/version' +import { CheckUpdateDto } from '../dto/version' import { Public } from '../../shared/guards/admin-auth.guard' +import { SkipTransform } from '../../shared/interceptors/transform.interceptor' /** * Mobile App Version API Controller - * This endpoint is designed to match the mobile app's expected API format + * Response format matches mining-app (Flutter) expected format: + * { hasUpdate: boolean, latestVersion?: { versionCode, versionName, ... } } */ @ApiTags('Mobile App Version') @Controller('api/app/version') @@ -22,29 +24,31 @@ export class MobileVersionController { @Get('check') @Public() - @ApiOperation({ summary: '检查更新 (移动端专用)' }) - @ApiResponse({ status: 200, type: UpdateCheckResultDto }) - async checkUpdate(@Query() dto: CheckUpdateDto): Promise { + @SkipTransform() + @ApiOperation({ summary: '检查更新 (mining-app 专用)' }) + async checkUpdate(@Query() dto: CheckUpdateDto) { const platform = this.getPlatform(dto.platform) - const result = await this.versionService.checkUpdate(platform, dto.current_version_code) + const result = await this.versionService.checkUpdate(platform, dto.versionCode) if (!result.hasUpdate || !result.latestVersion) { - return { - needUpdate: false, - } + return { hasUpdate: false } } + const v = result.latestVersion return { - needUpdate: true, - version: result.latestVersion.versionName, - versionCode: result.latestVersion.versionCode, - downloadUrl: result.latestVersion.downloadUrl, - fileSize: Number(BigInt(result.latestVersion.fileSize)), - fileSizeFriendly: result.latestVersion.fileSizeFriendly, - sha256: result.latestVersion.fileSha256, - forceUpdate: result.isForceUpdate, - updateLog: result.latestVersion.changelog, - releaseDate: result.latestVersion.releaseDate?.toISOString() ?? new Date().toISOString(), + hasUpdate: true, + latestVersion: { + versionCode: v.versionCode, + versionName: v.versionName, + buildNumber: v.buildNumber, + downloadUrl: v.downloadUrl, + fileSize: Number(BigInt(v.fileSize)), + fileSha256: v.fileSha256, + changelog: v.changelog, + isForceUpdate: result.isForceUpdate, + minOsVersion: v.minOsVersion ?? null, + releaseDate: v.releaseDate?.toISOString() ?? null, + }, } } } diff --git a/backend/services/mining-admin-service/src/api/dto/version/check-update.dto.ts b/backend/services/mining-admin-service/src/api/dto/version/check-update.dto.ts index f0f305bd..8e339f37 100644 --- a/backend/services/mining-admin-service/src/api/dto/version/check-update.dto.ts +++ b/backend/services/mining-admin-service/src/api/dto/version/check-update.dto.ts @@ -17,5 +17,5 @@ export class CheckUpdateDto { @Type(() => Number) @IsInt() @Min(0) - current_version_code: number + versionCode: number } diff --git a/backend/services/mining-admin-service/src/shared/interceptors/transform.interceptor.ts b/backend/services/mining-admin-service/src/shared/interceptors/transform.interceptor.ts index 4ea2932b..b0e2f6e4 100644 --- a/backend/services/mining-admin-service/src/shared/interceptors/transform.interceptor.ts +++ b/backend/services/mining-admin-service/src/shared/interceptors/transform.interceptor.ts @@ -1,10 +1,25 @@ -import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; +import { Injectable, NestInterceptor, ExecutionContext, CallHandler, SetMetadata } from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +export const SKIP_TRANSFORM_KEY = 'skipTransform'; +export const SkipTransform = () => SetMetadata(SKIP_TRANSFORM_KEY, true); + @Injectable() export class TransformInterceptor implements NestInterceptor { + constructor(private readonly reflector: Reflector) {} + intercept(context: ExecutionContext, next: CallHandler): Observable { + const skip = this.reflector.getAllAndOverride(SKIP_TRANSFORM_KEY, [ + context.getHandler(), + context.getClass(), + ]); + + if (skip) { + return next.handle(); + } + return next.handle().pipe(map((data) => ({ success: true, data, timestamp: new Date().toISOString() }))); } }