You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Rodger-Wang 2cf260eb05 服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放) 3 weeks ago
..
README.md 服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放) 3 weeks ago
build.sh 服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放) 3 weeks ago
index.html 服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放) 3 weeks ago
index.template.html 服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放) 3 weeks ago

README.md

下载落地页(dl.ymaikj.com)

一个纯静态页,托管在阿里云 OSS 上,不占服务器、不经 NPM。 安装包也放同一个桶里,页面按 UA 决定跳商店还是给 APK 直链。

deploy/dl/
├── index.template.html   ← 源文件,改页面改这个
├── build.sh              ← 把 App 图标内联进去,生成 index.html
└── index.html            ← 生成物,**上传的是它**(已入库,方便直接传)

版本号、更新日志、各商店链接都不在页面里维护,实时取自管理后台(见下文「三」)。 图标取自 apps/client/assets/images/app_icon.png,与 App 用的是同一份素材。


一、为什么放 OSS 而不是放业务服务器

下载页一般要挂 APK 直链。微信、各家浏览器对「发 apk 的域名」判定很粗暴, 一旦被拦截或标记为风险,同域名上的接口请求也会一起遭殃。所以它必须与 ym.ymaikj.com(业务网关)分开。

放 OSS 还有两个顺带好处:页面和安装包同源(没有跨域、没有防盗链问题), 以及不占业务机的带宽——一个版本几十 MB,几千次下载就是几百 GB。


二、部署步骤(首次)

✅ 2026-09-23:ymai-dl 桶、dl.ymaikj.com 域名与证书均已建好并实测可用 (证书有效期至 2027-03-23,404 路由正确,与 ym.ymaikj.com 的跨域也已实测通过)。 下面三步留档,重建时照做。

1. 准备存储桶

建议新建一个专用桶,例如 ymai-dl(上海,与 ymaioss 同地域):

  • 读写权限:公共读(安装包本来就要公开下载)
  • 不要复用 ymaioss。那个桶里是用户录音,把公开分发的东西混进去会让 权限、生命周期规则、流量账单都分不清谁是谁。

想省事复用 ymaioss 也能跑通,但页面要放在 EAIMAR/dist/index.html 这种子路径下,且 oss.ymaikj.com 已经绑给它了,你还得再绑一个 dl.ymaikj.com。 收益不大,不推荐。

2. 开启静态网站托管

桶 → 数据管理 → 静态页面:

项 填
默认首页 index.html
默认 404 页 index.html(可选,让任何路径都落到下载页)
子目录首页 开启

不开这一项,访问 https://dl.ymaikj.com/ 会返回桶的 XML 列表或 403,而不是页面。

3. 绑定域名 dl.ymaikj.com

桶 → 传输管理 → 域名管理 → 绑定域名:

  1. 填 dl.ymaikj.com,勾选「自动添加 CNAME 记录」(域名在同一个阿里云账号下时可用; 否则去 DNS 那边手工加一条 CNAME 指向桶的外网 Endpoint)
  2. ⚠️ 中国大陆地域的桶绑自定义域名,域名必须已备案。ymaikj.com 应该已备案, 确认一下子域名是否需要单独报备。
  3. 证书:同一页的「证书托管」里传一张 dl.ymaikj.com 的证书。 阿里云「数字证书管理服务」可以申请免费的 DV 证书,签完直接在这里选。 不配证书 = 只能 http 访问,微信和现在的浏览器都会拦。

4. 上传页面与安装包

用 ossutil(推荐,能重复执行):

# 首次配置:ossutil config -e oss-cn-shanghai.aliyuncs.com -i <AK> -k <SK>

# 页面(放桶根)
ossutil cp deploy/dl/index.html oss://ymai-dl/index.html \
  --meta "Content-Type:text/html; charset=utf-8#Cache-Control:no-cache, must-revalidate"

# 安装包
ossutil cp eaimar-release-1.0.2-20260923.apk \
  oss://ymai-dl/android/EAIMAR/eaimar-release-1.0.2-20260923.apk \
  --meta "Content-Type:application/vnd.android.package-archive#Content-Disposition:attachment"

也可以直接在 OSS 控制台点「上传文件」,然后在文件的「设置 HTTP 头」里改这两项。

⚠️ 页面必须设 Cache-Control: no-cache。默认缓存会让你改了页面之后老用户 还拿着旧版本,而这种问题根本没人会来报。

⚠️ APK 建议设 Content-Disposition: attachment。不设的话部分浏览器会尝试 「预览」这个文件,表现为点了没反应或者打开一堆乱码。


三、与管理后台联动(版本号、商店链接、更新日志)

页面打开时会调一次 POST https://ym.ymaikj.com/api/home/user_getchannelapps (该接口在网关白名单里,未登录可调),把后台配的东西取回来:

页面上的 来自后台哪里 落到哪个字段
版本号 服务配置 → 版本与分发 → 发版配置 → 线上版本 app_release.version
「本次更新」 版本与分发 → 发版配置 → 更新日志 app_release.changelog
App Store 链接 版本与分发 → 渠道分发 → 全球-苹果(101) 的下载地址 channel_app.address
各安卓商店链接 渠道分发 → 华为(1) / 小米(2) / OPPO(3) / VIVO(4) / 荣耀(5) 同上
APK 直链 渠道分发 → 官方渠道(100) 的下载地址 同上

后台改完,页面刷新即生效,不需要重新上传。

渠道地址留空时后端会自动回退到「发版配置」里的默认下载地址(AppRelease.DownloadAddress), 所以只想维护一套地址的话,只填那一处就够——填成 https://dl.ymaikj.com 即可兜住所有渠道。

⚠️ APK 直链约定挂在「官方渠道(100)」下。这是本页面单方面的约定,后台界面上没有任何提示, 所以要么按这个约定配,要么去改 index.template.html 里 CFG.channels 的映射。

⚠️ 接口打不通时(断网 / 网关挂了 / 跨域被拦)页面用 CFG.fallback 的兜底值渲染,不报错—— 用户是来下载的,给他看一个报错页没有任何用。代价是兜底值会比后台旧, 所以别把 fallback 当配置入口去维护。


四、发版时要做什么

  1. 打包,产物名按仓库约定:eaimar-release-<版本号>-<时间>.apk (不要留 app-release.apk)
  2. 传安装包 —— 两条路任选:
    • 后台传(推荐):服务配置 → 版本与分发 → 「默认下载地址」旁边的 上传 APK 按钮。 传到分发桶的 android/<应用>/ 目录(按应用分目录,先选应用才能传),带进度条, 传完**自动写进「渠道分发 → 官方渠道(100)」**的下载地址,不动「默认下载地址」那一格。
    • 手工传:oss://ymai-dl/android/,见上文「二、4」
  3. 到后台「版本与分发」改线上版本与更新日志(用「上传 APK」传的话,官方渠道地址已自动写好)

⚠️ 后台上传的前置:分发桶要配跨域(CORS)

浏览器是直传到 OSS(预签名 PUT 打的是 ymai-dl.oss-cn-shanghai.aliyuncs.com, 不是 dl.ymaikj.com),所以桶上必须有 CORS 规则,否则浏览器直接拦掉、 XHR 只报一句没有细节的「网络错误」。

OSS 控制台 → ymai-dl → 权限管理 → 跨域设置 → 创建规则:

项 填
来源 https://console.ymaikj.com
https://console-dev.ymaikj.com
允许 Methods PUT(顺带勾 GET、HEAD)
允许 Headers content-type(或 *)

对照:主桶 ymaioss 早就配好了(所以产品固件上传一直能用), 2026-09-23 实测 ymai-dl 的预检返回 403,需要照着补一条。

页面本身不用动。只有改页面文案/样式,或者 App 图标换了,才需要:

cd deploy/dl && ./build.sh      # 重新内联图标,生成 index.html
# 再把 index.html 传一次

五、页面行为

环境 行为
iOS 跳 App Store
Android(认出品牌) 主按钮跳对应商店,副按钮给 APK 直链
Android(认不出品牌) 直接给 APK 直链
桌面浏览器 两个按钮都给,提示用手机打开
微信 / QQ 内置浏览器 一进页面就弹遮罩,引导「右上角 ··· → 在浏览器中打开」

⚠️ 微信那一层不是可选项。微信会拦截 apk 下载而且静默失败——点了什么都不发生, 用户只会认为这个页面坏了。所以是进页面就提示,而不是等他点了才说。

品牌判断的口径与 App 内 getAndroidStoreInfoByBrand 一致:判的是手机品牌, 不是从哪家商店下载的(国内五家共用一个包)。认不出就走 APK,这个兜底方向是安全的。

商店地址与 APK 地址相同时(后台该渠道没单独配、回退到了默认地址)只显示一个按钮—— 两个一模一样的按钮只会让人犹豫点哪个。


六、待办

首选是去后台「渠道分发」配(见上文「三」),配了就不用动代码。

index.template.html 里 CFG.fallback 的商店链接目前是占位地址 https://emai.ymaikj.com/1223,搜 TODO(store-links) 能定位,它只在接口打不通时才会被用到。 各商店上架后可以顺手更新:

key 从哪拿
appStore App Store Connect →「App 信息 → Apple ID」,一串纯数字,拼成 https://apps.apple.com/cn/app/id<数字>
huawei / honor 各自开发者后台的应用详情页链接,形如 https://appgallery.huawei.com/app/C<数字>
xiaomi https://app.mi.com/details?id=com.yimai.eaimar
oppo / vivo 各自开发者后台的详情页链接

⚠️ 包名是 com.yimai.eaimar(iOS bundle id 同名)。


七、注意

  • 别在这个页面做 Universal Link 唤起:UL 域名是 yimai.games,不是 ymaikj.com, 在 ymaikj 的任何子域上配都不会生效。
  • 桶是公共读,APK 谁都能下——这对安装包是对的。但别把别的东西往这个桶里放。
  • 下载量上来之后再在 OSS 前面挂 CDN,页面不用改(域名不变)。
  • 图标在页面里只内联一份(<img>),favicon 与 apple-touch-icon 由 JS 复用同一个 data URI。在 <head> 里再写两个 href 会把几十 KB 的 base64 存三份,页面体积直接翻三倍。