提交图

37 次代码提交

作者 SHA1 备注 提交日期
XuqmGroup
501d7e09ab fix(update): fix OPPO token expiry, sign empty params, and MI already-live detection
- OPPO: re-obtain access token after APK upload (prevents expiry during long uploads)
- OPPO: exclude empty-string params from api_sign computation per OPPO spec
- OPPO: include errno in error message for easier debugging
- MI: detect already-live version via packageInfo.versionCode before upload;
  throw VersionAlreadyLiveException → executor marks state APPROVED instead of REJECTED

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 19:11:13 +08:00
XuqmGroup
450a44de68 fix: isolate private deployment databases and fix store review refresh bugs
application.yml — all services:
- Replace hardcoded jdbc:mysql://39.107.53.187 with ${SPRING_DATASOURCE_URL:fallback}
- Same for SPRING_DATASOURCE_USERNAME/PASSWORD
- im-service: replace hardcoded redisdev.xuqinmin.com with ${SPRING_DATA_REDIS_*}
  This ensures docker-compose environment overrides take effect; without these
  placeholders, Spring Boot's relaxed binding couldn't override the YAML values
  and the private deployment connected to production databases.

StoreSubmissionService.refreshStoreReviewStatus — two bugs fixed:
1. MI/UNDER_REVIEW_XIAOMI branch now guards against downgrading APPROVED state.
   Xiaomi's poll API returns UNDER_REVIEW_XIAOMI when the submitted version is
   not yet the live version, even after the store approves it. Previously this
   caused the manual refresh to overwrite a webhook-confirmed APPROVED with
   UNDER_REVIEW on every click.
2. When the poll returns APPROVED but currentSubmissionLive=false (another version
   is live on the store), no longer overwrite an existing APPROVED (from webhook)
   with nonCurrentRelease=true. The webhook is authoritative; the live version
   difference just means distribution is pending, not that this is a non-current
   release. Only adds nonCurrentRelease when transitioning FROM a non-APPROVED
   state (true pre-existing detection).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 18:25:50 +08:00
XuqmGroup
d007072ea9 fix(update): send webhook on store live detection (Xiaomi 已上架)
updateStoreReviewLive was calling IM notifier but not sendWebhook,
so polling-detected APPROVED events (e.g. Xiaomi going live) never
triggered the tenant's configured webhook URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 15:57:51 +08:00
XuqmGroup
4d54d2a4a4 docs(private): 更新私有化SDK设计文档添加配置管理和错误码规范
- Flutter包名格式从xuqm_private_flutter_*改为xuqm_private_*
- 添加configVersion字段用于追踪配置变更,格式为YYYY.MM.DD-序号
- 添加配置版本管理说明,包含schemaVersion兼容性策略
- 添加配置热更新机制,支持冷加载和热加载两种方式
- 添加多环境配置支持,可通过activeProfile指定生效环境
- 添加统一错误码规范,覆盖配置缺失、格式错误、版本不兼容等场景
- 更新验收标准,包含热更新、多环境切换、错误码一致性要求
- 添加私有化开发计划中的错误码规范、文档同步、数据迁移等任务
- 补充MySQL运维细节、证书自动续期、监控告警、日志收集等部署要求
- 添加性能基准指标,包含HTTP API、WebSocket、文件传输等性能要求
- 修复应用商店审核状态轮询中的逻辑错误,添加小米商店特殊处理
- 更新前端界面显示审核版本信息,优化状态刷新逻辑
2026-05-18 19:17:44 +08:00
XuqmGroup
93fdb31cdc docs(private): 完善私有化部署开发计划和设计规范
- 增加实时进度和交接规则,定义任务状态枚举和更新格式
- 创建任务进度台账,涵盖P0-P5阶段全部开发任务
- 补充部署仓库交付边界确认和进度审计规范
- 完善MySQL/Redis双模式支持,增加external/managed选项
- 增加离线部署、安全治理、可观测性等完整交付能力
- 更新仓库结构设计,增加secrets.env、observability、data目录
- 补充健康检查、诊断脚本、升级回滚、备份恢复详细要求
- 优化应用商店审核状态查询逻辑,增加手动刷新接口
- 修复小米和VIVO商店状态查询中的版本匹配逻辑错误
- 增加缓存键版本隔离,防止不同版本状态混淆
- 优化厂商API连通性检查和审核状态轮询机制
2026-05-18 19:00:38 +08:00
XuqmGroup
87edb316a5 feat(private-deploy): 支持 MySQL/Redis 外部连接和托管模式部署
- 添加 external 和 managed 两种数据库/缓存模式支持
- 实现 MySQL/Redis 托管安装脚本和配置向导
- 支持客户自备连接或部署脚本新建基础设施
- 更新部署文档说明不同模式的配置和验证要求
- 添加应用版本防重复上传和删除功能
- 实现应用商店预提交检查和发布计划功能
2026-05-18 18:37:10 +08:00
XuqmGroup
b3b33dbb7b fix: remove unreliable post-failure live-check; restrict REJECTED poll to HUAWEI
Post-failure live check called pollStoreSingleReviewState on submission
failure, but for MI/VIVO/OPPO/HONOR the poll returns APPROVED for ANY
live version (not version-specific). This caused false positives: if an
older version was live on Xiaomi, the poll would return APPROVED and
incorrectly mark the new submission as 已上线(直接上传).

Changes:
- Remove post-failure live check from executeSinglePlan and sequential
  failure handler — submission failures are just marked REJECTED
- Restrict the REJECTED-store poll to HUAWEI only, since it is the only
  store where pollStoreSingleReviewState is version-specific
  (compares onShelfVersionCode against v.getVersionCode())
- Log full VIVO data response to capture versionCode field name for
  future version-specific detection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 17:52:53 +08:00
XuqmGroup
8d46d21726 fix: store resubmission, Xiaomi curl, and live-on-store detection
- Dockerfile: add curl to Alpine runtime image (required by Xiaomi/Vivo
  APK upload which uses ProcessBuilder curl for HTTP/1.1 multipart)
- AppStoreService: mark previously-APPROVED stores as WITHDRAWN on
  resubmission so executeSubmitAsync calls the store cancel API first;
  guard updateStoreReview from stale APPROVED webhooks on PENDING/WITHDRAWN
  stores; add updateStoreReviewLive() to record pre-existing live versions
  with liveOnStore/preExisting metadata
- StoreSubmissionService: call cancelAtStore for WITHDRAWN stores before
  resubmitting; expand poll query to include REJECTED stores and call
  updateStoreReviewLive when a REJECTED store is found live; after any
  submission failure check if the store already has the version live
  (catches Huawei/Vivo pre-existing direct uploads at submission time)
- AppVersionRepository: add findAllWithUnderReviewOrRejectedStores query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 17:30:26 +08:00
XuqmGroup
8de0338b93 fix: withdraw previously-approved store reviews before re-submitting same version
When re-submitting a version to stores where the previous review was APPROVED:

1. markSubmitted now sets those stores to WITHDRAWN (not PENDING), preserving
   the old batchId/submittedAt for traceability. This signals to executeSubmitAsync
   that the store cancel API must be called before a new submission is attempted.

2. executeSubmitAsync detects the WITHDRAWN state and calls cancelAtStore first,
   then falls through to the normal submission path. This revokes the old approval
   on the store's side so no stale webhook or poll cycle can fire APPROVED for the
   old review after re-submission.

3. updateStoreReview now rejects APPROVED transitions from PENDING or WITHDRAWN
   states (stale webhook guard). A valid approval can only arrive after the store
   has seen the new submission (i.e. current state must be SUBMITTING or UNDER_REVIEW).
   This prevents autoPublishAfterReview from triggering before the new review cycle.

Operation log includes `approvedWithdrawn` list when any store was withdrawn on re-submit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 17:09:31 +08:00
XuqmGroup
4e54737e72 feat: webhook shows app name; auto-withdraw superseded approved stores
- Webhook notification body shows app display name (resolved from
  tenant-service via internal API with in-memory cache) instead of appKey
- When re-uploading a package with the same versionCode, automatically
  withdraw APPROVED store entries from the older entity before submitting
  the new entity, preventing duplicate active submissions
- tenant-service /internal/sdk/apps/{appKey}/platform-info now includes
  the app 'name' field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 13:31:31 +08:00
XuqmGroup
39367a57e1 fix MI poll: don't mistake old published version as new version approved
The MI /devupload/dev/query API returns the currently-published app's status,
not the pending submission. appStatus=3 means the previous version is still
online, not that the new submission was accepted. Use updateVersion=true as
the approval signal; default updateVersion to false to avoid false positives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 13:04:18 +08:00
XuqmGroup
81f04ee432 fix MI poll: log full response, fix synchroResult=0 mapped to REJECTED not UNDER_REVIEW
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:39:06 +08:00
XuqmGroup
f7dbce7268 fix HONOR poll endpoint and status mapping; improve all store polling reliability
- HONOR: use get-app-current-release endpoint (correct), auditResult field (0=review,1=approved,2=rejected)
- HONOR: assertHonorSuccess now accepts both "0" and "0000" success codes
- OPPO: add integer status mapping (111=approved, 444=rejected) from reference impl
- All stores: add full response body logging for diagnosing poll issues

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:15:19 +08:00
XuqmGroup
8dea96ef5e fix: skip already-reviewing stores on resubmit; clean up orphaned SUBMITTING states
- StoreSubmissionService: skip UNDER_REVIEW/APPROVED stores in preflight loop to prevent duplicate submissions
- StoreSubmissionService: post-batch sweep marks any still-SUBMITTING stores in same batch as REJECTED
- StoreSubmissionService: @EventListener(ApplicationReadyEvent) clears orphaned SUBMITTING states on startup
- AppVersionRepository: add findAllWithSubmittingStores() native query for startup sweep

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:58:27 +08:00
XuqmGroup
4136cd57b6 feat: add app transfer API, parallel store upload, DingTalk/WeCom/Feishu webhook formats
- OpsController/OpsService: POST /api/ops/apps/{appKey}/transfer to move app between tenants
- StoreSubmissionService: read parallelStoreUpload from publish config; conditional parallel vs sequential submission
- AppStoreService: support DINGTALK/WECOM/FEISHU/CUSTOM notify formats in sendWebhook()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 15:34:59 +08:00
XuqmGroup
8443af4818 fix: add --http1.1 to MI curl upload to prevent HTTP/2 stream error (exit 92) 2026-05-16 13:28:50 +08:00
XuqmGroup
e7dbdc2ef3 fix(update): use curl for Xiaomi APK upload to bypass server-side body timeout
RestTemplate drops large multipart payloads on the MI API server; switching to
ProcessBuilder curl with Expect:100-continue headers and a 130-minute timeout resolves
upload failures for large APKs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 02:24:04 +08:00
XuqmGroup
0ed09a8229 一大波改动 2026-05-15 22:11:03 +08:00
XuqmGroup
b24e3669cb 一大波改动 2026-05-15 16:47:22 +08:00
XuqmGroup
fb8a9d453d fix(update): 修复华为上传URL响应格式 urlInfo 单对象处理
华为实际返回格式为 urlInfo (单对象) 而非 urlList (列表),
代码需同时支持两种格式:
- urlList: 列表形式(旧版API)
- urlInfo: 单对象形式(当前API,含 url/objectId/headers/method)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:16:19 +08:00
XuqmGroup
ac35f7e2fb fix(update): 修复华为上传URL NPE及提交批次超时限制
- submitToHuawei: urlList 字段做防御性处理,找不到时降级到 data,
  同时输出实际响应内容方便排查
- executeSubmitAsync: allOf.join() 改为 get(20, MINUTES),
  防止大文件上传卡住时批次线程永久阻塞

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:58:10 +08:00
XuqmGroup
1a18925034 feat: 厂商应用商店提交功能完善及push用户管理
update-service:
- 修复华为 appId 解析 NPE(支持直接从响应体顶层读取 value 字段)
- 修复 OPPO 更新描述不足5字符时自动补空格
- 修复 VIVO 签名中文字符需 URL 编码
- 修复 RestTemplate 无超时(30s连接/5min读取)
- AppVersionEntity 添加 grayCallbackUrl 字段

tenant-service:
- FeatureServiceController switch 添加 FILE 分支(修复编译错误)
- FeatureServiceManager 添加 buildFileConfig 方法
- AppController 添加应用用户列表代理端点
- AppUserClient 新增 IM/Push 用户列表客户端

push-service:
- 新增 PushUserEntity/PushUserRepository/PushAccountService
- 新增 PushAuthController(内部鉴权接口)
- PushManagementController 添加用户管理接口
- PushAppSecretClient 对接 tenant-service 鉴权

im-service:
- ImAccountRepository/ImAccountService 添加用户搜索接口
- ImAdminController 添加管理端用户列表
- InternalPresenceController 完善在线状态接口

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:40:35 +08:00
XuqmGroup
71929fef67 docs(deploy): 添加完整的部署文档和配置示例
- 新增 compose.production.yaml 和 compose.production.server.yaml 部署配置
- 添加 nginx.dev.xuqinmin.com.conf 和 nginx.sentry.xuqinmin.com.conf 反向代理配置
- 创建详细的部署指南文档 deploy/README.md,涵盖架构设计和部署步骤
- 添加前端访问文档 web/README.md,包含线上地址和接口说明
- 补充平台文档总览 README.md,整合各模块文档入口
- 配置多服务容器化部署,包括 tenant-service、im-service、push-service 等
- 设置外部数据库和 Redis 连接配置,确保服务间正确通信
- 配置 WebSocket 和 API 路由转发规则,支持实时通信和版本更新服务
2026-05-09 14:53:42 +08:00
XuqmGroup
cf2013a52d feat(im): 添加平台事件通知功能支持应用审核状态实时更新
- 新增 ImPlatformEventController 提供令牌获取接口
- 新增 InternalImPlatformEventController 处理内部通知请求
- 实现 ImPlatformEventService 核心服务逻辑包括令牌签发和消息推送
- 添加 StoreReviewImNotifier 在更新服务中触发审核状态变更通知
- 在前端平台中集成实时审核状态更新功能
- 配置各项目环境版本管理文件 (.java-version, .nvmrc)
- 更新 Docker 忽略文件和 Maven 配置以优化构建流程
2026-05-08 18:32:46 +08:00
XuqmGroup
dc1ada94ea docs(deploy): 添加部署文档和安全设计规范
- 新增 XuqmGroup 部署文档,包含部署方案、架构建议和部署步骤
- 添加安全设计规范,涵盖密码安全、AppSecret验证和服务端API认证
- 补充平台REST API规范,定义Server-to-Server调用接口和错误码
- 创建Java IM服务端SDK计划文档,规划Maven包发布和接口实现
2026-05-08 18:32:00 +08:00
XuqmGroup
0385b2010a feat(update): 添加应用更新检查功能支持用户ID参数
- 在UpdateApi接口中新增可选的userId查询参数
- 新增UpdateSDK对象用于统一管理应用更新逻辑
- 实现应用版本检查、下载安装和APK文件处理功能
- 添加下载URL规范化处理逻辑
- 在Flutter SDK中新增update模块实现跨平台更新功能
- 在iOS SDK中新增UpdateSDK类提供应用更新检查接口
- 支持Android和iOS平台的应用商店跳转功能
- 添加React Native SDK的更新检查和插件注册功能
- 实现RN Bundle的检查、下载和缓存机制
2026-05-08 12:00:33 +08:00
XuqmGroup
77dafd76bf chore: sync local changes 2026-05-07 19:39:42 +08:00
XuqmGroup
a8293bb4c4 feat: Java SDK baseUrl 内置默认值;fix: update-service 大文件APK解析、file-service hash去重 2026-05-03 11:00:12 +08:00
XuqmGroup
d2dea0c332 feat(android-sdk): 添加完整的IM客户端SDK实现
- 实现了Android SDK的完整IM功能接口,包括消息、群组、好友、会话等核心功能
- 添加了消息收发、历史记录、撤回编辑等完整的消息操作能力
- 实现了群组管理功能,包括创建、成员管理、权限设置等操作
- 添加了好友关系链管理,支持添加、删除、分组等操作
- 实现了会话管理功能,包括置顶、免打扰、已读状态等
- 添加了黑名单、资料管理、搜索等辅助功能
- 补齐了批量操作接口,提升客户端操作效率
- 实现了WebSocket连接管理和事件监听机制
- 添加了离线消息同步和状态管理功能
2026-05-02 22:57:55 +08:00
XuqmGroup
f6c06db04b feat(deploy): 添加生产环境部署配置和联调环境切换功能
- 新增 .env.production.example 配置文件,包含所有微服务的数据库和Redis配置
- 添加 compose.production.yaml Docker Compose部署文件,定义web和各服务容器
- 实现Android SDK环境切换功能,支持外部服务和本地联调模式切换
- 添加推送注册状态管理和接收开关设置界面
- 集成演示服务的应用密钥客户端和认证服务实现
- 完善文档说明各SDK模块的集成和使用方法
2026-04-30 11:47:01 +08:00
XuqmGroup
32b0e49e61 docs(deploy): 添加生产环境部署配置示例和部署文档
- 新增 .env.production.example 环境变量配置模板
- 添加 compose.production.yaml Docker Compose 部署配置
- 创建 web.Dockerfile 前端构建部署文件
- 编写详细的 README.md 部署文档,涵盖架构、配置、步骤等内容
- 添加离线推送架构设计文档
- 更新 IM 多平台进度跟踪文档
2026-04-30 09:49:05 +08:00
XuqmGroup
93311f1739 feat(sdk): 添加鸿蒙SDK核心功能模块
- 实现SDKContext用于配置管理和数据持久化存储
- 定义完整的类型系统包括消息、用户、群组等接口
- 集成更新SDK支持原生应用和RN热更新检查
- 提供统一的XuqmSDK入口类和模块导出
- 编写详细的开发文档和使用示例
2026-04-29 19:08:13 +08:00
XuqmGroup
f5a1eb4470 docs(sdk): 添加 React Native SDK 文档和 Android/HarmonyOS 发版脚本
- 新增 XuqmGroup React Native SDK 使用文档,包含安装、初始化、HTTP客户端、IM模块、推送模块、版本管理等功能说明
- 添加 Android Gradle 发版任务脚本,支持构建发布 APK 并上传到更新服务
- 添加 HarmonyOS hvigorw 发版任务脚本,支持 HAP 包构建和上传功能
- 实现多平台版本检查、自动重连、灰度发布等发版流程自动化
- 集成商店提交、定时发布、Webhook 回调等发布后处理功能
2026-04-29 17:35:52 +08:00
XuqmGroup
c3968e808d docs(sdk): 添加 Android SDK 文档和 API 设计规范
- 新增 Android SDK 使用文档,包含模块结构、集成方式和快速开始指南
- 添加 SDK API 重设计规范,统一初始化和登录接口设计
- 补充安全设计规范,完善 UserSig 鉴权和敏感数据处理方案
- 创建平台 REST API 规范,定义服务端到服务端的调用接口
- 添加离线推送架构设计,集成各大厂商推送服务与 IM 联动方案
2026-04-29 15:46:40 +08:00
XuqmGroup
d7f5fd02c2 docs(server): 添加服务器信息记录和联调接口文档
- 创建信息记录文档,包含项目管理要求、产物范围、Git仓库、制品仓库信息
- 添加服务器部署信息,包括应用服务器、MySQL/Redis服务器、Jenkins服务配置
- 记录邮件服务、DNS/HTTPS证书配置及安全备注
- 创建API联调文档,包含线上入口、ID约定、初始化管理员账号信息
- 添加统一响应格式、常见错误码、鉴权规则说明
- 提供核心接口清单,涵盖tenant-service、im-service、push-service等服务
- 补充curl示例,包含运营平台登录、IM登录、会话管理等操作示例
- 实现会话控制器,支持置顶、免打扰、标记已读、草稿等功能
- 添加全局异常处理器,统一处理业务异常和参数校验错误
- 创建IM管理控制器,提供用户管理、好友请求、黑名单等管理功能
2026-04-29 12:33:25 +08:00
XuqmGroup
eae18723a5 feat(update): add app store distribution — store config, server-side submission, scheduled publish, webhook
feat(im): expand IM API with friends, groups, admin ops, operation logging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 00:34:17 +08:00
XuqmGroup
73060518f0 feat(im): 添加即时通讯SDK核心功能
- 实现IM API接口定义,包括消息、群组、好友、黑名单等功能
- 定义IM消息相关数据模型,包含聊天类型、消息类型、用户资料等
- 实现ImSDK单例类,提供登录、消息发送、群组管理、好友管理等核心功能
- 添加WebSocket连接管理,支持自动重连机制
- 实现历史消息查询、群组操作、用户资料管理等API调用
- 添加会话状态管理,支持置顶、静音、草稿等功能
- 集成文件上传结果,支持多媒体消息发送
- 实现连接状态监听和事件回调机制
2026-04-28 21:05:06 +08:00