diff --git a/miniprogram/core/Api.ts b/miniprogram/core/Api.ts index d0027ef..05bab2f 100644 --- a/miniprogram/core/Api.ts +++ b/miniprogram/core/Api.ts @@ -1,4 +1,5 @@ -import { Emitter } from "./Emitter"; +import { Emitter, EventType } from "./Emitter"; +import { API_FAILED_SHOW_MESSAGE } from "./Config"; import { Logger, LogLabel, LevelLogLabel, colorRadio, StatusLabel } from "./Logger"; interface IAppAPIParam { api: { @@ -116,16 +117,57 @@ type IAPIEvent = { } /** - * 接口调用 + * 输出事件类型 */ -class API extends Emitter> { +type IAPIResultEvent = { + + /** + * 成功获取数据 + */ + ok: O, + + /** + * 无论因为什么 + * 总之数据获取到 + */ + no: { message: string } & U, + + /** + * 完成了 + * 无论失败与否 + */ + done: { message: string, data: O } & U +} + +/** + * API 接口调用 + * @template I API 输入数据 + * @template O API 输出数据 + * @template E API 中的事件 + * @template U 用户自定义的输出数据 + */ +class API< + I extends IAnyData = IAnyData, + O extends IAnyData = IAnyData, + E extends Record = Record, + U extends IAnyData = IAnyData +> extends Emitter < + { + // 这个复杂的泛型是为了 MixIn 用户自定义事件类型 + // 懂得如何使用就可以了 + // 不要试图去理解下面这三行代码,真正的恶魔在等着你 + [P in (keyof (IAPIEvent & IAPIResultEvent) | keyof E)] : + P extends keyof IAPIEvent ? IAPIEvent[P] : + P extends keyof IAPIResultEvent ? IAPIResultEvent[P] : E[P] + } +> { /** * 基础 URL * TODO: 这里可能涉及负载均衡 */ public static get baseUrl():string { - return "https://blog.mrkbear.com"; + return "https://jwc.nogg.cn"; } public static defaultLogLabel:LogLabel = new LogLabel( @@ -366,7 +408,7 @@ class API extends Emitter { - if (api === this) return; + if ((api as API | this) === this) return; if (!api.requestData) return; if (api.requestData!.url !== this.requestData!.url) return; if (api.requestData!.method !== this.requestData!.method) return; @@ -471,9 +513,9 @@ class API extends Emitter>; - public wait(callBack?: ICallBack): this; - public wait(callBack?: ICallBack): Promise> | this { + public waitRequest(): Promise>; + public waitRequest(callBack: ICallBack): this; + public waitRequest(callBack?: ICallBack): Promise> | this { // 存在 callback 使用传统回调 if (callBack) { @@ -491,6 +533,85 @@ class API extends Emitter["done"]>; + public wait(callBack: IResCallBack): this; + public wait(callBack?: IResCallBack): Promise["done"]> | this { + + // 存在 callback 使用传统回调 + if (callBack) { + callBack.ok && this.on("ok", callBack.ok); + callBack.no && this.on("no", callBack.no); + callBack.done && this.on("done", callBack.done); + return this; + } + + // 不存在 callback 使用 Promise 对象 + else { + return new Promise((r) => { + this.on("done", r); + }); + } + } + + /** + * 请求加载时显示加载动画 + * @param message 消息 可以为函数 + * @param mask 使用蒙版阻止点击穿透 + */ + public showLoading(message: string | ((data?: Partial) => string), mask: boolean = false): this { + + // 获取标题 + let title: string = message instanceof Function ? message(this.data) : message; + + this.on("request", () => { + wx.showLoading({ + title, mask + }) + }); + + this.on("complete", () => { + wx.hideLoading(); + }); + + return this; + }; + + /** + * 显示导航栏加载动画 + */ + public showNavigationBarLoading(): this { + + this.on("request", () => { + wx.showNavigationBarLoading() + }); + + this.on("complete", () => { + wx.hideNavigationBarLoading(); + }); + + return this; + } + + /** + * 请求失败后的提示语句 + */ + public showFailed(): this { + + // 生成随机索引值 + let randomIndex = Math.floor( + Math.random() * API_FAILED_SHOW_MESSAGE.length + ); + + this.on("fail", () => { + wx.showToast({ + title: API_FAILED_SHOW_MESSAGE[randomIndex], + icon: "none" + }); + }); + + return this; + }; } /** @@ -507,6 +628,12 @@ interface ICallBack { complete?: (data: IAPIEvent<{}, O>["complete"]) => any; } +interface IResCallBack { + ok?: (data: IAPIResultEvent["ok"]) => any; + no?: (data: IAPIResultEvent["no"]) => any; + done?: (data: IAPIResultEvent["done"]) => any; +} + /** * Request 请求策略 * 此策略用于节流 diff --git a/miniprogram/core/Config.ts b/miniprogram/core/Config.ts index 1a9dca9..6a968e8 100644 --- a/miniprogram/core/Config.ts +++ b/miniprogram/core/Config.ts @@ -36,3 +36,14 @@ export const LOGGER_FILTER:Array[] = [ // 输出警告和错误 // ["WARN", "ERROR", "FATAL"], ]; + +/** + * 请求失败的提示用语 + * 请求失败时如果选择自动显示消息 + * 则会从以下内容中选择 + */ +export const API_FAILED_SHOW_MESSAGE: string[] = [ + "失败啦(ó_ò。)", "服务器睡着了", "数据移民火星了", + "数据在半路走丢了", "服务器打了个瞌睡", "服务器被玩坏了", + "服务器在扶老奶奶过马路", "服务器累了", "服务器在拯救世界" +] \ No newline at end of file diff --git a/miniprogram/pages/Timetable/TestCore.ts b/miniprogram/pages/Timetable/TestCore.ts index cc9c7cd..70259d0 100644 --- a/miniprogram/pages/Timetable/TestCore.ts +++ b/miniprogram/pages/Timetable/TestCore.ts @@ -62,7 +62,7 @@ implements Partial { info: { data: "abc" } - }).request().wait({ + }).request().waitRequest({ success: (d) => console.log(d) }) }