From 55826db8c4e2fabe92adf679489d7e56a66e50cf Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Fri, 8 May 2026 12:00:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(update):=20=E6=B7=BB=E5=8A=A0=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=9B=B4=E6=96=B0=E6=A3=80=E6=9F=A5=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=94=A8=E6=88=B7ID=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在UpdateApi接口中新增可选的userId查询参数 - 新增UpdateSDK对象用于统一管理应用更新逻辑 - 实现应用版本检查、下载安装和APK文件处理功能 - 添加下载URL规范化处理逻辑 - 在Flutter SDK中新增update模块实现跨平台更新功能 - 在iOS SDK中新增UpdateSDK类提供应用更新检查接口 - 支持Android和iOS平台的应用商店跳转功能 - 添加React Native SDK的更新检查和插件注册功能 - 实现RN Bundle的检查、下载和缓存机制 --- ops-platform/src/api/ops.ts | 19 +++++++ .../views/services/ServiceRequestsView.vue | 16 ++++++ tenant-platform/src/api/update.ts | 1 + .../views/update/VersionManagementView.vue | 50 +++++++++++++++---- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/ops-platform/src/api/ops.ts b/ops-platform/src/api/ops.ts index 8841deb..37e291d 100644 --- a/ops-platform/src/api/ops.ts +++ b/ops-platform/src/api/ops.ts @@ -49,6 +49,25 @@ export interface ServiceRequest { reviewNote?: string createdAt: string reviewedAt?: string + tenant?: { + id: string + username: string + nickname: string + email: string + phone?: string + type: 'MAIN' | 'SUB' + status: 'ACTIVE' | 'DISABLED' | 'PENDING_EMAIL' + } | null + app?: { + id: string + appKey: string + name: string + packageName: string + iosBundleId?: string + harmonyBundleName?: string + tenantId: string + createdAt: string + } | null } export interface ServiceRequestPage { diff --git a/ops-platform/src/views/services/ServiceRequestsView.vue b/ops-platform/src/views/services/ServiceRequestsView.vue index 94bd5e6..9934708 100644 --- a/ops-platform/src/views/services/ServiceRequestsView.vue +++ b/ops-platform/src/views/services/ServiceRequestsView.vue @@ -11,6 +11,22 @@ + + + + + + @@ -260,36 +260,47 @@ + + + + - + 比例 成员 - + @@ -700,6 +711,7 @@ const storeConfigs = ref([]) const loadingPublishConfig = ref(false) const savingPublishConfig = ref(false) const publishConfigForm = ref({ + allowAnonymousUpdateCheck: false, defaultGrayPercent: 0, grayMode: 'PERCENT' as GrayMode, graySelectionSource: 'LOCAL' as GraySelectionSource, @@ -734,6 +746,7 @@ const loadingOperationLogs = ref(false) const hasGraySelectCallback = computed(() => Boolean(publishConfigForm.value.graySelectCallbackUrl.trim())) const hasGrayDirectorySyncCallback = computed(() => Boolean(publishConfigForm.value.grayDirectorySyncCallbackUrl.trim())) const hasAnyGrayCallback = computed(() => hasGraySelectCallback.value || hasGrayDirectorySyncCallback.value) +const allowAnonymousUpdateCheck = computed(() => Boolean(publishConfigForm.value.allowAnonymousUpdateCheck)) type FieldDef = { key: string; label: string; type?: 'password' | 'textarea'; placeholder?: string } type GuideStep = { title: string; description: string } @@ -1041,6 +1054,7 @@ function normalizePublishConfig(raw: Record | null | undefined) const grayMode = String(raw?.grayMode ?? 'PERCENT') as GrayMode const graySelectionSource = String(raw?.graySelectionSource ?? 'LOCAL') as GraySelectionSource return { + allowAnonymousUpdateCheck: Boolean(raw?.allowAnonymousUpdateCheck ?? raw?.defaultAllowAnonymousUpdateCheck ?? false), defaultGrayPercent: Number((raw as Record)?.defaultGrayPercent ?? 0), grayMode, graySelectionSource, @@ -1067,6 +1081,10 @@ async function loadPublishConfig() { try { const res = await updateAdminApi.getPublishConfig(appKey) publishConfigForm.value = parsePublishConfig(res.data.data.configJson) + if (allowAnonymousUpdateCheck.value) { + publishConfigForm.value.grayMode = 'PERCENT' + publishConfigForm.value.graySelectionSource = 'LOCAL' + } if (publishConfigForm.value.grayMode === 'MEMBERS' && !hasAnyGrayCallback.value) { publishConfigForm.value.grayMode = 'PERCENT' } @@ -1090,6 +1108,10 @@ async function savePublishConfig() { graySelectCallbackUrl: normalizeCallbackUrl(publishConfigForm.value.graySelectCallbackUrl), grayDirectorySyncCallbackUrl: normalizeCallbackUrl(publishConfigForm.value.grayDirectorySyncCallbackUrl), } + if (payload.allowAnonymousUpdateCheck) { + payload.grayMode = 'PERCENT' + payload.graySelectionSource = 'LOCAL' + } if (payload.grayMode === 'MEMBERS' && !hasAnyGrayCallback.value) { ElMessage.warning('成员模式至少需要配置一个回调地址') return @@ -1161,6 +1183,10 @@ const grayForm = ref({ }) function openGrayDialog(row: { id: string }, type: 'app' | 'rn') { + if (allowAnonymousUpdateCheck.value) { + ElMessage.warning('当前应用开启了免登录检查更新,灰度发布已禁用') + return + } grayTarget.value = { id: row.id, type } grayForm.value = { enabled: true, @@ -1212,6 +1238,10 @@ async function syncGrayMembers() { async function submitGray() { if (!grayTarget.value) return + if (allowAnonymousUpdateCheck.value) { + ElMessage.warning('当前应用开启了免登录检查更新,灰度发布已禁用') + return + } if (grayForm.value.enabled && grayForm.value.grayMode === 'MEMBERS' && grayForm.value.selectionSource === 'LOCAL' && !hasGrayDirectorySyncCallback.value) { ElMessage.warning('未配置成员目录同步回调,无法选择本地成员') return