From 4f49012bb695212197473962cb243da9ac863ba8 Mon Sep 17 00:00:00 2001 From: MrKBear Date: Fri, 31 Dec 2021 17:20:54 +0800 Subject: [PATCH 1/4] Update ReadMe file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a50321..dcb92d2 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ 掌上教务处作为工业大学的社区开源项目,自从2017年开始已有近5年岁月,在无数同学的贡献之下,为大家打造便捷的校园服务。 -__*!!!注意!!!*__ +__*!!!警告!!!*__ -请在主仓库提交代码,而非镜像仓库! +请在主仓库提交代码,而非镜像仓库!在镜像仓库提交的代码将会在同步时被覆盖! 主仓库: http://git.mrkbear.com/MrKBear/mini-dlpu-v3 From 22af68428f77f0b09706849449f9f4ca5d795d1e Mon Sep 17 00:00:00 2001 From: mrkbear Date: Sun, 2 Jan 2022 18:29:21 +0800 Subject: [PATCH 2/4] Storage multi instance processing logic --- miniprogram/app.ts | 5 +- miniprogram/core/Storage.ts | 72 +++++++++++++++++++++++-- miniprogram/pages/Timetable/TestCore.ts | 13 +++-- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/miniprogram/app.ts b/miniprogram/app.ts index f2661d8..c05849f 100644 --- a/miniprogram/app.ts +++ b/miniprogram/app.ts @@ -1,8 +1,9 @@ import { IAppAPIParam } from "./core/Api"; +import { IAppStorageParam, Storage, IStorageData } from "./core/Storage"; import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger"; -App({ +App({ /** * API 模块需要的全局数据 @@ -16,7 +17,7 @@ App({ /** * 存储缓存键值 */ - // storageCache: new Set(), + storage: new Map>(), /** * 小程序加载时 diff --git a/miniprogram/core/Storage.ts b/miniprogram/core/Storage.ts index 1d36a19..13d7eae 100644 --- a/miniprogram/core/Storage.ts +++ b/miniprogram/core/Storage.ts @@ -1,5 +1,13 @@ import { Logger, LogLabel, LevelLogLabel, colorRadio } from "./Logger"; +interface IAppStorageParam { + + /** + * storage 缓存 + */ + storage: Map> +} + /** * 状态 */ @@ -81,7 +89,8 @@ type IStorageData = { * 1. 该类封装了 wxStorage 操作 * 2. 全异步获取无阻塞 * 3. 使用数据缓缓冲区,优化高频存取 - * 4. + * 4. 如果全局范围内已存在莫键值 storage 的实例 + * 则此实例将链接到已存在实例 */ class Storage { @@ -103,18 +112,41 @@ class Storage { /** * 缓存数据 */ - private cache:T; + private _cache: T = {} as T; + private set cache(data: T) { + if (this.cacheStorage) { + for (const key in data) { + this.cacheStorage.cache[key] = data[key]; + } + } else { + for (const key in data) { + this._cache[key] = data[key]; + } + } + } + private get cache():T { + if (this.cacheStorage) return this.cacheStorage.cache; + else return this._cache; + } /** * cache 到 storage 等待列表 */ private saveWaiter:Waiter = new Waiter(); + /** + * 缓存对象 + */ + private cacheStorage:Storage | undefined; + /** * 将数据从 cache 同步到 storage */ public async save():Promise { + // 如果存在链接的实例 + if (this.cacheStorage) return this.cacheStorage.save(); + // 如果没有开始存储 // 发起一次异步读取 if(this.saveWaiter.state === StorageState.DONE) @@ -150,6 +182,24 @@ class Storage { }); } + /** + * 在缓存中搜索此键值的实例 + */ + private findStorageCache(): boolean { + let { storage: storageMap } = getApp(); + + // 查找缓存 + let storage = storageMap.get(this.key); + if (storage) { + this.cacheStorage = storage as Storage; + return true; + }; + + // 缓存此实例 + storageMap.set(this.key, this); + return false; + } + /** * 重置全部数据 */ @@ -164,13 +214,25 @@ class Storage { /** * @param defaultData 键值默认数据 */ - public constructor(key:string, defaultData:T) { + public constructor(key:string, defaultData?:T) { this.key = key; - this.defaultData = defaultData; + this.defaultData = defaultData ?? {} as T; this.StorageLogLabel = new LogLabel( `Storage:${ this.key }`, colorRadio(34, 230, 258) ); + // 如果已找到其他实力,将此实例链接到目标实例 + if (this.findStorageCache()) { + + // 设置默认值 + for (const key in this.defaultData) { + if (this.cache[key] === void 0) { + this.set(key, this.defaultData[key]); + } + } + return; + }; + // 读取数据到缓存 this.cache = wx.getStorageSync(this.key); @@ -205,4 +267,4 @@ class Storage { } export default Storage; -export { Storage, StorageState, Waiter }; \ No newline at end of file +export { Storage, StorageState, Waiter, IAppStorageParam, IStorageData }; \ No newline at end of file diff --git a/miniprogram/pages/Timetable/TestCore.ts b/miniprogram/pages/Timetable/TestCore.ts index f405248..2fc8e6c 100644 --- a/miniprogram/pages/Timetable/TestCore.ts +++ b/miniprogram/pages/Timetable/TestCore.ts @@ -15,6 +15,15 @@ implements Partial { be: 2 }); + let s2 = new Storage("test", { + be: 1, + aa: "abc" + }); + + s2.set("be", 4); + + console.log(s, s2); + setTimeout(() => { s.set("be", 12); }, 1000) @@ -55,9 +64,7 @@ implements Partial { } }).request().wait({ success: (d) => console.log(d) - }).wait({ - success: (d) => console.log(d) - }); + }) } } From 49ed8e588afbce0727499080d1f98ca456df343f Mon Sep 17 00:00:00 2001 From: MrKBear Date: Mon, 3 Jan 2022 08:44:39 +0800 Subject: [PATCH 3/4] Remove test case --- miniprogram/core/TestCase.ts | 205 ----------------------------------- 1 file changed, 205 deletions(-) delete mode 100644 miniprogram/core/TestCase.ts diff --git a/miniprogram/core/TestCase.ts b/miniprogram/core/TestCase.ts deleted file mode 100644 index 42e0e3b..0000000 --- a/miniprogram/core/TestCase.ts +++ /dev/null @@ -1,205 +0,0 @@ -// import { Logger } from "../logger/Logger"; -import { LogStyle, LogLabel } from "./Logger"; - -/** - * 测试结果 - */ -class TestResult { - - /** - * 用例名称 - */ - public caseName:string; - - /** - * 测试结果 - */ - public result:boolean; - - /** - * 消息 - */ - public message:string; - - /** - * 附加消息 - */ - public attach:string; - - /** - * 初始化 - * @param caseName 用例名称 - */ - constructor(caseName:string) { - this.caseName = caseName; - this.result = false; - this.message = ""; - this.attach = ""; - } - - /** - * 设置结果 - */ - public setResult(result:boolean, message?:string, attach?:string) { - this.result = result; - this.message = message ?? (result ? "success!" : "failed!"); - this.attach = attach ?? this.attach; - - return this; - } -} - -/** - * 测试函数结构 - */ -type TestFunction = () => TestResult | Promise; - -/** - * 收集测试函数结构 - */ -class CaseCollect { - - /** - * 用例键名 - */ - public key:string; - - /** - * 用例测试函数 - */ - public caseFunction:TestFunction; - - /** - * 测试结果 - */ - result: Promise | undefined; - - /** - * @param key 测试用例键名 - * @param caseFunction 测试函数 - */ - public constructor(key:string, caseFunction:TestFunction) { - this.key = key; - this.caseFunction = caseFunction; - } - - /** - * 运行测试用例 - */ - public async runTestCase():Promise { - - let result = this.caseFunction(); - - if(result instanceof Promise) { - this.result = result; - } else { - this.result = Promise.resolve(result); - } - - return this; - } - - public static readonly baseStyle = new LogStyle().setBlank(); - - public static readonly successLabel:LogLabel = new LogLabel("√", - new LogStyle().setBlank("0 4px").setBorder("1000px", "1px solid green") - ); - - /** - * 打印结果 - * @param current 当前进度 - * @param total 总进度 - */ - public printResult(current?:number, total?:number) { - - // 如果测试没有运行,先运行它 - if(this.result === void 0) this.runTestCase(); - - this.result?.then((res) => { - - if(res.result) { - console.log( - `%c√%c %c1/1%c %c${ this.key }%c ` + res.message, - "padding:0 4px; border-radius:1000px; border:1px solid green; color:green", - "", "padding:0 4px; border-radius:4px; border:1px solid green; color:green", - "", "padding:0 4px; border-radius:4px; border:1px solid #979797; color:#979797", - "" - ) - } else { - console.log( - `%c√%c %c1/1%c %c${ this.key }%c ` + res.message, - "padding:0 4px; border-radius:1000px; border:1px solid red; color:red", - "", "padding:0 4px; border-radius:4px; border:1px solid red; color:red", - "", "padding:0 4px; border-radius:4px; border:1px solid #979797; color:#979797", - "" - ) - } - console.log(res) - }) - } - - /** - * 收集测试用例 - * @param testCaseClass 测试用例表 - */ - public static collectCase(testCaseClass:ITestCase):CaseCollect[] { - - // 获取静态方法 key - let key = Object.getOwnPropertyNames(testCaseClass); - - // 过滤掉通用的方法和属性 - key = key.filter((key) => !/(length|name|prototype)/.test(key) ); - - // 生成 CaseCollect - let caseCollect = []; - - for (let i = 0; i < key.length; i++) { - caseCollect.push(new CaseCollect(key[i], testCaseClass[key[i]])) - } - - return caseCollect; - } - - /** - * 运行测试样例 - */ - public static async runCollectCase(cases:CaseCollect[]):Promise { - - let running:Promise[] = []; - - for(let i = 0; i < cases.length; i++) { - running.push(cases[i].runTestCase()); - } - - return Promise.all(running); - } - - /** - * 启动单元测试 - */ - public static runUnitTest(testCaseClass:ITestCase) { - - let caseCollect = this.collectCase(testCaseClass); - - CaseCollect.runCollectCase(caseCollect).then((caseCollect:CaseCollect[]) => { - - for(let i = 0; i < caseCollect.length; i++) { - caseCollect[i].printResult() - } - }) - } -} - -/** - * 测试用例接口 - */ -interface ITestCase { - - /** - * 测试用例函数 - */ - [key:string]:TestFunction; -} - -export default ITestCase; -export { ITestCase, TestResult, TestFunction, CaseCollect }; \ No newline at end of file From 121b620312a257362b4c1f82e997fe53a1cd2453 Mon Sep 17 00:00:00 2001 From: MrKBear Date: Mon, 3 Jan 2022 13:32:52 +0800 Subject: [PATCH 4/4] Optimize Modular --- miniprogram/core/Emitter.ts | 56 ++--- miniprogram/core/Module.ts | 279 ++++++++++++++--------- miniprogram/pages/Timetable/StatusBar.ts | 6 +- miniprogram/pages/Timetable/TestCore.ts | 2 +- 4 files changed, 187 insertions(+), 156 deletions(-) diff --git a/miniprogram/core/Emitter.ts b/miniprogram/core/Emitter.ts index 06ca652..bc237e1 100644 --- a/miniprogram/core/Emitter.ts +++ b/miniprogram/core/Emitter.ts @@ -2,27 +2,18 @@ export type EventType = string | symbol; // An event handler can take an optional event argument // and should not return a value -export type Handler = (event: T) => void; -export type WildcardHandler> = ( - type: keyof T, - event: T[keyof T] -) => void; +export type Handler = (event: T) => void; // An array of all currently registered event handlers for a type -export type EventHandlerList = Array>; -export type WildCardEventHandlerList> = Array>; +export type EventHandlerList = Array>; // A map of event types and their corresponding event handlers. -export type EventHandlerMap> = Map< - keyof Events | '*', - EventHandlerList | WildCardEventHandlerList +export type EventHandlerMap> = Map< + keyof Events, + EventHandlerList >; -type GenericEventHandler> = - | Handler - | WildcardHandler; - -export class Emitter> { +export class Emitter> { /** * A Map of event names to registered handler functions. @@ -41,17 +32,14 @@ export class Emitter> { this.all!.set(type, [] as EventHandlerList); } - on(type: Key, handler: Handler): void; - on(type: '*', handler: WildcardHandler): void; - /** * Register an event handler for the given type. - * @param {string|symbol} type Type of event to listen for, or `'*'` for all events + * @param {string|symbol} type Type of event to listen for * @param {Function} handler Function to call in response to given event * @memberOf mitt */ - public on(type: Key, handler: GenericEventHandler) { - const handlers: Array> | undefined = this.all!.get(type); + public on(type: Key, handler: Handler) { + const handlers: Array> | undefined = this.all!.get(type); if (handlers) { handlers.push(handler); } @@ -60,18 +48,15 @@ export class Emitter> { } } - off(type: Key, handler?: Handler): void; - off(type: '*', handler: WildcardHandler): void; - /** * Remove an event handler for the given type. * If `handler` is omitted, all handlers of the given type are removed. - * @param {string|symbol} type Type of event to unregister `handler` from, or `'*'` + * @param {string|symbol} type Type of event to unregister `handler` from * @param {Function} [handler] Handler function to remove * @memberOf mitt */ - public off(type: Key, handler?: GenericEventHandler) { - const handlers: Array> | undefined = this.all!.get(type); + public off(type: Key, handler?: Handler) { + const handlers: Array> | undefined = this.all!.get(type); if (handlers) { if (handler) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); @@ -82,20 +67,14 @@ export class Emitter> { } } - emit(type: Key, event: Events[Key]): void; - emit(type: undefined extends Events[Key] ? Key : never): void; - /** * Invoke all handlers for the given type. - * If present, `'*'` handlers are invoked after type-matched handlers. - * - * Note: Manually firing '*' handlers is not supported. * * @param {string|symbol} type The event type to invoke * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ - emit(type: Key, evt?: Events[Key]) { + emit(type: Key, evt: Events[Key]) { let handlers = this.all!.get(type); if (handlers) { (handlers as EventHandlerList) @@ -104,14 +83,5 @@ export class Emitter> { handler(evt!); }); } - - handlers = this.all!.get('*'); - if (handlers) { - (handlers as WildCardEventHandlerList) - .slice() - .map((handler) => { - handler(type, evt!); - }); - } } } \ No newline at end of file diff --git a/miniprogram/core/Module.ts b/miniprogram/core/Module.ts index 61610ce..5a5c559 100644 --- a/miniprogram/core/Module.ts +++ b/miniprogram/core/Module.ts @@ -1,5 +1,5 @@ -import { Emitter, EventType } from "./Emitter"; -import { Logger, LogLabel, LogStyle, LevelLogLabel } from "./Logger"; +import { Emitter } from "./Emitter"; +import { Logger, LogLabel, colorRadio, LevelLogLabel } from "./Logger"; /** * 自定义对象类型 @@ -50,6 +50,149 @@ type Depends> = { [x:string]: Modular>; }; +/** + * 微信继承的函数 + */ +class WXInstanceMethods< + E extends IAnyTypeObject = IAnyTypeObject, + W extends AnyWXContext = AnyWXContext +> +extends Emitter +implements InstanceMethods { + + public superContext: W; + + public constructor(context: W) { + super(); + this.superContext = context; + } + + public setData(data: Partial & WechatMiniprogram.IAnyObject, callback?: () => void): void { + return this.superContext.setData(data, callback); + } + + public hasBehavior(behavior: string): void { + return this.superContext.hasBehavior(behavior); + } + + public triggerEvent(name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption): void { + return this.superContext.triggerEvent(name, detail, options) + } + + public createSelectorQuery(): WechatMiniprogram.SelectorQuery { + return this.superContext.createSelectorQuery(); + } + + public createIntersectionObserver(options: WechatMiniprogram.CreateIntersectionObserverOption): WechatMiniprogram.IntersectionObserver { + return this.superContext.createIntersectionObserver(options); + } + + public selectComponent(selector: string): WechatMiniprogram.Component.TrivialInstance { + return this.superContext.selectComponent(selector); + } + + public selectAllComponents(selector: string): WechatMiniprogram.Component.TrivialInstance[] { + return this.superContext.selectAllComponents(selector); + } + + public selectOwnerComponent(): WechatMiniprogram.Component.TrivialInstance { + return this.superContext.selectOwnerComponent(); + } + + public getRelationNodes(relationKey: string): WechatMiniprogram.Component.TrivialInstance[] { + return this.superContext.getRelationNodes(relationKey); + } + + public groupSetData(callback?: () => void): void { + return this.superContext.groupSetData(callback); + } + + public getTabBar(): WechatMiniprogram.Component.TrivialInstance { + return this.superContext.getTabBar(); + } + + public getPageId(): string { + return this.superContext.getPageId(); + } + + public animate(selector: string, keyFrames: WechatMiniprogram.Component.KeyFrame[], duration: number, callback?: () => void): void; + public animate(selector: string, keyFrames: WechatMiniprogram.Component.ScrollTimelineKeyframe[], duration: number, + scrollTimeline: WechatMiniprogram.Component.ScrollTimelineOption): void; + public animate(selector: any, keyFrames: any, duration: any, scrollTimeline?: any): void { + return this.superContext.animate(selector, keyFrames, duration, scrollTimeline); + } + + public clearAnimation(selector: string, callback: () => void): void; + public clearAnimation(selector: string, options?: WechatMiniprogram.Component.ClearAnimationOptions, callback?: () => void): void; + public clearAnimation(selector: any, options?: any, callback?: any): void { + return this.superContext.clearAnimation(selector, options, callback); + } + + public getOpenerEventChannel(): WechatMiniprogram.EventChannel { + return this.superContext.getOpenerEventChannel(); + } +} + +/** + * 微信继承的属性 + */ +class WXInstanceProperties< + E extends IAnyTypeObject = IAnyTypeObject, + W extends AnyWXContext = AnyWXContext +> +extends WXInstanceMethods +implements InstanceProperties { + + public override superContext: W; + + constructor(context: W) { + super(context); + this.superContext = context; + } + + public get is(): string { return this.superContext.is }; + + public get route(): string { return this.superContext.route }; + + public get options(): Record { return this.superContext.options }; +} + +class WXILifetime< + E extends IAnyTypeObject = IAnyTypeObject, + W extends AnyWXContext = AnyWXContext +> +extends WXInstanceProperties +implements ILifetime { + + public onLoad(query: Record): void | Promise {}; + + public onShow(): void | Promise {}; + + public onReady(): void | Promise {}; + + public onHide(): void | Promise {}; + + public onUnload(): void | Promise {}; + + public onPullDownRefresh(): void | Promise {}; + + public onReachBottom(): void | Promise {}; + + public onShareAppMessage(options: WechatMiniprogram.Page.IShareAppMessageOption): void | WechatMiniprogram.Page.ICustomShareContent {}; + + public onShareTimeline(): void | WechatMiniprogram.Page.ICustomTimelineContent {}; + + public onPageScroll(options: WechatMiniprogram.Page.IPageScrollOption): void | Promise {}; + + public onTabItemTap(options: WechatMiniprogram.Page.ITabItemTapOption): void | Promise {}; + + public onResize(options: WechatMiniprogram.Page.IResizeOption): void | Promise {}; + + public onAddToFavorites(options: WechatMiniprogram.Page.IAddToFavoritesOption): WechatMiniprogram.Page.IAddToFavoritesContent { + return {}; + }; +} + /** * 页面模组 * @template M 所属 Manager @@ -60,9 +203,10 @@ type Depends> = { class Modular< M extends Manager = Manager, DEP extends Depends = Depends, - E extends Record = Record, - TD extends IAnyTypeObject = IAnyTypeObject> -extends Emitter + E extends IAnyTypeObject = IAnyTypeObject, + TD extends IAnyTypeObject = IAnyTypeObject +> +extends WXILifetime implements WXContext { // [x:string]: any; @@ -95,7 +239,7 @@ implements WXContext { public functionList:Set; /** - * 函数使用的参数列表 + * 模组使用的参数列表 */ public paramList:Set; @@ -103,13 +247,6 @@ implements WXContext { * 命名空间 */ public nameSpace:string; - - // 映射主上下文属性 - public get is():string { return this.context.is }; - public get route():string { return this.context.route }; - public get options():Record { - return this.context.options; - }; /** * 一旦被类被构造,整个页面的全部申明周期将 @@ -120,7 +257,7 @@ implements WXContext { */ public constructor(manager:M, nameSpace:string, depend?: DEP) { - super(); + super(manager.context); // 保存微信上下文 this.manager = manager; @@ -134,7 +271,7 @@ implements WXContext { this.nameSpace = nameSpace; } - public setData(data:Partial, callback?: () => void):void { + public override setData(data:Partial, callback?: () => void):void { if(this.data === void 0) { this.data = {} as TD; @@ -162,76 +299,6 @@ implements WXContext { (this.context as IAnyTypeObject) [`${ this.nameSpace }$${ name }`] = fn.bind(this); } - - //#region 映射微信的继承函数 - - public hasBehavior(behavior: string): void { - return this.context.hasBehavior(behavior); - } - - public triggerEvent(name: string, detail?: DetailType, - options?: WechatMiniprogram.Component.TriggerEventOption): void { - return this.context.triggerEvent(name, detail, options); - } - - public createSelectorQuery(): WechatMiniprogram.SelectorQuery { - return this.context.createSelectorQuery(); - } - - public createIntersectionObserver(options: WechatMiniprogram.CreateIntersectionObserverOption): - WechatMiniprogram.IntersectionObserver { - return this.context.createIntersectionObserver(options); - } - - public selectComponent(selector: string): WechatMiniprogram.Component.TrivialInstance { - return this.context.selectComponent(selector); - } - - public selectAllComponents(selector: string): WechatMiniprogram.Component.TrivialInstance[] { - return this.context.selectAllComponents(selector); - } - - public selectOwnerComponent(): WechatMiniprogram.Component.TrivialInstance { - return this.context.selectOwnerComponent(); - } - - public getRelationNodes(relationKey: string): WechatMiniprogram.Component.TrivialInstance[] { - return this.context.getRelationNodes(relationKey); - } - - public groupSetData(callback?: () => void): void { - return this.context.groupSetData(callback); - } - - public getTabBar(): WechatMiniprogram.Component.TrivialInstance { - return this.context.getTabBar(); - } - - public getPageId(): string { - return this.context.getPageId(); - } - - public animate(selector: string, keyFrames: WechatMiniprogram.Component.KeyFrame[], - duration: number, callback?: () => void): void; - public animate(selector: string, keyFrames: WechatMiniprogram.Component.ScrollTimelineKeyframe[], - duration: number, scrollTimeline: WechatMiniprogram.Component.ScrollTimelineOption): void; - public animate(selector: any, keyFrames: any, duration: any, scrollTimeline?: any): void { - return this.context.animate(selector, keyFrames, duration, scrollTimeline); - } - - public clearAnimation(selector: string, callback: () => void): void; - public clearAnimation(selector: string, options?: WechatMiniprogram.Component.ClearAnimationOptions, - callback?: () => void): void; - public clearAnimation(selector: any, options?: any, callback?: any): void { - return this.context.clearAnimation(selector, options, callback); - } - - public getOpenerEventChannel(): WechatMiniprogram.EventChannel { - return this.context.getOpenerEventChannel(); - } - - //#endregion - } /** @@ -244,19 +311,9 @@ class Manager { * 微信生命周期 */ static readonly WxLifeCycle:(keyof ILifetime)[] = [ - "onShow", - "onReady", - "onHide", - "onUnload", - "onPullDownRefresh", - "onReachBottom", - "onShareAppMessage", - "onShareTimeline", - "onAddToFavorites", - "onPageScroll", - "onResize", - "onTabItemTap" - ] + "onShow", "onReady", "onHide", "onUnload", "onPullDownRefresh", "onReachBottom", + "onShareAppMessage", "onShareTimeline","onAddToFavorites","onPageScroll", "onResize", "onTabItemTap" + ]; /** * 保存页面上下文 @@ -288,9 +345,10 @@ class Manager { * @param depend 模块依赖 * @returns 模块实例 */ - public addModule, M extends Modular> - (mode: new (manager:Manager, nameSpace:string, depend?:DEP) => M, - nameSpace:string, depend?:DEP):M { + public addModule, M extends Modular> ( + mode: new (manager:this, nameSpace:string, depend?:DEP) => M, + nameSpace:string, depend?:DEP + ):M { let mod = new mode(this, nameSpace, depend); this.modules.push(mod); return mod; @@ -300,14 +358,14 @@ class Manager { * 创建指定生命周期的钩子 * @param key 生命周期键值 */ - public creatHooks(key:keyof ILifetime):(...arg: any[]) => Promise { - return async (...arg: any[]) => { + public creatHooks(key: Key): ILifetime[Key] { + let hook = (async (...arg: any[]) => { let hooks:Promise[] = []; for(let i = 0; i < this.modules.length; i++) { - let fn:Function = (this.modules[i] as IAnyTypeObject)[key]; + let fn:Function = this.modules[i][key]; if(fn === void 0) continue; let res: Promise | any = fn.apply(this.modules[i], arg); @@ -340,7 +398,10 @@ class Manager { } return Promise.all(hooks); - } + }); + + // TODO: 此处为,关键位置,容易出错,请再次检查 + return (hook as any); } /** @@ -383,7 +444,7 @@ class Manager { this.context.setData(this.context.data); // 调用全部模块的 onLoad 周期 - let res = this.creatHooks("onLoad")(query as any); + let res = this.creatHooks("onLoad")(query); // 打印每个模块的键值对使用情况 for(let i = 0; i < this.modules.length; i++) { @@ -411,9 +472,9 @@ class Manager { /** * 模块被添加时的标签 */ - public static readonly AddModuleLabel = new LogLabel("addModule", - new LogStyle().setBorder("4px", `1px solid #8600FF`) - .setColor("#FF00FF", "rgba(54, 0, 255, .2)").setBlank("0 5px") + public static readonly AddModuleLabel = new LogLabel( + "addModule", + colorRadio(54, 0, 255) ) /** diff --git a/miniprogram/pages/Timetable/StatusBar.ts b/miniprogram/pages/Timetable/StatusBar.ts index d248d9a..41aa963 100644 --- a/miniprogram/pages/Timetable/StatusBar.ts +++ b/miniprogram/pages/Timetable/StatusBar.ts @@ -4,7 +4,7 @@ import { Logger, LogLabel, LevelLogLabel, LifeCycleLogLabel, NormalStyle } from /** * 在 UI 中显示的数据 */ -type DisplayData = { +interface IDisplayData { /** * 显示内容 @@ -20,8 +20,8 @@ type DisplayData = { /** * 模组事件 */ -type StatusBarEvent = { - m: DisplayData +interface StatusBarEvent { + m: IDisplayData }; /** diff --git a/miniprogram/pages/Timetable/TestCore.ts b/miniprogram/pages/Timetable/TestCore.ts index 2fc8e6c..cc9c7cd 100644 --- a/miniprogram/pages/Timetable/TestCore.ts +++ b/miniprogram/pages/Timetable/TestCore.ts @@ -8,7 +8,7 @@ import { Storage } from "../../core/Storage"; class TestCore extends Modular implements Partial { - public onLoad() { + public override onLoad() { let s = new Storage("test", { a: new Date(),