M0: contracts 契约类型 SSOT(T-M0-04)
落地《契约规范》§8/§9/§12,全工程唯一来源: - InboundHandlers 枚举:45 入站 handler 名,原样拼写(finsh/canclevibrator/opensaoma 等) - OutboundHandlers 枚举:21 出站 handler 名,含命名陷阱(getphoneinfo≠getphoneInfo、 getBattery≠getbattery、backgameData-末尾连字符) - PayloadType:入站/出站 raw|json 标注表 + 入站同步返回类型 + 查询函数 - DTO interface ×17(§12 字段同名同义):Sharetype/Maplocation/PhoneInfo/savephoto/ videoinfo/Othervideoinfo/GamePay/PayState/ShareLogin/ShareSuccess 等 - Result<T> + Errors(ErrorKind/LocationErrorCode/AppError) - 经 entry 临时 smoke 全量引用,CompileArkTS 编译通过 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
424c5f4d94
commit
26299c06ce
+20
-3
@@ -1,3 +1,20 @@
|
|||||||
// contracts HAR —— 契约类型 SSOT(导出入口 SSOT)
|
// contracts HAR —— 契约类型 SSOT(全工程唯一来源)
|
||||||
// 各子模块实现完成后在此统一 export。占位常量确保 HAR 可编译。
|
// 落地《TSGame_原生与H5接口契约总规范》§8/§9/§12 的 handler 名、DTO、错误与返回类型。
|
||||||
export const contracts_MODULE_VERSION: string = '1.0.0';
|
|
||||||
|
// —— Handler 名(原样拼写,不可纠正)——
|
||||||
|
export { InboundHandlers } from './src/main/ets/handlers/InboundHandlers';
|
||||||
|
export { OutboundHandlers } from './src/main/ets/handlers/OutboundHandlers';
|
||||||
|
|
||||||
|
// —— 载荷类型标注(raw / json)——
|
||||||
|
export { PayloadType, InboundPayload, InboundSyncReturn, OutboundPayload,
|
||||||
|
inboundPayloadType, outboundPayloadType } from './src/main/ets/handlers/PayloadType';
|
||||||
|
|
||||||
|
// —— 数据结构 DTO(§12,字段同名同义)——
|
||||||
|
export { SharetypeBean, MaplocationInfo, PhoneInfoBean, SavephotoURLBean,
|
||||||
|
VideoinfoBean, OthervideoinfoBean, GamePayReq, PayStateResp, ShareLoginResp,
|
||||||
|
ShareSuccessResp, OpenUrlTitleDataReq, OpenApplyDownloadReq, SwitchOverGameReq,
|
||||||
|
MediaTypeAudioReq, SrcIsLoopReq, GetAudioUrlResp, WifiLevelResp } from './src/main/ets/dto/Dtos';
|
||||||
|
|
||||||
|
// —— 错误与统一返回 ——
|
||||||
|
export { LocationErrorCode, ErrorKind, AppError, makeError } from './src/main/ets/result/Errors';
|
||||||
|
export { Result } from './src/main/ets/result/Result';
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/**
|
||||||
|
* 数据结构汇总(《契约规范》§12)。
|
||||||
|
*
|
||||||
|
* 🔴 字段名严格对应原 Android 代码,序列化时必须【同名同语义】,不可改名/改大小写。
|
||||||
|
* 多数字段为 String(H5 历史习惯),数值型按契约标注。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 分享入参(friendsSharetypeUrlToptitleDescript 的 data),全 String。§12 sharetypeBean */
|
||||||
|
export interface SharetypeBean {
|
||||||
|
/** "1" 好友(弹面板) / "2" 朋友圈(直发微信) */
|
||||||
|
sharefriend: string;
|
||||||
|
/** "1" 网页/文本 / "2" Canvas截图 / "3" 图片链接 / "4" 视频(抖音) */
|
||||||
|
type: string;
|
||||||
|
/** 分享子类型 */
|
||||||
|
sharetype: string;
|
||||||
|
/** 分享链接 或 图片地址 */
|
||||||
|
webpageUrl: string;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 定位回传(getlocationinfo 的 data)。§12 MaplocationInfo */
|
||||||
|
export interface MaplocationInfo {
|
||||||
|
latitude: number; // double
|
||||||
|
longitude: number; // double
|
||||||
|
address: string;
|
||||||
|
country: string;
|
||||||
|
province: string;
|
||||||
|
city: string;
|
||||||
|
district: string;
|
||||||
|
street: string;
|
||||||
|
cityCode: string;
|
||||||
|
streetNum: string;
|
||||||
|
adCode: string;
|
||||||
|
aoiName: string;
|
||||||
|
accuracy: number; // float
|
||||||
|
locationType: number; // int
|
||||||
|
/** 0 成功 / -1 未就绪 / -2 权限拒绝 / 其他=底层错误码 */
|
||||||
|
errorCode: number;
|
||||||
|
errorMsg: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 手机信息回传(getphoneinfo 出站 data),全 String。§12 phoneInfoBean */
|
||||||
|
export interface PhoneInfoBean {
|
||||||
|
PhoneVersion: string;
|
||||||
|
PhoneAdresseMAC: string;
|
||||||
|
PhoneModel: string;
|
||||||
|
PhoneDeviceBrand: string;
|
||||||
|
PhoneProvidersName: string;
|
||||||
|
PhoneIMEI: string;
|
||||||
|
PhoneIMSI: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 图片下载数组元素(getphoto 回传数组)。§12 savephotoURLBean */
|
||||||
|
export interface SavephotoURLBean {
|
||||||
|
pid: string;
|
||||||
|
photourl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 加入/创建房间入参(createRoom 的 data),全 String。§12 videoinfobean */
|
||||||
|
export interface VideoinfoBean {
|
||||||
|
playerid: string;
|
||||||
|
roomid: string;
|
||||||
|
agentid: string;
|
||||||
|
gameid: string;
|
||||||
|
left: string;
|
||||||
|
top: string;
|
||||||
|
pmw: string;
|
||||||
|
pmh: string;
|
||||||
|
width: string;
|
||||||
|
height: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 请求远端视频窗口入参(getVideoinfo 入站的 data)。§12 Othervideoinfo */
|
||||||
|
export interface OthervideoinfoBean {
|
||||||
|
playerid: string;
|
||||||
|
left: string;
|
||||||
|
top: string;
|
||||||
|
width: string;
|
||||||
|
height: string;
|
||||||
|
pmw: string;
|
||||||
|
pmh: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** App 内微信支付入参(getGameplay 的 data)。§12 支付相关 */
|
||||||
|
export interface GamePayReq {
|
||||||
|
price: string;
|
||||||
|
body: string;
|
||||||
|
typeplay: number; // int
|
||||||
|
type: string;
|
||||||
|
user: number; // int
|
||||||
|
}
|
||||||
|
|
||||||
|
/** App 内微信支付结果回传(PayuserPaytypePaystate 出站 data)。§12 支付相关 */
|
||||||
|
export interface PayStateResp {
|
||||||
|
user: string;
|
||||||
|
state: number; // int:1 成功 / 0 取消
|
||||||
|
typeplay: string;
|
||||||
|
type: string;
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 微信登录回传(sharelogin 出站 data),全 String。§12 sharelogin */
|
||||||
|
export interface ShareLoginResp {
|
||||||
|
openid: string;
|
||||||
|
headimgurl: string;
|
||||||
|
nickname: string;
|
||||||
|
sex: string;
|
||||||
|
city: string;
|
||||||
|
province: string;
|
||||||
|
unionid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 分享结果回传(sharesuccess 出站 data)。§12 sharesuccess */
|
||||||
|
export interface ShareSuccessResp {
|
||||||
|
/** 2 成功 / 3 取消 */
|
||||||
|
success: number;
|
||||||
|
/** 1 好友 / 2 朋友圈 */
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开通用网页容器入参(OpenurlTitleData 的 data)。§8.8 / §11.2 */
|
||||||
|
export interface OpenUrlTitleDataReq {
|
||||||
|
url: string;
|
||||||
|
title: string;
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 按包名启动 App 入参(openApplyDownloadpath 的 data)。§8.8 */
|
||||||
|
export interface OpenApplyDownloadReq {
|
||||||
|
packagename: string;
|
||||||
|
downloadpath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 容器内切换子游戏入参(SwitchOverGameData 的 data)。§11.1 */
|
||||||
|
export interface SwitchOverGameReq {
|
||||||
|
/** "2" 竖屏 / "3" 横屏 */
|
||||||
|
webtype: string;
|
||||||
|
/** 目标游戏目录名 */
|
||||||
|
Gamedirectory: string;
|
||||||
|
/** 游戏 id(用于判断/下载) */
|
||||||
|
gamedownloadurl: string;
|
||||||
|
/** 交换数据 */
|
||||||
|
data: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 播放语音消息入参(mediaTypeAudio 的 data)。§8.7 */
|
||||||
|
export interface MediaTypeAudioReq {
|
||||||
|
audiourl: string;
|
||||||
|
type: string;
|
||||||
|
user: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 播放游戏音效/背景乐入参(srcIsloop 的 data)。§8.7 / §10.6 */
|
||||||
|
export interface SrcIsLoopReq {
|
||||||
|
/** wav 文件名(非 URL),路径 <解压根>/<game>/assets/wav/<src> */
|
||||||
|
src: string;
|
||||||
|
/** 0 播一次 / >0 循环 / <0 停止 */
|
||||||
|
isloop: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 录音上传完成回传(getaudiourl 出站 data)。§9 / §10.6 */
|
||||||
|
export interface GetAudioUrlResp {
|
||||||
|
audiourl: string;
|
||||||
|
time: number; // float
|
||||||
|
/** 旧容器 webviewActivity 录音成功时额外携带,值同 audiourl */
|
||||||
|
filepath?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** WiFi 信号回传(getwifiLevel 出站 data)。§9 */
|
||||||
|
export interface WifiLevelResp {
|
||||||
|
ssidname: string;
|
||||||
|
signalLevel: number; // int 0~4
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
* 入站 Handler 全集(H5 → 原生)。
|
||||||
|
*
|
||||||
|
* 来源:《TSGame_原生与H5接口契约总规范》§8。H5 通过
|
||||||
|
* `bridge.callHandler('<名称>', '<data>', responseCallback)` 调用,原生用
|
||||||
|
* `registerHandler('<名称>', ...)` 接收。
|
||||||
|
*
|
||||||
|
* 🔴 铁律:枚举【值】是 H5 实际发出的字符串,**必须与原 Android 代码逐字一致**,
|
||||||
|
* 包括拼写错误(`finsh`/`getcameraaAddress`/`canclevibrator` 等),不可"纠正"。
|
||||||
|
* 枚举【成员名】仅供 ArkTS 侧引用,可用规范驼峰。
|
||||||
|
*/
|
||||||
|
export enum InboundHandlers {
|
||||||
|
// —— §8.1 账号 / 社交 ——
|
||||||
|
/** 触发授权登录("1"=QQ 空实现 / 其他=微信)。异步回传 sharelogin */
|
||||||
|
AccreditLogin = 'accreditlogin',
|
||||||
|
/** 分享(微信/QQ/抖音),data=sharetypeBean JSON。异步回传 sharesuccess(仅微信) */
|
||||||
|
FriendsShare = 'friendsSharetypeUrlToptitleDescript',
|
||||||
|
/** 批量下载图片/头像到本地,data=图片下载 JSON 数组。异步回传 getphoto */
|
||||||
|
GetPhoto = 'getphoto',
|
||||||
|
|
||||||
|
// —— §8.2 支付 ——
|
||||||
|
/** 浏览器方式支付(当前生效),data=收银台 URL。无回传 */
|
||||||
|
PayBrowser = 'paybrowser',
|
||||||
|
/** App 内微信支付(仅旧版容器),data=GamePay JSON。异步回传 PayuserPaytypePaystate */
|
||||||
|
GetGameplay = 'getGameplay',
|
||||||
|
|
||||||
|
// —— §8.3 设备 / 系统信息 ——
|
||||||
|
/** 获取系统时间,同步返回毫秒时间戳裸串 */
|
||||||
|
GetTime = 'getTime',
|
||||||
|
/** 获取电话状态,同步返回 int 裸串(0 挂断/1 接起/2…) */
|
||||||
|
GetPhoneState = 'getphonestate',
|
||||||
|
/** 主动获取电量,异步回传 getBattery */
|
||||||
|
GetBattery = 'getbattery',
|
||||||
|
/** 主动获取 WiFi 信号,异步回传 getwifiLevel */
|
||||||
|
GetWifiLevel = 'getwifiLevel',
|
||||||
|
/** 主动获取网络状态,同步返回 int 裸串(1 无网/2 WiFi/3 移动) */
|
||||||
|
GetNetwork = 'getnetwork',
|
||||||
|
/** App 版本比较结果,同步返回 int 裸串(1=本地>网络,0=否) */
|
||||||
|
GetCompareCode = 'getcompareCode',
|
||||||
|
/** 获取手机配置信息(注意大写 I,区别出站 getphoneinfo),异步回传 getphoneinfo */
|
||||||
|
GetPhoneInfo = 'getphoneInfo',
|
||||||
|
/** 获取市场 ID,同步返回 market 值裸串 */
|
||||||
|
GetMarketName = 'getmarketname',
|
||||||
|
/** 获取任意本地配置值,data=配置名,同步返回该配置值裸串 */
|
||||||
|
GetOtherName = 'getothername',
|
||||||
|
/** 获取 other 配置值,同步返回裸串 */
|
||||||
|
GetOther = 'getOther',
|
||||||
|
|
||||||
|
// —— §8.4 交互 / 反馈 ——
|
||||||
|
/** 切换屏幕方向,data="1"横屏/其他竖屏 */
|
||||||
|
Orientation = 'orientation',
|
||||||
|
/** 震动,data=long 毫秒裸串 */
|
||||||
|
Vibrator = 'vibrator',
|
||||||
|
/** 重复震动,data=int(-1 否/1 重复) */
|
||||||
|
RepeatVibrator = 'repeatvibrator',
|
||||||
|
/** 取消震动(拼写原样 cancle) */
|
||||||
|
CancleVibrator = 'canclevibrator',
|
||||||
|
/** 写入剪贴板,data=文本 */
|
||||||
|
GameCopyText = 'gameCopytext',
|
||||||
|
/** 读取剪贴板,同步返回剪贴板内容裸串 */
|
||||||
|
GamePasteText = 'gamepastetext',
|
||||||
|
/** 发送通知(空实现,未落地),data=裸串 */
|
||||||
|
Notification = 'notification',
|
||||||
|
|
||||||
|
// —— §8.5 摇一摇 ——
|
||||||
|
/** 开始监听摇一摇,异步回传 shakeEnd */
|
||||||
|
StartShake = 'startshake',
|
||||||
|
/** 摇一摇声音开关,data="1"开/其他关 */
|
||||||
|
SwitchShake = 'SwitchShake',
|
||||||
|
/** 停止监听摇一摇 */
|
||||||
|
StopShake = 'stopshake',
|
||||||
|
|
||||||
|
// —— §8.6 定位 ——
|
||||||
|
/** 开启定位,data="1"连续/其他单次。异步回传 getlocationinfo */
|
||||||
|
StartLocation = 'startlocation',
|
||||||
|
/** 主动取最近一次定位,同步返回 MaplocationInfo JSON(未就绪返回错误码 JSON) */
|
||||||
|
GetLocationInfo = 'getlocationinfo',
|
||||||
|
|
||||||
|
// —— §8.7 音频 ——
|
||||||
|
/** 准备/开始录音(长按)。异步回传 getaudiourl */
|
||||||
|
PrepareAudio = 'prepareaudio',
|
||||||
|
/** 播放语音消息,data=audiourl/type/user JSON。异步回传 gameui_play_voice/gameui_stop_voice */
|
||||||
|
MediaTypeAudio = 'mediaTypeAudio',
|
||||||
|
/** 播放游戏音效/背景乐,data=src/isloop JSON。无回传 */
|
||||||
|
SrcIsLoop = 'srcIsloop',
|
||||||
|
/** 语音播放总开关,data="1"开/其他静音 */
|
||||||
|
VoicePlaying = 'voicePlaying',
|
||||||
|
|
||||||
|
// —— §8.8 扫码 / 相机 / 浏览器 / 网页 ——
|
||||||
|
/** 打开扫一扫(拼写原样 saoma),异步回传 getsaomaData */
|
||||||
|
OpenSaoma = 'opensaoma',
|
||||||
|
/** 打开相机拍照,异步回传 getcameraaAddress */
|
||||||
|
OpenCamera = 'opencamera',
|
||||||
|
/** 系统/QQ 浏览器打开链接,data=URL */
|
||||||
|
Browser = 'browser',
|
||||||
|
/** 打开内置通用网页容器(子游戏跳转路径 B),data=url/title/data JSON。回传 getWebdata */
|
||||||
|
OpenUrlTitleData = 'OpenurlTitleData',
|
||||||
|
/** 按包名启动 App,失败则浏览器打开下载地址,data=packagename/downloadpath JSON */
|
||||||
|
OpenApplyDownloadPath = 'openApplyDownloadpath',
|
||||||
|
|
||||||
|
// —— §8.9 子游戏切换 / 房间(音视频) ——
|
||||||
|
/** 容器内切换子游戏(路径 A),data=webtype/Gamedirectory/gamedownloadurl/data JSON */
|
||||||
|
SwitchOverGameData = 'SwitchOverGameData',
|
||||||
|
/** 判断子游戏资源是否就绪,data=目录名,同步返回 "1"已装/"0"未装 */
|
||||||
|
GetGameInstall = 'getGameinstall',
|
||||||
|
/** 加入/创建音视频房间(声网),data=videoinfobean JSON。【本期桩】 */
|
||||||
|
CreateRoom = 'createRoom',
|
||||||
|
/** 退出房间,data=裸串。【本期桩】 */
|
||||||
|
ExitRoom = 'exitRoom',
|
||||||
|
/** 请求/绑定远端视频窗口,data=Othervideoinfo JSON。异步回传 getVideoinfo。【本期桩】 */
|
||||||
|
GetVideoInfo = 'getVideoinfo',
|
||||||
|
/** 视频悬浮框显隐,data="1"显示/其他隐藏。【本期桩】 */
|
||||||
|
DragViewVideoIsShow = 'DragViewvideoIsshow',
|
||||||
|
|
||||||
|
// —— §8.10 退出 / 返回 ——
|
||||||
|
/** 退出游戏(拼写原样 finsh,非 finish) */
|
||||||
|
Finsh = 'finsh',
|
||||||
|
/** 子游戏带数据返回大厅(仅 NewwebviewActivity),data=裸串 */
|
||||||
|
BackGameData = 'backgameData',
|
||||||
|
/** 获取通讯录(未实现/已注释,保留名以兜底) */
|
||||||
|
GetAddressBook = 'getAddressBook',
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 出站 Handler 全集(原生 → H5)。
|
||||||
|
*
|
||||||
|
* 来源:《TSGame_原生与H5接口契约总规范》§9。原生通过
|
||||||
|
* `callHandler('<名称>', '<data>', null)` 调用;H5 必须用
|
||||||
|
* `registerHandler('<名称>', ...)` 注册才能收到。
|
||||||
|
*
|
||||||
|
* 🔴 命名陷阱(与入站对照,逐字保留):
|
||||||
|
* - 出站 `getphoneinfo`(全小写) ≠ 入站 `getphoneInfo`(大写 I)。
|
||||||
|
* - 出站 `getBattery`(大写 B) ≠ 入站 `getbattery`(小写 b)。
|
||||||
|
* - 出站 `backgameData-`(**末尾连字符**) ≠ 入站 `backgameData`(无连字符)。
|
||||||
|
* - getphoto/getwifiLevel/getnetwork/getlocationinfo/getVideoinfo 入站出站【同名】。
|
||||||
|
*/
|
||||||
|
export enum OutboundHandlers {
|
||||||
|
/** 前后台状态,data="1"前台/"2"后台。首次加载 100% 及前后台切换时下发 */
|
||||||
|
AppService = 'appservice',
|
||||||
|
/** 截图上传地址 http://<本机IP>:<端口>/testurl。页面加载完成时下发 */
|
||||||
|
SetPostUrl = 'setPostUrl',
|
||||||
|
/** 网页回传 text / Intent 透传 data。页面首次加载完成;或通用网页关闭回传(101) */
|
||||||
|
GetWebData = 'getWebdata',
|
||||||
|
/** 图片/头像下载完成,data=[{pid,photourl}] JSON 数组。与入站 getphoto 同名 */
|
||||||
|
GetPhoto = 'getphoto',
|
||||||
|
/** 微信授权登录成功,data=sharelogin JSON(用户资料) */
|
||||||
|
ShareLogin = 'sharelogin',
|
||||||
|
/** 分享结果,data={success,type} JSON(success 2 成功/3 取消)。仅微信完整 */
|
||||||
|
ShareSuccess = 'sharesuccess',
|
||||||
|
/** 摇一摇触发后约 1 秒,data="" 空串 */
|
||||||
|
ShakeEnd = 'shakeEnd',
|
||||||
|
/** 电量,data=float 裸串(0~1)。大写 B,区别入站 getbattery */
|
||||||
|
GetBattery = 'getBattery',
|
||||||
|
/** WiFi 信号,data={ssidname,signalLevel(0~4)} JSON。与入站同名 */
|
||||||
|
GetWifiLevel = 'getwifiLevel',
|
||||||
|
/** 网络状态变化,data=int 裸串(1 断网/2 WiFi/3 移动)。与入站同名 */
|
||||||
|
GetNetwork = 'getnetwork',
|
||||||
|
/** 录音上传完成/取消,data={audiourl,time(,filepath)} JSON */
|
||||||
|
GetAudioUrl = 'getaudiourl',
|
||||||
|
/** 语音开始播放,data=user 透传裸串 */
|
||||||
|
GameUiPlayVoice = 'gameui_play_voice',
|
||||||
|
/** 语音播放完成/被打断,data=user 透传裸串 */
|
||||||
|
GameUiStopVoice = 'gameui_stop_voice',
|
||||||
|
/** 手机配置信息,data=phoneInfoBean JSON。全小写,区别入站 getphoneInfo */
|
||||||
|
GetPhoneInfo = 'getphoneinfo',
|
||||||
|
/** 房间其他用户加入,data=int 裸串(远端 uid)。【本期桩不推】 */
|
||||||
|
GetVideoInfo = 'getVideoinfo',
|
||||||
|
/** App 内微信支付结果,data={user,state,typeplay,type,data} JSON。【本期桩不推】 */
|
||||||
|
PayUserPayTypePayState = 'PayuserPaytypePaystate',
|
||||||
|
/** 定位结果,data=MaplocationInfo JSON(或错误码 JSON)。与入站同名 */
|
||||||
|
GetLocationInfo = 'getlocationinfo',
|
||||||
|
/** 来电状态广播,data=int 裸串 */
|
||||||
|
PhoneState = 'phonestate',
|
||||||
|
/** 扫码返回,data=扫码结果裸串 */
|
||||||
|
GetSaomaData = 'getsaomaData',
|
||||||
|
/** 拍照返回(拼写原样双 a),data=照片路径裸串 */
|
||||||
|
GetCameraAddress = 'getcameraaAddress',
|
||||||
|
/** 返回键确认对话框流程,data="" 空串。⚠ 末尾连字符,区别入站 backgameData */
|
||||||
|
BackGameDataDash = 'backgameData-',
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* 每个 handler 的载荷类型标注(《契约规范》§8/§9,框架 §5.4 "裸串 vs JSON 陷阱")。
|
||||||
|
*
|
||||||
|
* `raw` —— data 是裸字符串,能力层直接使用,不做 JSON 解析/序列化。
|
||||||
|
* `json` —— data 是 JSON 字符串,能力层需 JSON.parse(入站)/ JSON.stringify(出站)。
|
||||||
|
*
|
||||||
|
* 用途:MessageCodec 不擅自 JSON 化 data;能力层据此逐 handler 决定如何处理载荷,
|
||||||
|
* 编译期可查、杜绝写错。查询用 `inboundPayloadType()` / `outboundPayloadType()`。
|
||||||
|
*/
|
||||||
|
import { InboundHandlers } from './InboundHandlers';
|
||||||
|
import { OutboundHandlers } from './OutboundHandlers';
|
||||||
|
|
||||||
|
export type PayloadType = 'raw' | 'json';
|
||||||
|
|
||||||
|
/** 入站 handler 的入参载荷类型(H5 → 原生)。 */
|
||||||
|
export const InboundPayload: Map<string, PayloadType> = new Map<string, PayloadType>([
|
||||||
|
[InboundHandlers.AccreditLogin, 'raw'],
|
||||||
|
[InboundHandlers.FriendsShare, 'json'],
|
||||||
|
[InboundHandlers.GetPhoto, 'json'],
|
||||||
|
[InboundHandlers.PayBrowser, 'raw'],
|
||||||
|
[InboundHandlers.GetGameplay, 'json'],
|
||||||
|
[InboundHandlers.GetTime, 'raw'],
|
||||||
|
[InboundHandlers.GetPhoneState, 'raw'],
|
||||||
|
[InboundHandlers.GetBattery, 'raw'],
|
||||||
|
[InboundHandlers.GetWifiLevel, 'raw'],
|
||||||
|
[InboundHandlers.GetNetwork, 'raw'],
|
||||||
|
[InboundHandlers.GetCompareCode, 'raw'],
|
||||||
|
[InboundHandlers.GetPhoneInfo, 'raw'],
|
||||||
|
[InboundHandlers.GetMarketName, 'raw'],
|
||||||
|
[InboundHandlers.GetOtherName, 'raw'],
|
||||||
|
[InboundHandlers.GetOther, 'raw'],
|
||||||
|
[InboundHandlers.Orientation, 'raw'],
|
||||||
|
[InboundHandlers.Vibrator, 'raw'],
|
||||||
|
[InboundHandlers.RepeatVibrator, 'raw'],
|
||||||
|
[InboundHandlers.CancleVibrator, 'raw'],
|
||||||
|
[InboundHandlers.GameCopyText, 'raw'],
|
||||||
|
[InboundHandlers.GamePasteText, 'raw'],
|
||||||
|
[InboundHandlers.Notification, 'raw'],
|
||||||
|
[InboundHandlers.StartShake, 'raw'],
|
||||||
|
[InboundHandlers.SwitchShake, 'raw'],
|
||||||
|
[InboundHandlers.StopShake, 'raw'],
|
||||||
|
[InboundHandlers.StartLocation, 'raw'],
|
||||||
|
[InboundHandlers.GetLocationInfo, 'raw'],
|
||||||
|
[InboundHandlers.PrepareAudio, 'raw'],
|
||||||
|
[InboundHandlers.MediaTypeAudio, 'json'],
|
||||||
|
[InboundHandlers.SrcIsLoop, 'json'],
|
||||||
|
[InboundHandlers.VoicePlaying, 'raw'],
|
||||||
|
[InboundHandlers.OpenSaoma, 'raw'],
|
||||||
|
[InboundHandlers.OpenCamera, 'raw'],
|
||||||
|
[InboundHandlers.Browser, 'raw'],
|
||||||
|
[InboundHandlers.OpenUrlTitleData, 'json'],
|
||||||
|
[InboundHandlers.OpenApplyDownloadPath, 'json'],
|
||||||
|
[InboundHandlers.SwitchOverGameData, 'json'],
|
||||||
|
[InboundHandlers.GetGameInstall, 'raw'],
|
||||||
|
[InboundHandlers.CreateRoom, 'json'],
|
||||||
|
[InboundHandlers.ExitRoom, 'raw'],
|
||||||
|
[InboundHandlers.GetVideoInfo, 'json'],
|
||||||
|
[InboundHandlers.DragViewVideoIsShow, 'raw'],
|
||||||
|
[InboundHandlers.Finsh, 'raw'],
|
||||||
|
[InboundHandlers.BackGameData, 'raw'],
|
||||||
|
[InboundHandlers.GetAddressBook, 'raw'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入站 handler 的【同步返回】载荷类型(仅对有同步返回的 handler 标注)。
|
||||||
|
* 未列出者表示无同步返回(结果走出站异步推送或无返回)。
|
||||||
|
*/
|
||||||
|
export const InboundSyncReturn: Map<string, PayloadType> = new Map<string, PayloadType>([
|
||||||
|
[InboundHandlers.GetTime, 'raw'],
|
||||||
|
[InboundHandlers.GetPhoneState, 'raw'],
|
||||||
|
[InboundHandlers.GetNetwork, 'raw'],
|
||||||
|
[InboundHandlers.GetCompareCode, 'raw'],
|
||||||
|
[InboundHandlers.GetMarketName, 'raw'],
|
||||||
|
[InboundHandlers.GetOtherName, 'raw'],
|
||||||
|
[InboundHandlers.GetOther, 'raw'],
|
||||||
|
[InboundHandlers.GamePasteText, 'raw'],
|
||||||
|
[InboundHandlers.GetLocationInfo, 'json'],
|
||||||
|
[InboundHandlers.GetGameInstall, 'raw'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** 出站 handler 的下发载荷类型(原生 → H5)。 */
|
||||||
|
export const OutboundPayload: Map<string, PayloadType> = new Map<string, PayloadType>([
|
||||||
|
[OutboundHandlers.AppService, 'raw'],
|
||||||
|
[OutboundHandlers.SetPostUrl, 'raw'],
|
||||||
|
[OutboundHandlers.GetWebData, 'raw'],
|
||||||
|
[OutboundHandlers.GetPhoto, 'json'],
|
||||||
|
[OutboundHandlers.ShareLogin, 'json'],
|
||||||
|
[OutboundHandlers.ShareSuccess, 'json'],
|
||||||
|
[OutboundHandlers.ShakeEnd, 'raw'],
|
||||||
|
[OutboundHandlers.GetBattery, 'raw'],
|
||||||
|
[OutboundHandlers.GetWifiLevel, 'json'],
|
||||||
|
[OutboundHandlers.GetNetwork, 'raw'],
|
||||||
|
[OutboundHandlers.GetAudioUrl, 'json'],
|
||||||
|
[OutboundHandlers.GameUiPlayVoice, 'raw'],
|
||||||
|
[OutboundHandlers.GameUiStopVoice, 'raw'],
|
||||||
|
[OutboundHandlers.GetPhoneInfo, 'json'],
|
||||||
|
[OutboundHandlers.GetVideoInfo, 'raw'],
|
||||||
|
[OutboundHandlers.PayUserPayTypePayState, 'json'],
|
||||||
|
[OutboundHandlers.GetLocationInfo, 'json'],
|
||||||
|
[OutboundHandlers.PhoneState, 'raw'],
|
||||||
|
[OutboundHandlers.GetSaomaData, 'raw'],
|
||||||
|
[OutboundHandlers.GetCameraAddress, 'raw'],
|
||||||
|
[OutboundHandlers.BackGameDataDash, 'raw'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
export function inboundPayloadType(name: string): PayloadType {
|
||||||
|
return InboundPayload.get(name) ?? 'raw';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function outboundPayloadType(name: string): PayloadType {
|
||||||
|
return OutboundPayload.get(name) ?? 'raw';
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 错误码与错误类型定义。
|
||||||
|
*
|
||||||
|
* 定位错误码来自《契约规范》§10.8 / §12 MaplocationInfo.errorCode;
|
||||||
|
* 其余为框架内部统一错误分类(框架 §10 ErrorCenter)。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 定位错误码(MaplocationInfo.errorCode 取值约定)。 */
|
||||||
|
export enum LocationErrorCode {
|
||||||
|
Success = 0,
|
||||||
|
/** 高德/底层原始错误码为正数时按原值透传 */
|
||||||
|
NotReady = -1,
|
||||||
|
PermissionDenied = -2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 框架内部错误类别(用于 ErrorCenter 收敛与处置策略)。 */
|
||||||
|
export enum ErrorKind {
|
||||||
|
/** 网络/请求失败 */
|
||||||
|
Network = 'network',
|
||||||
|
/** 配置解析/缺失 */
|
||||||
|
Config = 'config',
|
||||||
|
/** 资源下载/解压失败 */
|
||||||
|
Resource = 'resource',
|
||||||
|
/** 权限被拒 */
|
||||||
|
Permission = 'permission',
|
||||||
|
/** 桥消息编解码/分发异常 */
|
||||||
|
Bridge = 'bridge',
|
||||||
|
/** 能力 Provider 内部异常 */
|
||||||
|
Capability = 'capability',
|
||||||
|
/** 未分类 */
|
||||||
|
Unknown = 'unknown',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 统一错误对象。 */
|
||||||
|
export interface AppError {
|
||||||
|
kind: ErrorKind;
|
||||||
|
/** 机器可读错误码(可选,如定位错误码、HTTP 状态码) */
|
||||||
|
code?: number;
|
||||||
|
/** 人类可读信息 */
|
||||||
|
message: string;
|
||||||
|
/** 原始底层错误(可选) */
|
||||||
|
cause?: Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeError(kind: ErrorKind, message: string, code?: number, cause?: Object): AppError {
|
||||||
|
return { kind, message, code, cause };
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 统一返回类型 Result<T>(框架 §10 横切:错误中心)。
|
||||||
|
*
|
||||||
|
* 成功携带 data,失败携带 AppError。用工厂方法构造,避免散落的 try/catch
|
||||||
|
* 直接抛到上层;调用方用 `isOk()` 收窄后取 `data`/`error`。
|
||||||
|
*/
|
||||||
|
import { AppError, ErrorKind, makeError } from './Errors';
|
||||||
|
|
||||||
|
export class Result<T> {
|
||||||
|
readonly success: boolean;
|
||||||
|
readonly data?: T;
|
||||||
|
readonly error?: AppError;
|
||||||
|
|
||||||
|
private constructor(success: boolean, data?: T, error?: AppError) {
|
||||||
|
this.success = success;
|
||||||
|
this.data = data;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ok<T>(data: T): Result<T> {
|
||||||
|
return new Result<T>(true, data, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fail<T>(error: AppError): Result<T> {
|
||||||
|
return new Result<T>(false, undefined, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static failWith<T>(kind: ErrorKind, message: string, code?: number): Result<T> {
|
||||||
|
return new Result<T>(false, undefined, makeError(kind, message, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
isOk(): boolean {
|
||||||
|
return this.success;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user