Add Modular and Manager, merge Logger to core
This commit is contained in:
		
							parent
							
								
									cea68f5145
								
							
						
					
					
						commit
						7fa3a215cf
					
				| @ -0,0 +1,17 @@ | |||||||
|  | 
 | ||||||
|  | page { | ||||||
|  |     background-color: #f4f0f1; | ||||||
|  |     color: rgba(0, 0, 0, .55); | ||||||
|  |     font-weight: 500; | ||||||
|  |     font-size: .9em; | ||||||
|  |     font-family: 'Lucida Sans',  | ||||||
|  |     'Lucida Sans Regular', 'Lucida Grande',  | ||||||
|  |     'Lucida Sans Unicode', 'Geneva', 'Verdana', 'sans-serif'; | ||||||
|  | } | ||||||
|  |    | ||||||
|  | @media (prefers-color-scheme: dark){ | ||||||
|  |     page { | ||||||
|  |       background-color: #1f1f1f; | ||||||
|  |       color: rgba(255, 255, 255, .55); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,5 +1,6 @@ | |||||||
| import { Logger } from "./logger/Logger"; | import { Logger } from "./logger/Logger"; | ||||||
| import { LevelLogLabel } from "./logger/LevelLogLabel"; | import { LevelLogLabel } from "./logger/LevelLogLabel"; | ||||||
|  | import { LifeCycleLogLabel } from "./logger/LifeCycleLogLabel"; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| App<IAppOption>({ | App<IAppOption>({ | ||||||
| @ -13,25 +14,7 @@ App<IAppOption>({ | |||||||
|      * 小程序加载时 |      * 小程序加载时 | ||||||
|      */ |      */ | ||||||
|     onLaunch() { |     onLaunch() { | ||||||
| 
 |         Logger.log("小程序启动...",  | ||||||
|     console.log(Logger.l({val:"hh"},  |         LevelLogLabel.TraceLabel, LifeCycleLogLabel.OnLaunchLabel); | ||||||
|     LevelLogLabel.FatalLabel,LevelLogLabel.ErrorLabel,LevelLogLabel.WarnLabel, |  | ||||||
|     LevelLogLabel.InfoLabel,LevelLogLabel.DebugLabel,LevelLogLabel.TraceLabel |  | ||||||
|     )); |  | ||||||
|      |  | ||||||
|     console.log(Logger.m( |  | ||||||
|         [LevelLogLabel.FatalLabel,LevelLogLabel.ErrorLabel,LevelLogLabel.WarnLabel, |  | ||||||
|             LevelLogLabel.InfoLabel,LevelLogLabel.DebugLabel,LevelLogLabel.TraceLabel], {val:"hh"}, "hh" |  | ||||||
|     )); |  | ||||||
| 
 |  | ||||||
|     console.log(Logger.ll({val:"hh"},  |  | ||||||
|     LevelLogLabel.FatalLabel,LevelLogLabel.ErrorLabel,LevelLogLabel.WarnLabel, |  | ||||||
|     LevelLogLabel.InfoLabel,LevelLogLabel.DebugLabel,LevelLogLabel.TraceLabel |  | ||||||
|     )); |  | ||||||
| 
 |  | ||||||
|     console.log(Logger.lm( |  | ||||||
|         [LevelLogLabel.FatalLabel,LevelLogLabel.ErrorLabel,LevelLogLabel.WarnLabel, |  | ||||||
|             LevelLogLabel.InfoLabel,LevelLogLabel.DebugLabel,LevelLogLabel.TraceLabel], {val:"hh"}, "hh" |  | ||||||
|     )); |  | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
| @ -134,5 +134,94 @@ class LogStyle { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default LogStyle; | /** | ||||||
| export {LogStyle}; |  * 日志标签 | ||||||
|  |  */ | ||||||
|  | class LogLabel { | ||||||
|  |    | ||||||
|  |     /** | ||||||
|  |      * 关键字 | ||||||
|  |      * 用于标识这个类别 | ||||||
|  |      */ | ||||||
|  |     public key:string; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 文字样式 | ||||||
|  |      */ | ||||||
|  |     public style:LogStyle; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 是否受到过滤器影响 | ||||||
|  |      */ | ||||||
|  |     public checked:boolean; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 是否输出 | ||||||
|  |      */ | ||||||
|  |     public display:boolean; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 是否为附件标签 | ||||||
|  |      * 例如回车、时间、代码位置 | ||||||
|  |      */ | ||||||
|  |     public attach:boolean; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @param key 关键字 | ||||||
|  |      * @param style 文字样式 | ||||||
|  |      */ | ||||||
|  |     constructor(key:string, style:LogStyle,  | ||||||
|  |     checked?:boolean, display?:boolean, attach?:boolean) { | ||||||
|  |         this.key = key; | ||||||
|  |         this.style = style; | ||||||
|  |         this.checked = checked ?? true; | ||||||
|  |         this.display = display ?? true; | ||||||
|  |         this.attach = attach ?? false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获得 Logger 输出使用的内容 | ||||||
|  |      */ | ||||||
|  |     public getLoggerOutput():string { | ||||||
|  |         if(!this.display) return ""; | ||||||
|  |         return `%c${ this.key }`; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获得 Text 输出内容 | ||||||
|  |      */ | ||||||
|  |     public getTextOutput():string { | ||||||
|  |         if(!this.display) return ""; | ||||||
|  |         return `[${ this.key }]`; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获得 style 格式化 | ||||||
|  |      */ | ||||||
|  |     public getStyleOutput():string { | ||||||
|  |         if(!this.display) return ""; | ||||||
|  |         return this.style.stringify(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 校验 | ||||||
|  |      */ | ||||||
|  |     public checking(src:RegExp | string):boolean { | ||||||
|  | 
 | ||||||
|  |         let pass = false; | ||||||
|  | 
 | ||||||
|  |         // 关闭校验
 | ||||||
|  |         if(!this.checked) return pass; | ||||||
|  |          | ||||||
|  |         if(src instanceof RegExp) { | ||||||
|  |             pass = (src as RegExp).test(this.key) | ||||||
|  |         } else { | ||||||
|  |             pass = (src as string) === this.key; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return pass; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default LogLabel; | ||||||
|  | export {LogLabel, LogStyle} | ||||||
| @ -1,7 +1,33 @@ | |||||||
| import { LOGGER_FILTER, LOGGER_CONSOLE } from "../utils/Config"; | import { LOGGER_FILTER, LOGGER_CONSOLE } from "./Config"; | ||||||
| import { InternalLogLabel } from "./InternalLogLabel"; | import { StackLogLabel } from "./PresetLogLabel"; | ||||||
| import { LogLabel } from "./LogLabel"; | import { LogLabel } from "./LogLabel"; | ||||||
| import { MultipleLogContent } from "./MultipleLogContent"; | 
 | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 多重内容捆绑 | ||||||
|  |  * 用于 log 输出 | ||||||
|  |  */ | ||||||
|  | class MultipleLogContent<T extends Array<any>> { | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * 输出内容 | ||||||
|  |      */ | ||||||
|  |     private readonly content:T; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * @param content 输出内容 | ||||||
|  |      */ | ||||||
|  |     public constructor(...content:T) { | ||||||
|  |         this.content = content; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获取内容 | ||||||
|  |      */ | ||||||
|  |     public getContent():T { | ||||||
|  |         return this.content; | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 格式化日志输出 |  * 格式化日志输出 | ||||||
| @ -93,7 +119,7 @@ class Logger { | |||||||
|         // TODO: 这里可以添加一些钩子作为中间件处理日志输出
 |         // TODO: 这里可以添加一些钩子作为中间件处理日志输出
 | ||||||
| 
 | 
 | ||||||
|         // 测试是否输出内容
 |         // 测试是否输出内容
 | ||||||
|         if(!Logger.testLog(...labels, ...attachLabel, InternalLogLabel.filterUrlLabel))  |         if(!Logger.testLog(...labels, ...attachLabel, StackLogLabel.filterUrlLabel))  | ||||||
|         return content.getContent(); |         return content.getContent(); | ||||||
| 
 | 
 | ||||||
|         // 计算收集样式
 |         // 计算收集样式
 | ||||||
| @ -113,7 +139,7 @@ class Logger { | |||||||
|     public static log<T>(content:T, ...labels:LogLabel[]):T { |     public static log<T>(content:T, ...labels:LogLabel[]):T { | ||||||
|         return Logger.logBase<Array<T>>( |         return Logger.logBase<Array<T>>( | ||||||
|             new MultipleLogContent<Array<T>>(content), labels,  |             new MultipleLogContent<Array<T>>(content), labels,  | ||||||
|             [InternalLogLabel.fileNameLabel] |             [StackLogLabel.fileNameLabel] | ||||||
|         )[0]; |         )[0]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -130,7 +156,7 @@ class Logger { | |||||||
|     public static logMultiple<T extends Array<any>>(labels:LogLabel[], ...content:T):T { |     public static logMultiple<T extends Array<any>>(labels:LogLabel[], ...content:T):T { | ||||||
|         return Logger.logBase<T>( |         return Logger.logBase<T>( | ||||||
|             new MultipleLogContent<T>(...content), labels,  |             new MultipleLogContent<T>(...content), labels,  | ||||||
|             [InternalLogLabel.fileNameLabel] |             [StackLogLabel.fileNameLabel] | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -147,7 +173,7 @@ class Logger { | |||||||
|     public static logLine<T>(content:T, ...labels:LogLabel[]):T { |     public static logLine<T>(content:T, ...labels:LogLabel[]):T { | ||||||
|         return Logger.logBase<Array<T>>( |         return Logger.logBase<Array<T>>( | ||||||
|             new MultipleLogContent<Array<T>>(content), labels,  |             new MultipleLogContent<Array<T>>(content), labels,  | ||||||
|             [InternalLogLabel.fileNameLabel, InternalLogLabel.blankLabel] |             [StackLogLabel.fileNameLabel, StackLogLabel.blankLabel] | ||||||
|         )[0]; |         )[0]; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -164,7 +190,7 @@ class Logger { | |||||||
|     public static logLineMultiple<T extends Array<any>>(labels:LogLabel[], ...content:T):T { |     public static logLineMultiple<T extends Array<any>>(labels:LogLabel[], ...content:T):T { | ||||||
|         return Logger.logBase<T>( |         return Logger.logBase<T>( | ||||||
|             new MultipleLogContent<T>(...content), labels,  |             new MultipleLogContent<T>(...content), labels,  | ||||||
|             [InternalLogLabel.fileNameLabel, InternalLogLabel.blankLabel] |             [StackLogLabel.fileNameLabel, StackLogLabel.blankLabel] | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
							
								
								
									
										356
									
								
								miniprogram/core/Module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								miniprogram/core/Module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,356 @@ | |||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 自定义对象类型 | ||||||
|  |  */ | ||||||
|  | type IAnyTypeObject<T = any> = { | ||||||
|  |     [x:string]: T; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 微信 Data 类型
 | ||||||
|  | type Data<D> = WechatMiniprogram.Page.Data<D>; | ||||||
|  | 
 | ||||||
|  | // 微信生命周期类型
 | ||||||
|  | type ILifetime = WechatMiniprogram.Page.ILifetime; | ||||||
|  | 
 | ||||||
|  | // 继承的方法
 | ||||||
|  | type InstanceMethods<D> = WechatMiniprogram.Page.InstanceMethods<D>; | ||||||
|  | 
 | ||||||
|  | // 继承的属性
 | ||||||
|  | type InstanceProperties = WechatMiniprogram.Page.InstanceProperties; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 定义微信微信上下文类型 | ||||||
|  |  *  | ||||||
|  |  * @template TD data 结构类型 | ||||||
|  |  * @template TC 用户 MinIn 类型 | ||||||
|  |  *  | ||||||
|  |  * Partial<ILifetime> 可选的微信生命周期 | ||||||
|  |  * Partial<Data<TD>> 可选的 data 结构 | ||||||
|  |  * InstanceMethods<TD> 必选的微信继承方法 | ||||||
|  |  * InstanceProperties 必选的微信继承属性 | ||||||
|  |  */ | ||||||
|  | type WXContext<TD, TC> = Partial<ILifetime> & Partial<Data<TD>>  | ||||||
|  | & InstanceMethods<TD> & InstanceProperties & TC; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 任意的微信上下文 | ||||||
|  |  * 当我们不关心具体是哪个上下文时 | ||||||
|  |  * 使用这个类型 | ||||||
|  |  */ | ||||||
|  | type AnyWXContext = WXContext<IAnyTypeObject, IAnyTypeObject>; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 依赖关系图谱 | ||||||
|  |  * 注意: 这是一个递给类型 | ||||||
|  |  * @template M 限制了所有依赖必须使用同一个 manager | ||||||
|  |  */ | ||||||
|  | type Depends<M extends Manager<AnyWXContext>> = { | ||||||
|  |     [x:string]: Modular<M, Depends<M>>; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 页面模组 | ||||||
|  |  * @template M 所属 Manager | ||||||
|  |  * @template DEP 模组依赖 | ||||||
|  |  * @template TD 模组 Data 类型 | ||||||
|  |  */ | ||||||
|  | class Modular< | ||||||
|  |     M   extends Manager<AnyWXContext> = Manager<AnyWXContext>, | ||||||
|  |     DEP extends Depends<M> = Depends<M>, | ||||||
|  |     TD  extends IAnyTypeObject = IAnyTypeObject> | ||||||
|  | implements WXContext<TD, IAnyTypeObject> { | ||||||
|  | 
 | ||||||
|  |     // [x:string]: any;
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 保存页面上下文 | ||||||
|  |      */ | ||||||
|  |     private manager:M; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 映射 Manager 上下文 | ||||||
|  |      */ | ||||||
|  |     private get context():M["context"] { | ||||||
|  |         return this.manager.context; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 模组依赖 | ||||||
|  |      */ | ||||||
|  |     protected depends?:DEP | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 模组数据 | ||||||
|  |      */ | ||||||
|  |     public data?:TD; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 模组使用的函数列表 | ||||||
|  |      */ | ||||||
|  |     private functionList:Set<string>; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 函数使用的参数列表 | ||||||
|  |      */ | ||||||
|  |     private paramList:Set<string>; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 命名空间 | ||||||
|  |      */ | ||||||
|  |     private nameSpace:string; | ||||||
|  | 
 | ||||||
|  |     // 映射主上下文属性
 | ||||||
|  |     public get is():string { return this.context.is }; | ||||||
|  |     public get route():string { return this.context.route }; | ||||||
|  |     public get options():Record<string, string | undefined> { | ||||||
|  |         return this.context.options; | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * 一旦被类被构造,整个页面的全部申明周期将 | ||||||
|  |      * 由该类实例控制,此后请勿修改任何生命周期函数 | ||||||
|  |      * @param manager 页面上下文 | ||||||
|  |      * @param nameSpace 模组命名空间 | ||||||
|  |      * @param depend 模组依赖 | ||||||
|  |      */ | ||||||
|  |     public constructor(manager:M, nameSpace:string, depend?: DEP) { | ||||||
|  | 
 | ||||||
|  |         // 保存微信上下文
 | ||||||
|  |         this.manager = manager; | ||||||
|  | 
 | ||||||
|  |         // 保存模块依赖
 | ||||||
|  |         this.depends = depend; | ||||||
|  | 
 | ||||||
|  |         // 初始化内部属性
 | ||||||
|  |         this.functionList = new Set<string>(); | ||||||
|  |         this.paramList = new Set<string>(); | ||||||
|  |         this.nameSpace = nameSpace; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public setData(data:Partial<TD>, callback?: () => void):void { | ||||||
|  | 
 | ||||||
|  |         if(this.data === void 0) { | ||||||
|  |             this.data = {} as TD; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let reportData:IAnyTypeObject = {}; | ||||||
|  | 
 | ||||||
|  |         for(let key in data) { | ||||||
|  |             (this.data as IAnyTypeObject)[key] = data[key]; | ||||||
|  |             reportData[`${ this.nameSpace }$${ key }`] = data[key]; | ||||||
|  |             this.paramList.add(key); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return this.context.setData(reportData, callback); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 向上层上下文传递函数 | ||||||
|  |      * @param fn 传递的函数 | ||||||
|  |      * @param name 函数名字 | ||||||
|  |      */ | ||||||
|  |     public setFunc(fn:Function, name:string):void { | ||||||
|  | 
 | ||||||
|  |         this.functionList.add(name); | ||||||
|  |         (this.context as IAnyTypeObject) | ||||||
|  |         [`${ this.nameSpace }$${ name }`] = fn.bind(this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     //#region 映射微信的继承函数
 | ||||||
|  | 
 | ||||||
|  |     public hasBehavior(behavior: string): void { | ||||||
|  |         return this.context.hasBehavior(behavior); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public triggerEvent<DetailType>(name: string, detail?: DetailType,  | ||||||
|  |         options?: WechatMiniprogram.Component.TriggerEventOption): void { | ||||||
|  |         return this.context.triggerEvent<DetailType>(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
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 页面控件 | ||||||
|  |  * 用于管理页面的所有模组 | ||||||
|  |  */ | ||||||
|  | class Manager<WXC extends AnyWXContext = AnyWXContext> { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 微信生命周期 | ||||||
|  |      */ | ||||||
|  |     static readonly WxLifeCycle:(keyof ILifetime)[] = [ | ||||||
|  |         "onShow",  | ||||||
|  |         "onReady",  | ||||||
|  |         "onHide",  | ||||||
|  |         "onUnload",  | ||||||
|  |         "onPullDownRefresh", | ||||||
|  |         "onReachBottom",  | ||||||
|  |         "onShareAppMessage",  | ||||||
|  |         "onShareTimeline", | ||||||
|  |         "onAddToFavorites", | ||||||
|  |         "onPageScroll",  | ||||||
|  |         "onResize",  | ||||||
|  |         "onTabItemTap" | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 保存页面上下文 | ||||||
|  |      */ | ||||||
|  |     public context:WXC; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 一旦被类被构造,整个页面的全部申明周期将 | ||||||
|  |      * 由该类实例控制,此后请勿修改任何生命周期函数 | ||||||
|  |      */ | ||||||
|  |     public constructor(context:WXC) { | ||||||
|  |   | ||||||
|  |         // 保存微信上下文
 | ||||||
|  |         this.context = context; | ||||||
|  |          | ||||||
|  |         // 初始化模组列表
 | ||||||
|  |         this.modules = []; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 模组列表 | ||||||
|  |      */ | ||||||
|  |     public modules:Modular[]; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 添加一个模块 | ||||||
|  |      * @param mode 模块类 | ||||||
|  |      * @param nameSpace 命名空间 | ||||||
|  |      * @param depend 模块依赖 | ||||||
|  |      * @returns 模块实例 | ||||||
|  |      */ | ||||||
|  |     public addModule<DEP extends Depends<this>, M extends Modular<this, DEP>> | ||||||
|  |     (mode: new (manager:Manager<WXC>, nameSpace:string, depend?:DEP) => M,  | ||||||
|  |     nameSpace:string, depend?:DEP):M { | ||||||
|  |         let mod = new mode(this, nameSpace, depend); | ||||||
|  |         this.modules.push(mod); | ||||||
|  |         return mod; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 创建指定生命周期的钩子 | ||||||
|  |      * @param key 生命周期键值 | ||||||
|  |      */ | ||||||
|  |     public creatHooks(key:keyof ILifetime):ILifetime[keyof ILifetime] { | ||||||
|  |         return (...arg: any[]) => { | ||||||
|  | 
 | ||||||
|  |             let hooks:Promise<any>[] = []; | ||||||
|  |             let simple:any; | ||||||
|  | 
 | ||||||
|  |             for(let i = 0; i < this.modules.length; i++) { | ||||||
|  | 
 | ||||||
|  |                 let res: Promise<any> | any =  | ||||||
|  |                 (this.modules[i] as IAnyTypeObject)[key](...arg); | ||||||
|  |                  | ||||||
|  |                 if (res instanceof Promise) { | ||||||
|  |                     hooks.push(res); | ||||||
|  |                      | ||||||
|  |                 } else { | ||||||
|  |                     hooks.push(Promise.resolve(res)); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if ( | ||||||
|  |                     key === "onShareAppMessage" ||  | ||||||
|  |                     key === "onShareTimeline" ||  | ||||||
|  |                     key === "onAddToFavorites" | ||||||
|  |                 ) { | ||||||
|  |                      | ||||||
|  |                     // 如果返回值有特殊含义在处理时进行 MinIn
 | ||||||
|  |                     simple = Object.assign({}, simple, res); | ||||||
|  |                 } else { | ||||||
|  |                     simple = res; | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(hooks.length === 0) return; | ||||||
|  |             if(hooks.length === 1) return simple; | ||||||
|  | 
 | ||||||
|  |             return Promise.all(hooks); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 创建全部生命周期钩子 | ||||||
|  |      */ | ||||||
|  |     public creatAllHooks() { | ||||||
|  |         for(let i = 0; i < Manager.WxLifeCycle.length; i++) { | ||||||
|  |             (this.context as IAnyTypeObject)[Manager.WxLifeCycle[i]] =  | ||||||
|  |             this.creatHooks(Manager.WxLifeCycle[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 加载全部的模块 | ||||||
|  |      */ | ||||||
|  |     public loadAllModule(query:Record<string, string | undefined>) { | ||||||
|  |         this.creatAllHooks(); | ||||||
|  |         let res = this.creatHooks("onLoad")(query as any);  | ||||||
|  |         return res; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { Manager, Modular, AnyWXContext, WXContext, ILifetime} | ||||||
							
								
								
									
										313
									
								
								miniprogram/core/PresetLogLabel.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								miniprogram/core/PresetLogLabel.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,313 @@ | |||||||
|  | import { LogLabel, LogStyle } from "./LogLabel"; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 栈信息 | ||||||
|  |  */ | ||||||
|  | class StackInfo { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 函数名 | ||||||
|  |      */ | ||||||
|  |     public functionName:string | undefined; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * 文件名 | ||||||
|  |      */ | ||||||
|  |     public fileName:string | undefined; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 文件路径 | ||||||
|  |      */ | ||||||
|  |     public url:string | undefined; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 文件名和行号 | ||||||
|  |      */ | ||||||
|  |     public fileNameLine: string | undefined;     | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 设置信息 | ||||||
|  |      * @param functionName 函数名 | ||||||
|  |      * @param fileName 文件名 | ||||||
|  |      * @param url 文件路径 | ||||||
|  |      */ | ||||||
|  |     public setInfo(functionName:string, fileNameLine:string, url:string):StackInfo { | ||||||
|  |         this.functionName = functionName; | ||||||
|  |         this.fileNameLine = fileNameLine; | ||||||
|  |         this.url = url; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 计算文件名 | ||||||
|  |      */ | ||||||
|  |     public calcFileName():string | undefined { | ||||||
|  | 
 | ||||||
|  |         let replaceToTs = this.fileNameLine?.replace(".js", ".ts"); | ||||||
|  |         let matched = replaceToTs?.match(/^(.+\.(js|ts)):\d+:\d+$/); | ||||||
|  | 
 | ||||||
|  |         return matched ? matched[1] : undefined; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 计算路径名 | ||||||
|  |      */ | ||||||
|  |     public calcPathName():string | undefined { | ||||||
|  | 
 | ||||||
|  |         let replaceToTs = this.url?.replace(".js", ".ts"); | ||||||
|  |         let matched = replaceToTs?.match(/^https?:\/\/(\d+\.){3}\d+:\d+\/(.+):\d+:\d+$/); | ||||||
|  | 
 | ||||||
|  |         return matched ? matched[2] : undefined; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获取函数调用栈列表 | ||||||
|  |      */ | ||||||
|  |     public static getCallStack():StackInfo[] { | ||||||
|  | 
 | ||||||
|  |         // 获取堆栈信息
 | ||||||
|  |         let stack:string | undefined = new Error().stack; | ||||||
|  | 
 | ||||||
|  |         if (stack === void 0) return []; | ||||||
|  | 
 | ||||||
|  |         // 去除 Error
 | ||||||
|  |         stack = stack.replace(/^(Error)\s/, ""); | ||||||
|  | 
 | ||||||
|  |         // 获取堆栈信息
 | ||||||
|  |         let stackList:string[] = stack.split(/\n/); | ||||||
|  | 
 | ||||||
|  |         let callStack:StackInfo[] = []; | ||||||
|  | 
 | ||||||
|  |         for(let i = 0; i < stackList.length; i++) { | ||||||
|  | 
 | ||||||
|  |             let matcher = stackList[i].match(/^\s+at\s+(.+)\s(\(.+\))/); | ||||||
|  |             if (matcher === null || matcher.length < 3) continue; | ||||||
|  | 
 | ||||||
|  |             let fileName = matcher[2].match(/.+\/(.+\..+:\d+:\d+)\)/); | ||||||
|  |             if (fileName === null || matcher.length < 2) continue; | ||||||
|  | 
 | ||||||
|  |             callStack.push(new StackInfo().setInfo( | ||||||
|  |                 matcher[1], fileName[1], matcher[2]?.replace(/(\(|\))/g, "") | ||||||
|  |             )) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // console.log(callStack);
 | ||||||
|  | 
 | ||||||
|  |         return callStack; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 排除的 | ||||||
|  |      */ | ||||||
|  |     public static readonly excludeFile:RegExp = /^.*(\\|\/)logger(\\|\/).+\.js:\d+:\d+/; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 获取第一个调用栈 | ||||||
|  |      */ | ||||||
|  |     public static getFirstStack():StackInfo | undefined { | ||||||
|  | 
 | ||||||
|  |         let callStack = this.getCallStack(); | ||||||
|  | 
 | ||||||
|  |         for(let i = 0; i < callStack.length; i++) { | ||||||
|  | 
 | ||||||
|  |             if(!callStack[i].url) continue; | ||||||
|  | 
 | ||||||
|  |             if(!StackInfo.excludeFile.test(callStack[i].url ?? "")) { | ||||||
|  |                 return callStack[i]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 内部预定义的 LogLabel | ||||||
|  |  */ | ||||||
|  | class StackLogLabel { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 堆栈路径样式 | ||||||
|  |      */ | ||||||
|  |     public static readonly normalStyle:LogStyle = new LogStyle() | ||||||
|  |     .setColor("#979797").setBorder("4px", "1px solid #979797").setBlank("0 5px"); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 一个回车 | ||||||
|  |      */ | ||||||
|  |     public static readonly blankLabel = new LogLabel("\n\r",  | ||||||
|  |     new LogStyle(), false, true, true); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 包含文件名和行号的 label | ||||||
|  |      */ | ||||||
|  |     public static get fileNameLabel():LogLabel { | ||||||
|  | 
 | ||||||
|  |         // 获得调用堆栈
 | ||||||
|  |         let stack = StackInfo.getFirstStack(); | ||||||
|  | 
 | ||||||
|  |         return new LogLabel(stack?.calcFileName() ?? "Unknown file name",  | ||||||
|  |         StackLogLabel.normalStyle, false, true, true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 包含 URL 链接的 label | ||||||
|  |      */ | ||||||
|  |     public static get urlLabel():LogLabel { | ||||||
|  | 
 | ||||||
|  |         // 获得调用堆栈
 | ||||||
|  |         let stack = StackInfo.getFirstStack(); | ||||||
|  | 
 | ||||||
|  |         return new LogLabel(stack?.calcPathName() ?? "Unknown url",  | ||||||
|  |         StackLogLabel.normalStyle, false, true, true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 仅仅用来 filter 的 URL 链接的 label | ||||||
|  |      */ | ||||||
|  |     public static get filterUrlLabel():LogLabel { | ||||||
|  | 
 | ||||||
|  |         // 获得调用堆栈
 | ||||||
|  |         let stack = StackInfo.getFirstStack(); | ||||||
|  | 
 | ||||||
|  |         return new LogLabel(stack?.calcPathName() ?? "Unknown url",  | ||||||
|  |         StackLogLabel.normalStyle, true, false, true); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 生成圆角颜色标签样式 | ||||||
|  |  */ | ||||||
|  |  const normalLevelStyleGen = (color:string):LogStyle => { | ||||||
|  |     return new LogStyle().setBorder("4px", `1px solid ${color}`) | ||||||
|  |     .setColor(color).setBlank("0 5px"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 调试等级标签 | ||||||
|  |  */ | ||||||
|  | class LevelLogLabel { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 致命 | ||||||
|  |      */ | ||||||
|  |     static readonly FatalLabel = new LogLabel( | ||||||
|  |         "FATAL", normalLevelStyleGen("#FF00CC") | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 错误 | ||||||
|  |      */ | ||||||
|  |     static readonly ErrorLabel = new LogLabel( | ||||||
|  |         "ERROR", normalLevelStyleGen("#FF0000") | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 警告 | ||||||
|  |      */ | ||||||
|  |     static readonly WarnLabel = new LogLabel( | ||||||
|  |         "WARN", normalLevelStyleGen("#FF9900") | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 消息 | ||||||
|  |      */ | ||||||
|  |     static readonly InfoLabel = new LogLabel( | ||||||
|  |         "INFO", normalLevelStyleGen("#99FF00") | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 调试 | ||||||
|  |      */ | ||||||
|  |     static readonly DebugLabel = new LogLabel( | ||||||
|  |         "DEBUG", normalLevelStyleGen("#00FF99") | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 追踪 | ||||||
|  |      */ | ||||||
|  |     static readonly TraceLabel = new LogLabel( | ||||||
|  |         "TRACE", normalLevelStyleGen("#00CCFF") | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 生成圆角颜色标签样式 | ||||||
|  |  */ | ||||||
|  |  const normalLifeStyleGen = (r:number, g:number, b:number):LogStyle => { | ||||||
|  |     return new LogStyle().setBorder("4px", `1px solid rgb(${ r }, ${ g }, ${ b })`) | ||||||
|  |     .setColor(`rgb(${ r }, ${ g }, ${ b })`, `rgba(${ r }, ${ g }, ${ b }, .1)`) | ||||||
|  |     .setBlank("0 5px"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 生命周期标签 | ||||||
|  |  */ | ||||||
|  | class LifeCycleLogLabel { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 小程序加载时 | ||||||
|  |      */ | ||||||
|  |     static readonly OnLaunchLabel = new LogLabel( | ||||||
|  |         "onLaunch", normalLifeStyleGen(160, 32, 240) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 生命周期函数--监听页面加载 | ||||||
|  |      */ | ||||||
|  |     static readonly OnLoadLabel = new LogLabel( | ||||||
|  |         "onLoad", normalLifeStyleGen(255, 140, 105) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 生命周期函数--监听页面初次渲染完成 | ||||||
|  |      */ | ||||||
|  |     static readonly OnReadyLabel = new LogLabel( | ||||||
|  |         "onReady", normalLifeStyleGen(255, 127, 36) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 生命周期函数--监听页面显示 | ||||||
|  |      */ | ||||||
|  |     static readonly OnShowLabel = new LogLabel( | ||||||
|  |         "onShow", normalLifeStyleGen(255, 215, 0) | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 生命周期函数--监听页面隐藏 | ||||||
|  |      */ | ||||||
|  |     static readonly OnHideLabel = new LogLabel( | ||||||
|  |         "onHide", normalLifeStyleGen(173, 255, 47) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 生命周期函数--监听页面卸载 | ||||||
|  |      */ | ||||||
|  |     static readonly OnUnloadLabel = new LogLabel( | ||||||
|  |         "onUnload", normalLifeStyleGen(127, 255, 212) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 页面相关事件处理函数--监听用户下拉动作 | ||||||
|  |      */ | ||||||
|  |     static readonly OnPullDownRefreshLabel = new LogLabel( | ||||||
|  |         "onPullDownRefresh", normalLifeStyleGen(0, 191, 255) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 页面上拉触底事件的处理函数 | ||||||
|  |      */ | ||||||
|  |     static readonly OnReachBottomLabel = new LogLabel( | ||||||
|  |         "onReachBottom", normalLifeStyleGen(84, 255, 159) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 用户点击右上角分享 | ||||||
|  |      */ | ||||||
|  |     static readonly OnShareAppMessageLabel = new LogLabel( | ||||||
|  |         "onShareAppMessage", normalLifeStyleGen(147, 112, 219) | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { StackInfo, StackLogLabel, LevelLogLabel, LifeCycleLogLabel }; | ||||||
| @ -1,6 +1,5 @@ | |||||||
| // import { Logger } from "../logger/Logger";
 | // import { Logger } from "../logger/Logger";
 | ||||||
| import { LogStyle } from "../logger/LogStyle"; | import { LogStyle, LogLabel } from "./LogLabel"; | ||||||
| import { LogLabel } from "../logger/LogLabel"; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 测试结果 |  * 测试结果 | ||||||
| @ -1,61 +0,0 @@ | |||||||
| import { LogStyle } from "./LogStyle"; |  | ||||||
| import { LogLabel } from "./LogLabel"; |  | ||||||
| import { StackInfo } from "./StackInfo"; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 内部预定义的 LogLabel |  | ||||||
|  */ |  | ||||||
| class InternalLogLabel { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 堆栈路径样式 |  | ||||||
|      */ |  | ||||||
|     public static readonly normalStyle:LogStyle = new LogStyle() |  | ||||||
|     .setColor("#979797").setBorder("4px", "1px solid #979797").setBlank("0 5px"); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 一个回车 |  | ||||||
|      */ |  | ||||||
|     public static readonly blankLabel = new LogLabel("\n\r",  |  | ||||||
|     new LogStyle(), false, true, true); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 包含文件名和行号的 label |  | ||||||
|      */ |  | ||||||
|     public static get fileNameLabel():LogLabel { |  | ||||||
| 
 |  | ||||||
|         // 获得调用堆栈
 |  | ||||||
|         let stack = StackInfo.getFirstStack(); |  | ||||||
| 
 |  | ||||||
|         return new LogLabel(stack?.calcFileName() ?? "Unknown file name",  |  | ||||||
|         InternalLogLabel.normalStyle, false, true, true); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 包含 URL 链接的 label |  | ||||||
|      */ |  | ||||||
|     public static get urlLabel():LogLabel { |  | ||||||
| 
 |  | ||||||
|         // 获得调用堆栈
 |  | ||||||
|         let stack = StackInfo.getFirstStack(); |  | ||||||
| 
 |  | ||||||
|         return new LogLabel(stack?.calcPathName() ?? "Unknown url",  |  | ||||||
|         InternalLogLabel.normalStyle, false, true, true); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 仅仅用来 filter 的 URL 链接的 label |  | ||||||
|      */ |  | ||||||
|     public static get filterUrlLabel():LogLabel { |  | ||||||
| 
 |  | ||||||
|         // 获得调用堆栈
 |  | ||||||
|         let stack = StackInfo.getFirstStack(); |  | ||||||
| 
 |  | ||||||
|         return new LogLabel(stack?.calcPathName() ?? "Unknown url",  |  | ||||||
|         InternalLogLabel.normalStyle, true, false, true); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default InternalLogLabel; |  | ||||||
| export {InternalLogLabel}; |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| import { LogStyle } from "./LogStyle"; |  | ||||||
| import { LogLabel } from "./LogLabel"; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 生成圆角颜色标签样式 |  | ||||||
|  */ |  | ||||||
| const normalStyleGen = (color:string):LogStyle => { |  | ||||||
|     return new LogStyle().setBorder("4px", `1px solid ${color}`) |  | ||||||
|     .setColor(color).setBlank("0 5px"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 调试等级标签 |  | ||||||
|  */ |  | ||||||
| class LevelLogLabel { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 致命 |  | ||||||
|      */ |  | ||||||
|     static readonly FatalLabel = new LogLabel( |  | ||||||
|         "FATAL", normalStyleGen("#FF00CC") |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 错误 |  | ||||||
|      */ |  | ||||||
|     static readonly ErrorLabel = new LogLabel( |  | ||||||
|         "ERROR", normalStyleGen("#FF0000") |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 警告 |  | ||||||
|      */ |  | ||||||
|     static readonly WarnLabel = new LogLabel( |  | ||||||
|         "WARN", normalStyleGen("#FF9900") |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 消息 |  | ||||||
|      */ |  | ||||||
|     static readonly InfoLabel = new LogLabel( |  | ||||||
|         "INFO", normalStyleGen("#99FF00") |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 调试 |  | ||||||
|      */ |  | ||||||
|     static readonly DebugLabel = new LogLabel( |  | ||||||
|         "DEBUG", normalStyleGen("#00FF99") |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 追踪 |  | ||||||
|      */ |  | ||||||
|     static readonly TraceLabel = new LogLabel( |  | ||||||
|         "TRACE", normalStyleGen("#00CCFF") |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default LevelLogLabel; |  | ||||||
| export { LevelLogLabel }; |  | ||||||
| @ -1,83 +0,0 @@ | |||||||
| import { LogStyle } from "./LogStyle"; |  | ||||||
| import { LogLabel } from "./LogLabel"; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 生成圆角颜色标签样式 |  | ||||||
|  */ |  | ||||||
| const normalStyleGen = (r:number, g:number, b:number):LogStyle => { |  | ||||||
|     return new LogStyle().setBorder("4px", `1px solid rgb(${ r }, ${ g }, ${ b })`) |  | ||||||
|     .setColor(`rgb(${ r }, ${ g }, ${ b })`, `rgba(${ r }, ${ g }, ${ b }, .1)`) |  | ||||||
|     .setBlank("0 5px"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 生命周期标签 |  | ||||||
|  */ |  | ||||||
| class LifeCycleLogLabel { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 小程序加载时 |  | ||||||
|      */ |  | ||||||
|     static readonly OnLaunchLabel = new LogLabel( |  | ||||||
|         "onLaunch", normalStyleGen(160, 32, 240) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 生命周期函数--监听页面加载 |  | ||||||
|      */ |  | ||||||
|     static readonly OnLoadLabel = new LogLabel( |  | ||||||
|         "onLoad", normalStyleGen(255, 140, 105) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 生命周期函数--监听页面初次渲染完成 |  | ||||||
|      */ |  | ||||||
|     static readonly OnReadyLabel = new LogLabel( |  | ||||||
|         "onReady", normalStyleGen(255, 127, 36) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 生命周期函数--监听页面显示 |  | ||||||
|      */ |  | ||||||
|     static readonly OnShowLabel = new LogLabel( |  | ||||||
|         "onShow", normalStyleGen(255, 215, 0) |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 生命周期函数--监听页面隐藏 |  | ||||||
|      */ |  | ||||||
|     static readonly OnHideLabel = new LogLabel( |  | ||||||
|         "onHide", normalStyleGen(173, 255, 47) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 生命周期函数--监听页面卸载 |  | ||||||
|      */ |  | ||||||
|     static readonly OnUnloadLabel = new LogLabel( |  | ||||||
|         "onUnload", normalStyleGen(127, 255, 212) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 页面相关事件处理函数--监听用户下拉动作 |  | ||||||
|      */ |  | ||||||
|     static readonly OnPullDownRefreshLabel = new LogLabel( |  | ||||||
|         "onPullDownRefresh", normalStyleGen(0, 191, 255) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 页面上拉触底事件的处理函数 |  | ||||||
|      */ |  | ||||||
|     static readonly OnReachBottomLabel = new LogLabel( |  | ||||||
|         "onReachBottom", normalStyleGen(84, 255, 159) |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 用户点击右上角分享 |  | ||||||
|      */ |  | ||||||
|     static readonly OnShareAppMessageLabel = new LogLabel( |  | ||||||
|         "onShareAppMessage", normalStyleGen(147, 112, 219) |  | ||||||
|     ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default LifeCycleLogLabel; |  | ||||||
| export { LifeCycleLogLabel }; |  | ||||||
| @ -1,93 +0,0 @@ | |||||||
| import { LogStyle } from "./LogStyle"; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 日志标签 |  | ||||||
|  */ |  | ||||||
| class LogLabel { |  | ||||||
|    |  | ||||||
|     /** |  | ||||||
|      * 关键字 |  | ||||||
|      * 用于标识这个类别 |  | ||||||
|      */ |  | ||||||
|     public key:string; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 文字样式 |  | ||||||
|      */ |  | ||||||
|     public style:LogStyle; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 是否受到过滤器影响 |  | ||||||
|      */ |  | ||||||
|     public checked:boolean; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 是否输出 |  | ||||||
|      */ |  | ||||||
|     public display:boolean; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 是否为附件标签 |  | ||||||
|      * 例如回车、时间、代码位置 |  | ||||||
|      */ |  | ||||||
|     public attach:boolean; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @param key 关键字 |  | ||||||
|      * @param style 文字样式 |  | ||||||
|      */ |  | ||||||
|     constructor(key:string, style:LogStyle,  |  | ||||||
|     checked?:boolean, display?:boolean, attach?:boolean) { |  | ||||||
|         this.key = key; |  | ||||||
|         this.style = style; |  | ||||||
|         this.checked = checked ?? true; |  | ||||||
|         this.display = display ?? true; |  | ||||||
|         this.attach = attach ?? false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获得 Logger 输出使用的内容 |  | ||||||
|      */ |  | ||||||
|     public getLoggerOutput():string { |  | ||||||
|         if(!this.display) return ""; |  | ||||||
|         return `%c${ this.key }`; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获得 Text 输出内容 |  | ||||||
|      */ |  | ||||||
|     public getTextOutput():string { |  | ||||||
|         if(!this.display) return ""; |  | ||||||
|         return `[${ this.key }]`; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获得 style 格式化 |  | ||||||
|      */ |  | ||||||
|     public getStyleOutput():string { |  | ||||||
|         if(!this.display) return ""; |  | ||||||
|         return this.style.stringify(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 校验 |  | ||||||
|      */ |  | ||||||
|     public checking(src:RegExp | string):boolean { |  | ||||||
| 
 |  | ||||||
|         let pass = false; |  | ||||||
| 
 |  | ||||||
|         // 关闭校验
 |  | ||||||
|         if(!this.checked) return pass; |  | ||||||
|          |  | ||||||
|         if(src instanceof RegExp) { |  | ||||||
|             pass = (src as RegExp).test(this.key) |  | ||||||
|         } else { |  | ||||||
|             pass = (src as string) === this.key; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return pass; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default LogLabel; |  | ||||||
| export {LogLabel} |  | ||||||
| @ -1,29 +0,0 @@ | |||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 多重内容捆绑 |  | ||||||
|  * 用于 log 输出 |  | ||||||
|  */ |  | ||||||
| class MultipleLogContent<T extends Array<any>> { |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 输出内容 |  | ||||||
|      */ |  | ||||||
|     private readonly content:T; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * @param content 输出内容 |  | ||||||
|      */ |  | ||||||
|     public constructor(...content:T) { |  | ||||||
|         this.content = content; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获取内容 |  | ||||||
|      */ |  | ||||||
|     public getContent():T { |  | ||||||
|         return this.content; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default MultipleLogContent; |  | ||||||
| export { MultipleLogContent }; |  | ||||||
| @ -1,124 +0,0 @@ | |||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 栈信息 |  | ||||||
|  */ |  | ||||||
| class StackInfo { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 函数名 |  | ||||||
|      */ |  | ||||||
|     public functionName:string | undefined; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * 文件名 |  | ||||||
|      */ |  | ||||||
|     public fileName:string | undefined; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 文件路径 |  | ||||||
|      */ |  | ||||||
|     public url:string | undefined; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 文件名和行号 |  | ||||||
|      */ |  | ||||||
|     public fileNameLine: string | undefined;     |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 设置信息 |  | ||||||
|      * @param functionName 函数名 |  | ||||||
|      * @param fileName 文件名 |  | ||||||
|      * @param url 文件路径 |  | ||||||
|      */ |  | ||||||
|     public setInfo(functionName:string, fileNameLine:string, url:string):StackInfo { |  | ||||||
|         this.functionName = functionName; |  | ||||||
|         this.fileNameLine = fileNameLine; |  | ||||||
|         this.url = url; |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 计算文件名 |  | ||||||
|      */ |  | ||||||
|     public calcFileName():string | undefined { |  | ||||||
| 
 |  | ||||||
|         let replaceToTs = this.fileNameLine?.replace(".js", ".ts"); |  | ||||||
|         let matched = replaceToTs?.match(/^(.+\.(js|ts)):\d+:\d+$/); |  | ||||||
| 
 |  | ||||||
|         return matched ? matched[1] : undefined; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 计算路径名 |  | ||||||
|      */ |  | ||||||
|     public calcPathName():string | undefined { |  | ||||||
| 
 |  | ||||||
|         let replaceToTs = this.url?.replace(".js", ".ts"); |  | ||||||
|         let matched = replaceToTs?.match(/^https?:\/\/(\d+\.){3}\d+:\d+\/(.+):\d+:\d+$/); |  | ||||||
| 
 |  | ||||||
|         return matched ? matched[2] : undefined; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获取函数调用栈列表 |  | ||||||
|      */ |  | ||||||
|     public static getCallStack():StackInfo[] { |  | ||||||
| 
 |  | ||||||
|         // 获取堆栈信息
 |  | ||||||
|         let stack:string | undefined = new Error().stack; |  | ||||||
| 
 |  | ||||||
|         if (stack === void 0) return []; |  | ||||||
| 
 |  | ||||||
|         // 去除 Error
 |  | ||||||
|         stack = stack.replace(/^(Error)\s/, ""); |  | ||||||
| 
 |  | ||||||
|         // 获取堆栈信息
 |  | ||||||
|         let stackList:string[] = stack.split(/\n/); |  | ||||||
| 
 |  | ||||||
|         let callStack:StackInfo[] = []; |  | ||||||
| 
 |  | ||||||
|         for(let i = 0; i < stackList.length; i++) { |  | ||||||
| 
 |  | ||||||
|             let matcher = stackList[i].match(/^\s+at\s+(.+)\s(\(.+\))/); |  | ||||||
|             if (matcher === null || matcher.length < 3) continue; |  | ||||||
| 
 |  | ||||||
|             let fileName = matcher[2].match(/.+\/(.+\..+:\d+:\d+)\)/); |  | ||||||
|             if (fileName === null || matcher.length < 2) continue; |  | ||||||
| 
 |  | ||||||
|             callStack.push(new StackInfo().setInfo( |  | ||||||
|                 matcher[1], fileName[1], matcher[2]?.replace(/(\(|\))/g, "") |  | ||||||
|             )) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // console.log(callStack);
 |  | ||||||
| 
 |  | ||||||
|         return callStack; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 排除的 |  | ||||||
|      */ |  | ||||||
|     public static readonly excludeFile:RegExp = /^.*(\\|\/)logger(\\|\/).+\.js:\d+:\d+/; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获取第一个调用栈 |  | ||||||
|      */ |  | ||||||
|     public static getFirstStack():StackInfo | undefined { |  | ||||||
| 
 |  | ||||||
|         let callStack = this.getCallStack(); |  | ||||||
| 
 |  | ||||||
|         for(let i = 0; i < callStack.length; i++) { |  | ||||||
| 
 |  | ||||||
|             if(!callStack[i].url) continue; |  | ||||||
| 
 |  | ||||||
|             if(!StackInfo.excludeFile.test(callStack[i].url ?? "")) { |  | ||||||
|                 return callStack[i]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default StackInfo; |  | ||||||
| export { StackInfo }; |  | ||||||
| @ -1,3 +1,4 @@ | |||||||
| { | { | ||||||
|   "usingComponents": {} |   "usingComponents": {}, | ||||||
|  |   "navigationStyle": "custom" | ||||||
| } | } | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | // view.status-bar { | ||||||
|  | //     // background-color: antiquewhite; | ||||||
|  | // } | ||||||
| @ -1,66 +1,68 @@ | |||||||
| // pages/Timetable/Timetable.ts
 | import { Logger } from "../../core/Logger"; | ||||||
|  | import { LevelLogLabel, LifeCycleLogLabel } from "../../core/PresetLogLabel"; | ||||||
|  | import { Manager, Modular, AnyWXContext, ILifetime } from "../../core/Module"; | ||||||
|  | 
 | ||||||
| Page({ | Page({ | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|    * 页面的初始数据 |      * 课程表页面加载 | ||||||
|      */ |      */ | ||||||
|   data: { |     onLoad: async function () { | ||||||
| 
 | 
 | ||||||
|   }, |         this; | ||||||
| 
 | 
 | ||||||
|   /** |         let manager = new Manager(this); | ||||||
|    * 生命周期函数--监听页面加载 |         let m1 = manager.addModule(M1, "m1"); | ||||||
|    */ |         let m2 = manager.addModule(M2, "m2", {m1}); | ||||||
|   onLoad() { |  | ||||||
| 
 | 
 | ||||||
|   }, |         let manager2 = new Manager(this); | ||||||
|  |         let m22 = manager.addModule(M2, "m1", {m1}); | ||||||
| 
 | 
 | ||||||
|   /** |         this.setData; | ||||||
|    * 生命周期函数--监听页面初次渲染完成 |  | ||||||
|    */ |  | ||||||
|   onReady() { |  | ||||||
| 
 | 
 | ||||||
|   }, |         Logger.log("课程表 (Timetable) 页面加载...",  | ||||||
|  |         LevelLogLabel.TraceLabel, LifeCycleLogLabel.OnLoadLabel); | ||||||
| 
 | 
 | ||||||
|   /** |         let systemInfo = wx.getSystemInfoSync(); | ||||||
|    * 生命周期函数--监听页面显示 |  | ||||||
|    */ |  | ||||||
|   onShow() { |  | ||||||
|   |   | ||||||
|   }, |         //状态栏高度
 | ||||||
|  |         let statusBarHeight = Number(systemInfo.statusBarHeight); | ||||||
|          |          | ||||||
|   /** |         let menu = wx.getMenuButtonBoundingClientRect() | ||||||
|    * 生命周期函数--监听页面隐藏 |  | ||||||
|    */ |  | ||||||
|   onHide() { |  | ||||||
|          |          | ||||||
|   }, |         //导航栏高度
 | ||||||
|  |         let navBarHeight = menu.height + (menu.top - statusBarHeight) * 2 | ||||||
|          |          | ||||||
|   /** |         //状态栏加导航栏高度
 | ||||||
|    * 生命周期函数--监听页面卸载 |         let navStatusBarHeight = statusBarHeight + menu.height + (menu.top - statusBarHeight) * 2 | ||||||
|    */ |  | ||||||
|   onUnload() { |  | ||||||
|          |          | ||||||
|   }, |         console.log('状态栏高度',statusBarHeight) | ||||||
|          |          | ||||||
|   /** |         console.log('导航栏高度',navBarHeight) | ||||||
|    * 页面相关事件处理函数--监听用户下拉动作 |  | ||||||
|    */ |  | ||||||
|   onPullDownRefresh() { |  | ||||||
|          |          | ||||||
|   }, |         console.log('状态栏加导航栏高度',navStatusBarHeight) | ||||||
| 
 | 
 | ||||||
|   /** |         this.setData({barh: navStatusBarHeight}); | ||||||
|    * 页面上拉触底事件的处理函数 |  | ||||||
|    */ |  | ||||||
|   onReachBottom() { |  | ||||||
| 
 |  | ||||||
|   }, |  | ||||||
| 
 |  | ||||||
|   /** |  | ||||||
|    * 用户点击右上角分享 |  | ||||||
|    */ |  | ||||||
|   onShareAppMessage() { |  | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  |    | ||||||
| }) | }) | ||||||
|  | 
 | ||||||
|  | class M1<M extends Manager> extends Modular<M, {}> { | ||||||
|  | 
 | ||||||
|  |     public onLoad(){ | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class M2<M extends Manager> extends Modular<M, {m1:M1<M>}> { | ||||||
|  |      | ||||||
|  |     public onLoad() { | ||||||
|  |         // this.setData();
 | ||||||
|  |     } | ||||||
|  |     // hhh(){
 | ||||||
|  |          | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     hh(){} | ||||||
|  | } | ||||||
| @ -1 +1,3 @@ | |||||||
|  | <view class="status-bar" style="height:{{barh}}px"></view> | ||||||
|  | 
 | ||||||
| <text>pages/Timetable/Timetable.wxml</text> | <text>pages/Timetable/Timetable.wxml</text> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user