diff --git a/.gitignore b/.gitignore index ef89d07..df99ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,9 @@ $RECYCLE.BIN/ # Node.js node_modules/ -.idea \ No newline at end of file + +# wxss +*.wxss + +# idea +.idea diff --git a/miniprogram/utils/Config.ts b/miniprogram/Config.ts similarity index 100% rename from miniprogram/utils/Config.ts rename to miniprogram/Config.ts diff --git a/miniprogram/app.ts b/miniprogram/app.ts index b7d0c2c..06eab41 100644 --- a/miniprogram/app.ts +++ b/miniprogram/app.ts @@ -1,27 +1,36 @@ -import {Logger} from "./utils/Logger"; -import * as label from "./utils/LogLabel"; +import { Logger, LevelLogLabel } from "./logger/index"; App({ - /** - * 全局数据 - */ - globalData: {}, + /** + * 全局数据 + */ + globalData: {}, - /** - * 小程序加载时 - */ - onLaunch() { + /** + * 小程序加载时 + */ + onLaunch() { - Logger.log("hh", - label.FatalLabel,label.ErrorLabel,label.WarnLabel, - label.InfoLabel,label.DebugLabel,label.TraceLabel - ); + console.log(Logger.l({val:"hh"}, + LevelLogLabel.FatalLabel,LevelLogLabel.ErrorLabel,LevelLogLabel.WarnLabel, + LevelLogLabel.InfoLabel,LevelLogLabel.DebugLabel,LevelLogLabel.TraceLabel + )); - Logger.logM( - [label.FatalLabel,label.ErrorLabel,label.WarnLabel, - label.InfoLabel,label.DebugLabel,label.TraceLabel], "hh" - ); + 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" + )); } }) \ No newline at end of file diff --git a/miniprogram/logger/InternalLogLabel.ts b/miniprogram/logger/InternalLogLabel.ts new file mode 100644 index 0000000..82c690a --- /dev/null +++ b/miniprogram/logger/InternalLogLabel.ts @@ -0,0 +1,61 @@ +import { LogStyle } from "./LogStyle"; +import { LogLabel } from "./LogLabel"; +import { StackInfo } from "./StackInfo"; + +/** + * 内部预定义的 LogLabel + */ +class InternalLogLabel { + + /** + * 堆栈路径样式 + */ + public static readonly normalStyle:LogStyle = new LogStyle() + .setColor("#CCCCCC").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?.fileName ?? "Unknown file name", + InternalLogLabel.normalStyle, false, true, true); + } + + /** + * 包含 URL 链接的 label + */ + public static get urlLabel():LogLabel { + + // 获得调用堆栈 + let stack = StackInfo.getFirstStack(); + + return new LogLabel(stack?.url ?? "Unknown url", + InternalLogLabel.normalStyle, false, true, true); + } + + /** + * 仅仅用来 filter 的 URL 链接的 label + */ + public static get filterUrlLabel():LogLabel { + + // 获得调用堆栈 + let stack = StackInfo.getFirstStack(); + + return new LogLabel(stack?.url ?? "Unknown url", + InternalLogLabel.normalStyle, true, false, true); + } + +} + +export default InternalLogLabel; +export {InternalLogLabel}; \ No newline at end of file diff --git a/miniprogram/logger/LevelLogLabel.ts b/miniprogram/logger/LevelLogLabel.ts new file mode 100644 index 0000000..7d8fb68 --- /dev/null +++ b/miniprogram/logger/LevelLogLabel.ts @@ -0,0 +1,61 @@ +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 }; \ No newline at end of file diff --git a/miniprogram/logger/LogLabel.ts b/miniprogram/logger/LogLabel.ts new file mode 100644 index 0000000..4f3253c --- /dev/null +++ b/miniprogram/logger/LogLabel.ts @@ -0,0 +1,93 @@ +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} \ No newline at end of file diff --git a/miniprogram/logger/LogStyle.ts b/miniprogram/logger/LogStyle.ts new file mode 100644 index 0000000..30990ee --- /dev/null +++ b/miniprogram/logger/LogStyle.ts @@ -0,0 +1,138 @@ + +/** + * 调试输出样式 + */ +class LogStyle { + + /** + * 日志文字颜色 + */ + private color:string | undefined; + + /** + * 日志背景颜色 + */ + private backgroundColor:string | undefined; + + /** + * 日志文字粗细 + */ + private weight:string | undefined; + + /** + * 日志文字大小 + */ + private size:string | undefined; + + /** + * 日志文字字体 + */ + private family:string | undefined; + + /** + * 日志文字圆角 + */ + private borderRadius:string | undefined; + + /** + * 日志文字边框 + */ + private border:string | undefined; + + /** + * 日志文字外边距 + */ + private margin:string | undefined; + + /** + * 日志文字内边距 + */ + private padding:string | undefined; + + /** + * 设置颜色 + * @param color 日志文字颜色 + * @param backgroundColor 日志背景颜色 + */ + public setColor(color?:string, backgroundColor?:string):LogStyle { + this.color = color ?? this.color; + this.backgroundColor = backgroundColor ?? this.backgroundColor; + return this; + } + + /** + * 设置边框 + * @param borderRadius 日志文字圆角 + * @param border 日志文字边框 + */ + public setBorder(borderRadius?:string, border?:string):LogStyle { + this.borderRadius = borderRadius ?? this.borderRadius; + this.border = border ?? this.border; + return this; + } + + /** + * 设置文字 + * @param weight 日志文字粗细 + * @param family 日志文字字体 + */ + public setFont(weight?:string, family?:string):LogStyle { + this.weight = weight ?? this.weight; + this.family = family ?? this.family; + return this; + } + + /** + * 设置文字大小 + * @param size 日志文字大小 + */ + public setSize(size?:string):LogStyle { + this.size = size ?? this.size; + return this; + } + + /** + * 设置内边距外边距 + * @param padding 内边距 + * @param margin 外边距 + */ + public setBlank(padding?:string, margin?:string):LogStyle { + this.padding = padding ?? this.padding; + this.margin = margin ?? this.margin; + return this; + } + + /** + * 字符化转义样式 + */ + public stringify():string { + let stringArr:string[] = []; + + this.color && stringArr.push(`color:${ this.color }`); + this.backgroundColor && stringArr.push(`background-color:${ this.backgroundColor }`); + this.weight && stringArr.push(`font-weight:${ this.weight }`); + this.family && stringArr.push(`font-family:${ this.family }`); + this.borderRadius && stringArr.push(`border-radius:${ this.borderRadius }`); + this.border && stringArr.push(`border:${ this.border }`); + this.size && stringArr.push(`font-size:${ this.size }`); + this.padding && stringArr.push(`padding:${ this.padding }`); + this.margin && stringArr.push(`margin:${ this.margin }`); + + return stringArr.join(";"); + } + + /** + * 克隆一个新的 LogStyle + */ + public clone():LogStyle { + return new LogStyle() + .setColor(this.color, this.backgroundColor) + .setBorder(this.borderRadius, this.border) + .setFont(this.weight, this.family) + .setBlank(this.padding, this.margin) + .setSize(this.size) + } +} + +export default LogStyle; +export {LogStyle}; \ No newline at end of file diff --git a/miniprogram/logger/Logger.ts b/miniprogram/logger/Logger.ts new file mode 100644 index 0000000..2a5a482 --- /dev/null +++ b/miniprogram/logger/Logger.ts @@ -0,0 +1,179 @@ +import {LOGGER_CONSOLE, LOGGER_FILTER} from "../Config"; +import { InternalLogLabel } from "./InternalLogLabel"; +import { LogLabel } from "./LogLabel"; +import { MultipleLogContent } from "./MultipleLogContent"; + +/** + * 格式化日志输出 + */ +class Logger { + + /** + * 标签过滤 + */ + public static filterLog(filter:Array, labels:LogLabel[]):boolean { + + let passNum:number = 0; + + for(let i = 0; i < filter.length; i++) { + + let pass:boolean = false; + for(let j = 0; j < labels.length; j++) { + + pass = labels[j].checking(filter[i]); + if(pass) break; + } + + if(pass) passNum ++; + } + + return passNum === filter.length; + } + + /** + * 检测是否应该输出 + * @param labels 使用标签 + */ + public static testLog(...labels:LogLabel[]):boolean { + + if(!LOGGER_CONSOLE) return false; + + let isLogging = false; + for(let i = 0; i < LOGGER_FILTER.length; i++) { + + // 判断是否进行输出 + isLogging = Logger.filterLog(LOGGER_FILTER[i], labels); + + if(isLogging) break; + } + + return isLogging; + } + + /** + * 收集计算样式 + * @param labels 使用标签 + */ + public static calcStyle(...labels:LogLabel[]):[string[], string[]] { + + // 过滤出需要显示的 Labels + let labelsNeedRender:LogLabel[] = labels.filter((label:LogLabel)=>{ + return label.display + }); + + let consoleLabels:string[] = []; + let consoleStyles:string[] = []; + + // 放置标签 + for(let i = 0; i < labelsNeedRender.length; i++) { + consoleLabels.push(labels[i].getLoggerOutput()); + + if (i !== ( labelsNeedRender.length - 1)) + consoleLabels.push("%c "); + + consoleStyles.push(labelsNeedRender[i].getStyleOutput()); + + if (i !== ( labelsNeedRender.length - 1)) + consoleStyles.push(""); + } + + return [consoleLabels, consoleStyles]; + } + + /** + * 基础调试输出 + * 其他的 Log 函数都是基于此封装 + * @param content 输出内容 + * @param label 使用标签 + * @param attachLabel 附加标签 + */ + public static logBase> + (content:MultipleLogContent, labels:LogLabel[], attachLabel:LogLabel[] = []):T { + + // TODO: 这里可以添加一些钩子作为中间件处理日志输出 + + // 测试是否输出内容 + if(!Logger.testLog(...labels, ...attachLabel, InternalLogLabel.filterUrlLabel)) + return content.getContent(); + + // 计算收集样式 + let [consoleLabels, consoleStyles]= Logger.calcStyle(...labels, ...attachLabel); + + // 调试输出 + console.log(consoleLabels.join(""), ...consoleStyles, ...content.getContent()); + + return content.getContent(); + } + + /** + * 调试输出 + * @param content 输出内容 + * @param label 使用标签 + */ + public static log(content:T, ...labels:LogLabel[]):T { + return Logger.logBase>( + new MultipleLogContent>(content), labels, + [InternalLogLabel.fileNameLabel] + )[0]; + } + + /** + * 函数 Logger.log 的别名 + */ + public static l:typeof Logger.log = Logger.log; + + /** + * 多重调试输出 + * @param labels 输出内容 + * @param content 使用标签 + */ + public static logMultiple>(labels:LogLabel[], ...content:T):T { + return Logger.logBase( + new MultipleLogContent(...content), labels, + [InternalLogLabel.fileNameLabel] + ); + } + + /** + * 函数 Logger.logMultiple 的别名 + */ + public static m:typeof Logger.logMultiple = Logger.logMultiple; + + /** + * 在下一行调试输出 + * @param content 输出内容 + * @param label 使用标签 + */ + public static logLine(content:T, ...labels:LogLabel[]):T { + return Logger.logBase>( + new MultipleLogContent>(content), labels, + [InternalLogLabel.urlLabel, InternalLogLabel.blankLabel] + )[0]; + } + + /** + * 函数 Logger.logMultiple 的别名 + */ + public static ll:typeof Logger.logLine = Logger.logLine; + + /** + * 在下一行多重调试输出 + * @param labels 输出内容 + * @param content 使用标签 + */ + public static logLineMultiple>(labels:LogLabel[], ...content:T):T { + return Logger.logBase( + new MultipleLogContent(...content), labels, + [InternalLogLabel.urlLabel, InternalLogLabel.blankLabel] + ); + } + + /** + * 函数 Logger.logLineMultiple 的别名 + */ + public static lm:typeof Logger.logLineMultiple = Logger.logLineMultiple; + +} + +export default Logger; +export { Logger }; \ No newline at end of file diff --git a/miniprogram/logger/MultipleLogContent.ts b/miniprogram/logger/MultipleLogContent.ts new file mode 100644 index 0000000..87dd610 --- /dev/null +++ b/miniprogram/logger/MultipleLogContent.ts @@ -0,0 +1,29 @@ + +/** + * 多重内容捆绑 + * 用于 log 输出 + */ +class MultipleLogContent> { + + /** + * 输出内容 + */ + private readonly content:T; + + /** + * @param content 输出内容 + */ + public constructor(...content:T) { + this.content = content; + } + + /** + * 获取内容 + */ + public getContent():T { + return this.content; + } +} + +export default MultipleLogContent; +export { MultipleLogContent }; \ No newline at end of file diff --git a/miniprogram/logger/StackInfo.ts b/miniprogram/logger/StackInfo.ts new file mode 100644 index 0000000..4b6d06d --- /dev/null +++ b/miniprogram/logger/StackInfo.ts @@ -0,0 +1,91 @@ + +/** + * 栈信息 + */ +class StackInfo { + + /** + * 函数名 + */ + public functionName:string | undefined; + + /** + * 文件名 + */ + public fileName:string | undefined; + + /** + * 文件路径 + */ + public url:string | undefined; + + public setInfo(functionName:string, fileName:string, url:string):StackInfo { + this.functionName = functionName; + this.fileName = fileName; + this.url = url; + return this; + } + + /** + * 获取函数调用栈列表 + */ + 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].fileName) continue; + + if(!StackInfo.excludeFile.test(callStack[i].fileName ?? "")) { + return callStack[i]; + } + } + + return; + } +} + +export default StackInfo; +export { StackInfo }; \ No newline at end of file diff --git a/miniprogram/logger/index.ts b/miniprogram/logger/index.ts new file mode 100644 index 0000000..6c169a9 --- /dev/null +++ b/miniprogram/logger/index.ts @@ -0,0 +1,11 @@ +import Logger from "./Logger"; + +export default Logger; +export { Logger }; + +export { InternalLogLabel } from "./InternalLogLabel"; +export { MultipleLogContent } from "./MultipleLogContent"; +export { LevelLogLabel } from "./LevelLogLabel"; +export { LogLabel } from "./LogLabel"; +export { LogStyle } from "./LogStyle"; +export { StackInfo } from "./StackInfo"; \ No newline at end of file diff --git a/miniprogram/pages/Account/Account.wxss b/miniprogram/pages/Account/Account.wxss deleted file mode 100644 index baf3871..0000000 --- a/miniprogram/pages/Account/Account.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/Account/Account.wxss */ \ No newline at end of file diff --git a/miniprogram/pages/Information/Information.wxss b/miniprogram/pages/Information/Information.wxss deleted file mode 100644 index d13379a..0000000 --- a/miniprogram/pages/Information/Information.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/Information/Information.wxss */ \ No newline at end of file diff --git a/miniprogram/utils/LogLabel.ts b/miniprogram/utils/LogLabel.ts deleted file mode 100644 index d4d8b51..0000000 --- a/miniprogram/utils/LogLabel.ts +++ /dev/null @@ -1,43 +0,0 @@ -import {LogLabel, LogStyle} from "./Logger"; - -// 成功 -export const SuccessLabel = new LogLabel( - "SUCCESS", new LogStyle().setColor("#FFFFFF", "#EE113D").setBorder("5px") -); - -// 失败 -export const FailedLabel = new LogLabel( - "SUCCESS", new LogStyle().setColor("#FFFFFF", "#33ff66").setBorder("3px") -); - - - -// 致命 -export const FatalLabel = new LogLabel( - "FATAL", new LogStyle().setColor("#FFFFFF", "#FF00CC").setBorder("3px") -); - -// 错误 -export const ErrorLabel = new LogLabel( - "ERROR", new LogStyle().setColor("#FFFFFF", "#FF0000").setBorder("3px") -); - -// 警告 -export const WarnLabel = new LogLabel( - "WARN", new LogStyle().setColor("#FFFFFF", "#FF9900").setBorder("3px") -); - -// 消息 -export const InfoLabel = new LogLabel( - "INFO", new LogStyle().setColor("#FFFFFF", "#99FF00").setBorder("3px") -); - -// 调试 -export const DebugLabel = new LogLabel( - "DEBUG", new LogStyle().setColor("#FFFFFF", "#00FF99").setBorder("3px") -); - -// 追踪 -export const TraceLabel = new LogLabel( - "TRACE", new LogStyle().setColor("#FFFFFF", "#00CCFF").setBorder("3px") -); \ No newline at end of file diff --git a/miniprogram/utils/Logger.ts b/miniprogram/utils/Logger.ts deleted file mode 100644 index ded1b76..0000000 --- a/miniprogram/utils/Logger.ts +++ /dev/null @@ -1,391 +0,0 @@ -import {LOGGER_CONSOLE, LOGGER_FILTER} from "./Config"; - -/** - * 调试输出样式 - */ -class LogStyle { - - /** - * 日志文字颜色 - */ - private color:string | undefined; - - /** - * 日志背景颜色 - */ - private backgroundColor:string | undefined; - - /** - * 日志文字粗细 - */ - private weight:string | undefined; - - /** - * 日志文字大小 - */ - private size:string | undefined; - - /** - * 日志文字字体 - */ - private family:string | undefined; - - /** - * 日志文字圆角 - */ - private borderRadius:string | undefined; - - /** - * 日志文字边框 - */ - private border:string | undefined; - - /** - * 设置颜色 - * @param color 日志文字颜色 - * @param backgroundColor 日志背景颜色 - */ - public setColor(color:string, backgroundColor?:string):LogStyle { - this.color = color; - this.backgroundColor = backgroundColor; - return this; - } - - /** - * 设置边框 - * @param borderRadius 日志文字圆角 - * @param border 日志文字边框 - */ - public setBorder(borderRadius:string, border?:string):LogStyle { - this.borderRadius = borderRadius; - this.border = border; - return this; - } - - /** - * 设置文字 - * @param weight 日志文字粗细 - * @param family 日志文字字体 - */ - public setFont(weight:string, family:string):LogStyle { - this.weight = weight; - this.family = family; - return this; - } - - /** - * 设置文字大小 - * @param size 日志文字大小 - */ - public setSize(size:string):LogStyle { - this.size = size; - return this; - } - - /** - * 字符化转义样式 - */ - public stringify():string { - let stringArr:string[] = []; - - this.color && stringArr.push(`color:${ this.color }`); - this.backgroundColor && stringArr.push(`background-color:${ this.backgroundColor }`); - this.weight && stringArr.push(`font-weight:${ this.weight }`); - this.family && stringArr.push(`font-family:${ this.family }`); - this.borderRadius && stringArr.push(`border-radius:${ this.borderRadius }`); - this.border && stringArr.push(`border:${ this.border }`); - this.size && stringArr.push(`font-size:${ this.size }`); - - stringArr.push(`margin-bottom:5px`); - - return stringArr.join(";"); - } -} - -/** - * 日志标签 - */ -class LogLabel { - - /** - * 关键字 - * 用于标识这个类别 - */ - public key:string; - - /** - * 文字样式 - */ - public style:LogStyle; - - /** - * @param key 关键字 - * @param style 文字样式 - */ - constructor(key:string, style:LogStyle) { - this.key = key; - this.style = style; - } - - /** - * 获得 Logger 输出使用的内容 - */ - public getLoggerOutput():string { - return `%c ${ this.key } `; - } - - /** - * 获得 Text 输出内容 - */ - public getTextOutput():string { - return `[${ this.key }]`; - } - - /** - * 获得 style 格式化 - */ - public getStyleOutput():string { - return this.style.stringify(); - } -} - -/** - * 栈信息 - */ -class StackInfo { - - /** - * 函数名 - */ - public functionName:string | undefined; - - /** - * 文件名 - */ - public fileName:string | undefined; - - /** - * 文件路径 - */ - public url:string | undefined; - - public setInfo(functionName:string, fileName:string, url:string):StackInfo { - this.functionName = functionName; - this.fileName = fileName; - this.url = url; - return this; - } - - /** - * 获取函数调用栈列表 - */ - 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] - )) - } - - return callStack; - } - - /** - * 排除的 - */ - static readonly excludeFile:RegExp = /^Logger\.js:\d+:\d+/; - - /** - * 获取第一个调用栈 - */ - static getFirstStack():StackInfo | undefined { - - let callStack = this.getCallStack(); - - for(let i = 0; i < callStack.length; i++) { - - if(!callStack[i].fileName) continue; - - if(!StackInfo.excludeFile.test(callStack[i].fileName ?? "")) { - return callStack[i]; - } - } - - return; - } -} - -/** - * 多重内容捆绑 - * 用于 log 输出 - */ -class MultipleLogContent { - - /** - * 输出内容 - */ - private content:any[]; - - /** - * @param content 输出内容 - */ - public constructor(...content:any[]) { - this.content = content; - } - - /** - * 获取内容 - */ - public getContent():any[] { - return this.content; - } -} - -/** - * 格式化日志输出 - */ -class Logger { - - /** - * 堆栈路径样式 - */ - static readonly pathStyle:LogStyle = new LogStyle().setColor("#CCCCCC"); - - /** - * 标签过滤 - */ - static filterLog(filter:Array, labels:LogLabel[]):boolean { - - let passNum:number = 0; - - for(let i = 0; i < filter.length; i++) { - - let pass:boolean = false; - for(let j = 0; j < labels.length; j++) { - - if(filter[i] instanceof RegExp) { - pass = (filter[i] as RegExp).test(labels[j].key) - } else { - pass = (filter[i] as String) === labels[j].key; - } - - if(pass) break; - } - - if(pass) passNum ++; - } - - return passNum === filter.length; - } - - /** - * 检测是否应该输出 - * @param labels 使用标签 - */ - static testLog(...labels:LogLabel[]):boolean { - - if(!LOGGER_CONSOLE) return false; - - let isLogging = false; - for(let i = 0; i < LOGGER_FILTER.length; i++) { - - // 判断是否进行输出 - isLogging = Logger.filterLog(LOGGER_FILTER[i], labels); - - if(isLogging) break; - } - - return isLogging; - } - - /** - * - * @param styledLabel calcStyle的处理结果 - */ - static addFileNameLabel():LogLabel { - - // 获得调用堆栈 - let stack = StackInfo.getFirstStack(); - - return new LogLabel(stack?.fileName ?? "", Logger.pathStyle); - } - - /** - * 收集计算样式 - * @param labels 使用标签 - */ - static calcStyle(...labels:LogLabel[]):[string[], string[]] { - - let consoleLabels:string[] = []; - let consoleStyles:string[] = []; - - // 放置标签 - for(let i = 0; i < labels.length; i++) { - consoleLabels.push(labels[i].getLoggerOutput()); - - if (i !== ( labels.length - 1)) - consoleLabels.push("%c "); - - consoleStyles.push(labels[i].getStyleOutput()); - - if (i !== ( labels.length - 1)) - consoleStyles.push(""); - } - - return [consoleLabels, consoleStyles]; - } - - /** - * 调试输出 - * @param content 输出内容 - * @param label 使用标签 - */ - static log(content:T, ...labels:LogLabel[]):T { - - let fileNameLabel = Logger.addFileNameLabel(); - - if(!Logger.testLog(...labels, fileNameLabel)) return content; - - let styledLabel = Logger.calcStyle(...labels); - - console.log( - styledLabel[0].join("") + fileNameLabel.getLoggerOutput(), - ...[...styledLabel[1], fileNameLabel.getStyleOutput()], - content - ); - - return content; - } - - /** - * 多重调试输出 - * @param labels 输出内容 - * @param content 使用标签 - */ - static logM(labels:LogLabel[], ...content:T[]):T[] { - return Logger.log(content, ...labels); - } -} - -export default Logger; -export {Logger, LogStyle, LogLabel} \ No newline at end of file diff --git a/project.config.json b/project.config.json index b4b9816..bf78da6 100644 --- a/project.config.json +++ b/project.config.json @@ -5,7 +5,7 @@ }, "miniprogramRoot": "miniprogram/", "compileType": "miniprogram", - "libVersion": "2.21.0", + "libVersion": "2.16.1", "projectname": "mini-dlpu-v3", "setting": { "urlCheck": false, @@ -51,5 +51,8 @@ "simulatorType": "wechat", "simulatorPluginLibVersion": {}, "appid": "wx7d809f5e8955843d", + "scripts": { + "beforeCompile": "" + }, "condition": {} } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 42fa8c5..45e3597 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,11 @@ "lib": ["ES2020"], "typeRoots": [ "./typings" - ] + ], + "baseUrl": "./miniprogram/", + "paths": { + "@logger": ["logger/"] + } }, "include": [ "./**/*.ts"