2026-04-24 16:16:54 +08:00
|
|
|
import axios from 'axios'
|
|
|
|
|
|
|
|
|
|
const updateClient = axios.create({
|
2026-04-28 16:08:07 +08:00
|
|
|
baseURL: 'http://192.168.116.9:8084',
|
2026-04-24 16:16:54 +08:00
|
|
|
timeout: 30000,
|
|
|
|
|
})
|
|
|
|
|
|
2026-04-28 16:08:07 +08:00
|
|
|
if (import.meta.env.DEV) {
|
|
|
|
|
updateClient.interceptors.request.use((config) => {
|
|
|
|
|
console.debug('[tenant-platform][UPDATE] request', {
|
|
|
|
|
method: config.method?.toUpperCase(),
|
|
|
|
|
url: config.baseURL ? `${config.baseURL}${config.url ?? ''}` : config.url,
|
|
|
|
|
params: config.params,
|
|
|
|
|
})
|
|
|
|
|
return config
|
|
|
|
|
})
|
|
|
|
|
updateClient.interceptors.response.use((res) => {
|
|
|
|
|
console.debug('[tenant-platform][UPDATE] response', {
|
|
|
|
|
status: res.status,
|
|
|
|
|
url: res.config.url,
|
|
|
|
|
})
|
|
|
|
|
return res
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-24 16:16:54 +08:00
|
|
|
updateClient.interceptors.request.use((config) => {
|
|
|
|
|
const token = localStorage.getItem('token')
|
|
|
|
|
if (token) config.headers.Authorization = `Bearer ${token}`
|
|
|
|
|
return config
|
|
|
|
|
})
|
|
|
|
|
|
2026-04-29 00:36:41 +08:00
|
|
|
export type StoreType = 'HUAWEI' | 'MI' | 'OPPO' | 'VIVO' | 'HONOR' | 'APP_STORE' | 'GOOGLE_PLAY'
|
|
|
|
|
export type StoreReviewState = 'PENDING' | 'UNDER_REVIEW' | 'APPROVED' | 'REJECTED'
|
|
|
|
|
|
|
|
|
|
export interface StoreConfig {
|
|
|
|
|
id: string
|
|
|
|
|
appId: string
|
|
|
|
|
storeType: StoreType
|
|
|
|
|
configJson?: string
|
|
|
|
|
enabled: boolean
|
|
|
|
|
updatedAt: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-24 16:16:54 +08:00
|
|
|
export interface AppVersion {
|
|
|
|
|
id: string
|
|
|
|
|
appId: string
|
|
|
|
|
platform: 'ANDROID' | 'IOS'
|
|
|
|
|
versionName: string
|
|
|
|
|
versionCode: number
|
2026-04-29 00:36:41 +08:00
|
|
|
packageName?: string
|
2026-04-24 16:16:54 +08:00
|
|
|
downloadUrl?: string
|
|
|
|
|
changeLog?: string
|
|
|
|
|
forceUpdate: boolean
|
|
|
|
|
publishStatus: 'DRAFT' | 'PUBLISHED' | 'DEPRECATED'
|
|
|
|
|
grayEnabled: boolean
|
|
|
|
|
grayPercent: number
|
|
|
|
|
appStoreUrl?: string
|
|
|
|
|
marketUrl?: string
|
2026-04-29 00:36:41 +08:00
|
|
|
scheduledPublishAt?: string
|
|
|
|
|
autoPublishAfterReview: boolean
|
|
|
|
|
webhookUrl?: string
|
|
|
|
|
storeSubmitTargets?: string
|
|
|
|
|
storeReviewStatus?: string
|
2026-04-24 16:16:54 +08:00
|
|
|
createdAt: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-29 12:33:26 +08:00
|
|
|
export interface AppPackageInspectResult {
|
|
|
|
|
platform: 'ANDROID' | 'IOS'
|
|
|
|
|
packageName?: string
|
|
|
|
|
versionName?: string
|
|
|
|
|
versionCode?: number
|
|
|
|
|
fileName?: string
|
|
|
|
|
detected: boolean
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-24 16:16:54 +08:00
|
|
|
export interface RnBundle {
|
|
|
|
|
id: string
|
|
|
|
|
appId: string
|
|
|
|
|
moduleId: string
|
|
|
|
|
platform: 'ANDROID' | 'IOS'
|
|
|
|
|
version: string
|
|
|
|
|
md5: string
|
|
|
|
|
minCommonVersion?: string
|
|
|
|
|
note?: string
|
|
|
|
|
publishStatus: 'DRAFT' | 'PUBLISHED' | 'DEPRECATED'
|
|
|
|
|
grayEnabled: boolean
|
|
|
|
|
grayPercent: number
|
|
|
|
|
createdAt: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-29 12:33:26 +08:00
|
|
|
export interface RnBundleInspectResult {
|
|
|
|
|
moduleId?: string
|
|
|
|
|
platform?: 'ANDROID' | 'IOS'
|
|
|
|
|
version?: string
|
|
|
|
|
minCommonVersion?: string
|
|
|
|
|
fileName?: string
|
|
|
|
|
detected: boolean
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-28 21:05:07 +08:00
|
|
|
export interface UnifiedAppUploadItem {
|
|
|
|
|
fileKey: string
|
|
|
|
|
platform: 'ANDROID' | 'IOS'
|
|
|
|
|
versionName: string
|
|
|
|
|
versionCode: number
|
|
|
|
|
changeLog?: string
|
|
|
|
|
forceUpdate: boolean
|
|
|
|
|
appStoreUrl?: string
|
|
|
|
|
marketUrl?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UnifiedRnUploadItem {
|
|
|
|
|
fileKey: string
|
|
|
|
|
moduleId: string
|
|
|
|
|
platform: 'ANDROID' | 'IOS'
|
|
|
|
|
version: string
|
|
|
|
|
minCommonVersion?: string
|
|
|
|
|
note?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface UnifiedReleaseManifest {
|
|
|
|
|
appVersions: UnifiedAppUploadItem[]
|
|
|
|
|
rnBundles: UnifiedRnUploadItem[]
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-24 16:16:54 +08:00
|
|
|
export const updateAdminApi = {
|
|
|
|
|
listAppVersions(appId: string, platform: 'ANDROID' | 'IOS') {
|
|
|
|
|
return updateClient.get<{ data: AppVersion[] }>('/api/v1/updates/app/list', {
|
|
|
|
|
params: { appId, platform },
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
publishAppVersion(id: string) {
|
|
|
|
|
return updateClient.post(`/api/v1/updates/app/${id}/publish`)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
unpublishAppVersion(id: string) {
|
|
|
|
|
return updateClient.post(`/api/v1/updates/app/${id}/unpublish`)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
grayAppVersion(id: string, enabled: boolean, percent: number) {
|
|
|
|
|
return updateClient.post(`/api/v1/updates/app/${id}/gray`, { enabled, percent })
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
uploadAppVersion(formData: FormData) {
|
|
|
|
|
return updateClient.post<{ data: AppVersion }>('/api/v1/updates/app/upload', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
2026-04-29 12:33:26 +08:00
|
|
|
inspectAppPackage(formData: FormData) {
|
|
|
|
|
return updateClient.post<{ data: AppPackageInspectResult }>('/api/v1/updates/app/inspect', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
2026-04-24 16:16:54 +08:00
|
|
|
listRnBundles(appId: string, moduleId?: string, platform?: string) {
|
|
|
|
|
return updateClient.get<{ data: RnBundle[] }>('/api/v1/rn/list', {
|
|
|
|
|
params: { appId, ...(moduleId && { moduleId }), ...(platform && { platform }) },
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
publishRnBundle(id: string) {
|
|
|
|
|
return updateClient.post(`/api/v1/rn/${id}/publish`)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
unpublishRnBundle(id: string) {
|
|
|
|
|
return updateClient.post(`/api/v1/rn/${id}/unpublish`)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
grayRnBundle(id: string, enabled: boolean, percent: number) {
|
|
|
|
|
return updateClient.post(`/api/v1/rn/${id}/gray`, { enabled, percent })
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
uploadRnBundle(formData: FormData) {
|
|
|
|
|
return updateClient.post<{ data: RnBundle }>('/api/v1/rn/upload', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
},
|
2026-04-28 21:05:07 +08:00
|
|
|
|
2026-04-29 12:33:26 +08:00
|
|
|
inspectRnBundle(formData: FormData) {
|
|
|
|
|
return updateClient.post<{ data: RnBundleInspectResult }>('/api/v1/rn/inspect', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
2026-04-28 21:05:07 +08:00
|
|
|
uploadUnifiedRelease(formData: FormData) {
|
|
|
|
|
return updateClient.post('/api/v1/updates/unified/upload', formData, {
|
|
|
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
|
|
|
})
|
|
|
|
|
},
|
2026-04-29 00:36:41 +08:00
|
|
|
|
|
|
|
|
// ── Store config ────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
getStoreConfigs(appId: string) {
|
|
|
|
|
return updateClient.get<{ data: StoreConfig[] }>('/api/v1/updates/store/configs', { params: { appId } })
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
saveStoreConfig(appId: string, storeType: StoreType, configJson: string, enabled: boolean) {
|
|
|
|
|
return updateClient.put<{ data: StoreConfig }>(
|
|
|
|
|
`/api/v1/updates/store/configs/${storeType}`,
|
|
|
|
|
{ configJson, enabled },
|
|
|
|
|
{ params: { appId } },
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
deleteStoreConfig(appId: string, storeType: StoreType) {
|
|
|
|
|
return updateClient.delete(`/api/v1/updates/store/configs/${storeType}`, { params: { appId } })
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
executeSubmitToStores(versionId: string, storeTypes: StoreType[]) {
|
|
|
|
|
return updateClient.post<{ data: AppVersion }>(
|
|
|
|
|
`/api/v1/updates/store/app/${versionId}/execute-submit`,
|
|
|
|
|
{ storeTypes },
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
updateStoreReview(versionId: string, storeType: StoreType, state: StoreReviewState) {
|
|
|
|
|
return updateClient.post<{ data: AppVersion }>(
|
|
|
|
|
`/api/v1/updates/store/app/${versionId}/review`,
|
|
|
|
|
{ storeType, state },
|
|
|
|
|
)
|
|
|
|
|
},
|
2026-04-24 16:16:54 +08:00
|
|
|
}
|