卡密-导入-激活-鉴权 完整流程文档
一、整体流程概览
二、各环节详解
① 卡密导入
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端 |
| 触发方式 |
管理员调用 POST /openapi/daycard/pool/import |
| 代码位置 |
DayCardPoolServiceImpl.importCards() |
| 输入 |
橘视厅真实激活码(cardCode),如 ASXXXXXX |
| 处理 |
为每个cardCode自动生成 thirdCardNo(随机数字+字母串),写入 day_card_pool 表,status=UNUSED |
| 产出 |
day_card_pool 表新增记录:cardCode + thirdCardNo + status=UNUSED |
| 关键 |
cardCode必须是橘视厅平台真实有效的激活码,否则后续激活会失败 |
② 配置橘视厅平台参数
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端数据库 |
| 存储位置 |
sys_config 表,param_key=JST_PLATFORM_CONFIG |
| 配置内容 |
jushitingBaseUrl / jushitingAccesser / jushitingBusinessLine / jushitingLoginRsaPublicKey / jushitingActivateSignKey / vipQueryBaseUrl |
| 来源 |
从生产环境 as-partner-backend 的 sys_config 表复制 |
| 作用 |
后端调用橘视厅API时的鉴权参数 |
③ 设备注册
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端 + MediaApp |
| 触发方式 |
管理后台 POST /manage/device/save 或自动创建 |
| 代码位置 |
DeviceController.save() → DeviceServiceImpl |
| 产出 |
device 表新增记录,deviceId=1(当前测试设备) |
| App引用 |
DayCardConfig.DEVICE_ID = 1L(硬编码) |
④ 点击播放
| 项目 |
内容 |
| 执行位置 |
MediaApp(Android端) |
| 代码位置 |
DetailActivity.btnPlay.onClick → startPaymentFlow() |
| 动作 |
调用天卡后端 GET /openapi/media/play-permission/{mediaId}?deviceId=1 |
| 目的 |
检查设备是否已有播放权限(是否已支付过且未过期) |
⑤ 创建订单
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端 |
| 触发方式 |
App调用 POST /openapi/daycard/create |
| 代码位置 |
DayCardOrderServiceImpl.createOrder() |
| 处理 |
1. Redis防重锁 2. 从 day_card_pool 中 SELECT...FOR UPDATE SKIP LOCKED 抢一张UNUSED的卡 3. 卡状态 UNUSED→RESERVED 4. 创建订单 status=CREATED |
| 产出 |
day_card_order 表新增订单 + 卡状态变为RESERVED |
⑥ 支付
| 项目 |
内容 |
| 执行位置 |
MediaApp + as-daycard-openapi 后端 |
| 测试方式 |
App调用 POST /openapi/payment/mock-pay/{orderNo} |
| 生产方式 |
微信扫码支付 POST /openapi/payment/native/create |
| 代码位置 |
DayCardOrderServiceImpl.mockPay() 或微信支付回调 |
⑦ 支付回调触发异步激活
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端 |
| 代码位置 |
DayCardOrderServiceImpl.payCallback() |
| 处理 |
1. 订单 status→PAID 2. 卡状态 RESERVED→USED 3. 设置初始expire_at(24h兜底) 4. 触发 @Async asyncActivateCard(order) |
| 关键 |
异步激活不阻塞支付回调返回,App此时已收到支付成功 |
⑧ 橘视厅API激活卡密(3步HTTP调用)
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端(异步线程池 thirdPartyActivateExecutor) |
| 代码位置 |
DayCardOrderServiceImpl.asyncActivateCard() → JushitingApiServiceImpl |
Step 1: 免密登录获取Token
Step 2: 卡密激活
Step 3: 查询VIP到期时间(仅Step2未返回expireTime时)
激活完成后更新数据库
⑨ 查询权益获取thirdCardNo
| 项目 |
内容 |
| 执行位置 |
as-daycard-openapi 后端 |
| 触发方式 |
App调用 GET /openapi/daycard/benefits/{deviceId} |
| 代码位置 |
DayCardOrderController.benefits() → DayCardOrderServiceImpl.getDeviceBenefits() |
| SQL |
SELECT...FROM day_card_pool WHERE device_id=? AND status='USED' AND expire_at > NOW() ORDER BY used_at DESC LIMIT 1 |
| 返回 |
{ hasBenefits: true, thirdCardNo: "xxx", cardCode: "xxx", expireAt: "xxx" } |
⑩ SDK初始化
| 项目 |
内容 |
| 执行位置 |
MediaApp(Android端) |
| 代码位置 |
DetailActivity.fetchVideoUrlAndPlay() → JetsenxSdkUtil.init(ctx, thirdCardNo, ...) |
| 参数 |
uid=thirdCardNo, utype=2(第三方ID), agcode, tenant, secret, accesser |
| SDK内部 |
JetsenxSdk向捷成平台注册用户身份,获取memberCode |
| 关键 |
此时橘视厅平台已有该thirdCardNo的订购关系(⑧步已建立) |
⑪ 获取视频地址
| 项目 |
内容 |
| 执行位置 |
MediaApp(Android端)→ JetsenxSdk → 橘视厅平台 |
| 代码位置 |
JetsenxSdkUtil.getAllVideoUrl() |
| 流程 |
1. getAllAssetPrices() 获取productCode 2. 根据parentContentType判断免费/付费 3. getVideoUrls() 或 getFreeVideoUrls() |
| 返回 |
VideoInfo[]: videoUrl(1080p/720p), format, movieCode |
| 前提 |
SDK已用有效thirdCardNo初始化 + 平台有订购关系 |
⑫ 播放
| 项目 |
内容 |
| 执行位置 |
MediaApp(Android端) |
| 代码位置 |
VideoPlayerActivity → ExoPlayer |
| 动作 |
用获取到的视频URL播放 |
三、当前阻滞点
四、打通链路的前置条件
- 从生产环境获取真实的橘视厅卡密(cardCode)
- 从生产环境
sys_config 表复制 JST_PLATFORM_CONFIG 配置值
- 清除当前mock卡密,用真实卡密重新导入天卡池
五、关键代码文件索引
MediaApp(Android端)
| 文件 |
作用 |
MediaApp/.../ui/DetailActivity.kt |
详情页,播放流程入口 |
MediaApp/.../sdk/JetsenxSdkUtil.kt |
JetsenxSdk封装,SDK初始化+获取视频地址 |
MediaApp/.../ui/VideoPlayerActivity.kt |
ExoPlayer播放器 |
MediaApp/.../network/DayCardApiService.kt |
天卡API接口定义 |
MediaApp/.../viewmodel/PaymentViewModel.kt |
天卡支付流程 |
MediaApp/.../config/DayCardConfig.kt |
天卡配置(设备ID、金额等) |
MediaApp/.../config/ApiConfig.kt |
媒资API配置 |
as-daycard-openapi(本项目后端)
| 文件 |
作用 |
.../daycard/controller/DayCardOrderController.java |
天卡订单Controller(创建/状态/权益) |
.../daycard/service/impl/DayCardOrderServiceImpl.java |
订单核心逻辑(createOrder/payCallback/asyncActivateCard/getDeviceBenefits) |
.../daycard/service/impl/DayCardPoolServiceImpl.java |
天卡池管理(导入/抢卡) |
.../jst/service/impl/JushitingApiServiceImpl.java |
橘视厅API调用(getToken/activateCard/queryVipExpireTime) |
.../jst/service/JstActivateCardResult.java |
卡密激活结果 |
.../device/controller/DeviceController.java |
设备管理 |
.../media/controller/MediaController.java |
媒资/播放权限 |
生产环境参考代码
| 文件 |
作用 |
app/.../request/AsApiRequester.java |
生产环境AS接口(init/check/checkBenefits/activate) |
app/.../utils/JetsenxSdkUtil.java |
生产环境SDK工具类 |
app/.../video/VideoDetailActivity.java |
生产环境详情页(完整播放流程) |
app/.../MainActivity.java |
生产环境主页(SDK初始化入口) |
app/.../config/AppConfiguration.java |
生产环境配置(AS基础地址) |