feat(mobile-upgrade): add IT0 App version management support
Add IT0 App as the third application in the mobile-upgrade frontend, connecting to IT0's new version-service backend. Changes: - api-client.ts: added 'it0' to AppType union, APP_CONFIGS entry pointing to NEXT_PUBLIC_IT0_API_URL (default: it0api.szaiai.com), exported it0ApiClient instance - version-repository-impl.ts: added it0VersionRepository instance, updated constructor client selection for it0, updated getVersionRepository() factory with switch/case - page.tsx: added IT0 App to APP_LABELS, added emerald green toggle button in app selector - upload-modal.tsx: fixed existing bug where parsePackage() was hardcoded to use mobile repository regardless of selected app; now uses getVersionRepository(appType) dynamically Backend: IT0 version-service at it0api.szaiai.com/api/v1/versions Env var: NEXT_PUBLIC_IT0_API_URL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2b2e1efc7a
commit
33ae08c90f
|
|
@ -2,15 +2,16 @@
|
|||
* 移动端版本管理首页
|
||||
*
|
||||
* 功能概述:
|
||||
* 统一管理榴莲 App 和股行 App 的版本发布。
|
||||
* 统一管理榴莲 App、股行 App 和 IT0 App 的版本发布。
|
||||
* 支持在同一界面切换管理不同应用的版本。
|
||||
*
|
||||
* 支持的应用:
|
||||
* - 榴莲 App (mobile): 连接 admin-service 后端
|
||||
* - 股行 App (mining): 连接 mining-admin-service 后端
|
||||
* - IT0 App (it0): 连接 IT0 version-service 后端
|
||||
*
|
||||
* 主要功能:
|
||||
* 1. 应用切换 - 在两个应用间切换版本管理
|
||||
* 1. 应用切换 - 在多个应用间切换版本管理
|
||||
* 2. 平台筛选 - 按 Android/iOS 筛选版本
|
||||
* 3. 版本上传 - 上传新版本 APK/IPA
|
||||
* 4. 版本管理 - 编辑、删除、启用/禁用版本
|
||||
|
|
@ -33,6 +34,7 @@ import toast from 'react-hot-toast'
|
|||
const APP_LABELS: Record<AppType, { name: string; description: string }> = {
|
||||
mobile: { name: '榴莲 App', description: '管理榴莲 App 的版本更新' },
|
||||
mining: { name: '股行 App', description: '管理股行 App 的版本更新' },
|
||||
it0: { name: 'IT0 App', description: '管理 IT0 App 的版本更新' },
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
|
|
@ -120,6 +122,16 @@ export default function HomePage() {
|
|||
>
|
||||
股行 App
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleAppTypeChange('it0')}
|
||||
className={`px-5 py-2.5 rounded-lg text-sm font-medium transition-all shadow-sm ${
|
||||
appType === 'it0'
|
||||
? 'bg-emerald-600 text-white shadow-emerald-200'
|
||||
: 'bg-white text-gray-700 hover:bg-gray-50 border border-gray-200'
|
||||
}`}
|
||||
>
|
||||
IT0 App
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@
|
|||
*
|
||||
* 功能概述:
|
||||
* 为前端提供统一的HTTP客户端,支持连接多个后端服务。
|
||||
* 当前支持两个应用的版本管理:
|
||||
* 当前支持三个应用的版本管理:
|
||||
* - mobile (榴莲 App): 连接 admin-service 后端
|
||||
* - mining (股行 App): 连接 mining-admin-service 后端
|
||||
* - it0 (IT0 App): 连接 IT0 version-service 后端
|
||||
*
|
||||
* 配置方式:
|
||||
* 通过环境变量配置后端地址:
|
||||
* - NEXT_PUBLIC_API_URL: 榴莲App后端地址
|
||||
* - NEXT_PUBLIC_MINING_API_URL: 股行App后端地址
|
||||
* - NEXT_PUBLIC_IT0_API_URL: IT0 App后端地址
|
||||
*
|
||||
* 使用方式:
|
||||
* ```typescript
|
||||
|
|
@ -38,8 +40,9 @@ export class ApiError extends Error {
|
|||
* 应用类型
|
||||
* - mobile: 榴莲 App (使用 admin-service 后端)
|
||||
* - mining: 股行 App (使用 mining-admin-service 后端)
|
||||
* - it0: IT0 App (使用 IT0 version-service 后端)
|
||||
*/
|
||||
export type AppType = 'mobile' | 'mining'
|
||||
export type AppType = 'mobile' | 'mining' | 'it0'
|
||||
|
||||
export interface ApiConfig {
|
||||
baseURL: string
|
||||
|
|
@ -52,7 +55,8 @@ export interface ApiConfig {
|
|||
* 注意:
|
||||
* - mobile 使用 /api/v1/versions 前缀 (admin-service)
|
||||
* - mining 使用 /api/v2/upgrade-versions 前缀 (mining-admin-service 公开接口)
|
||||
* - API前缀不同是因为两个后端是独立的服务
|
||||
* - it0 使用 /api/v1/versions 前缀 (IT0 version-service)
|
||||
* - API前缀不同是因为各后端是独立的服务
|
||||
*/
|
||||
const APP_CONFIGS: Record<AppType, ApiConfig> = {
|
||||
// 榴莲 App - 连接原有的 admin-service 后端
|
||||
|
|
@ -65,6 +69,11 @@ const APP_CONFIGS: Record<AppType, ApiConfig> = {
|
|||
baseURL: process.env.NEXT_PUBLIC_MINING_API_URL || 'http://localhost:3023',
|
||||
apiPrefix: '/api/v2/upgrade-versions',
|
||||
},
|
||||
// IT0 App - 连接 IT0 version-service 后端
|
||||
it0: {
|
||||
baseURL: process.env.NEXT_PUBLIC_IT0_API_URL || 'https://it0api.szaiai.com',
|
||||
apiPrefix: '/api/v1/versions',
|
||||
},
|
||||
}
|
||||
|
||||
export function createApiClient(appType: AppType = 'mobile'): AxiosInstance {
|
||||
|
|
@ -111,3 +120,4 @@ export function getApiPrefix(appType: AppType): string {
|
|||
|
||||
export const apiClient = createApiClient('mobile')
|
||||
export const miningApiClient = createApiClient('mining')
|
||||
export const it0ApiClient = createApiClient('it0')
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
ParsedPackageInfo,
|
||||
Platform,
|
||||
} from '@/domain'
|
||||
import { apiClient, miningApiClient, AppType, getApiPrefix } from '../http/api-client'
|
||||
import { apiClient, miningApiClient, it0ApiClient, AppType, getApiPrefix } from '../http/api-client'
|
||||
|
||||
export class VersionRepositoryImpl implements IVersionRepository {
|
||||
private client: AxiosInstance
|
||||
|
|
@ -20,7 +20,9 @@ export class VersionRepositoryImpl implements IVersionRepository {
|
|||
this.client = client
|
||||
this.apiPrefix = '/api/v1/versions'
|
||||
} else {
|
||||
this.client = appType === 'mining' ? miningApiClient : apiClient
|
||||
this.client = appType === 'mining' ? miningApiClient
|
||||
: appType === 'it0' ? it0ApiClient
|
||||
: apiClient
|
||||
this.apiPrefix = getApiPrefix(appType)
|
||||
}
|
||||
}
|
||||
|
|
@ -118,11 +120,16 @@ export class VersionRepositoryImpl implements IVersionRepository {
|
|||
}
|
||||
}
|
||||
|
||||
// Pre-created repository instances for both apps
|
||||
// Pre-created repository instances for all apps
|
||||
export const versionRepository = new VersionRepositoryImpl('mobile')
|
||||
export const miningVersionRepository = new VersionRepositoryImpl('mining')
|
||||
export const it0VersionRepository = new VersionRepositoryImpl('it0')
|
||||
|
||||
// Factory function to get repository by app type
|
||||
export function getVersionRepository(appType: AppType): VersionRepositoryImpl {
|
||||
return appType === 'mining' ? miningVersionRepository : versionRepository
|
||||
switch (appType) {
|
||||
case 'mining': return miningVersionRepository
|
||||
case 'it0': return it0VersionRepository
|
||||
default: return versionRepository
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import { useState, useRef } from 'react'
|
||||
import { Platform } from '@/domain'
|
||||
import { useVersionActions } from '@/application'
|
||||
import { versionRepository } from '@/infrastructure/repositories/version-repository-impl'
|
||||
import { useVersionActions, useAppType } from '@/application'
|
||||
import { getVersionRepository } from '@/infrastructure/repositories/version-repository-impl'
|
||||
|
||||
interface UploadModalProps {
|
||||
onClose: () => void
|
||||
|
|
@ -12,6 +12,7 @@ interface UploadModalProps {
|
|||
|
||||
export function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
||||
const { uploadVersion } = useVersionActions()
|
||||
const { appType } = useAppType()
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
|
@ -48,7 +49,7 @@ export function UploadModal({ onClose, onSuccess }: UploadModalProps) {
|
|||
// Auto-parse package info
|
||||
setIsParsing(true)
|
||||
try {
|
||||
const parsed = await versionRepository.parsePackage(selectedFile, detectedPlatform)
|
||||
const parsed = await getVersionRepository(appType).parsePackage(selectedFile, detectedPlatform)
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
platform: detectedPlatform,
|
||||
|
|
|
|||
Loading…
Reference in New Issue