feat(tools): 抽象通用组件成包并接入 #27
Some checks failed
Egg Server MIflow / build-image (push) Failing after 30s
Some checks failed
Egg Server MIflow / build-image (push) Failing after 30s
This commit is contained in:
parent
09e352a9c1
commit
5a2990cd7e
1
.npmrc
Normal file
1
.npmrc
Normal file
@ -0,0 +1 @@
|
||||
@egg:registry=https://git.yingbo.im:333/api/packages/zhaoyingbo/npm/
|
@ -1,4 +1,5 @@
|
||||
import loggerIns from "../../log"
|
||||
import logger from "@egg/logger"
|
||||
|
||||
import appInfo from "../appInfo"
|
||||
import pbClient from "../pbClient"
|
||||
|
||||
@ -20,7 +21,7 @@ const update = async (id: string, appName: string, value: string) => {
|
||||
}
|
||||
|
||||
tokenCache[appName] = value
|
||||
loggerIns.info(`reset ${appName} access token success: ${value}`)
|
||||
logger.info(`reset ${appName} access token success: ${value}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
7
index.ts
7
index.ts
@ -1,11 +1,12 @@
|
||||
import loggerIns from "./log"
|
||||
import logger from "@egg/logger"
|
||||
import { makeCheckPathTool } from "@egg/path-tool"
|
||||
|
||||
import { manageBotReq } from "./routes/bot"
|
||||
import { manageMessageReq } from "./routes/message"
|
||||
import { manageMicroAppReq } from "./routes/microApp"
|
||||
import { manageSheetReq } from "./routes/sheet"
|
||||
import { initSchedule } from "./schedule"
|
||||
import genContext from "./utils/genContext"
|
||||
import { makeCheckPathTool } from "./utils/pathTools"
|
||||
|
||||
initSchedule()
|
||||
|
||||
@ -38,4 +39,4 @@ const server = Bun.serve({
|
||||
port: 3000,
|
||||
})
|
||||
|
||||
loggerIns.info(`Listening on ${server.hostname}:${server.port}`)
|
||||
logger.info(`Listening on ${server.hostname}:${server.port}`)
|
||||
|
55
log/index.ts
55
log/index.ts
@ -1,55 +0,0 @@
|
||||
import "winston-daily-rotate-file"
|
||||
|
||||
import winston, { format } from "winston"
|
||||
|
||||
const isProd = process.env.NODE_ENV === "production"
|
||||
|
||||
const transports: any[] = [
|
||||
new winston.transports.Console({
|
||||
level: "info",
|
||||
}),
|
||||
]
|
||||
|
||||
if (isProd) {
|
||||
const config = {
|
||||
datePattern: "YYYY-MM-DD",
|
||||
zippedArchive: true,
|
||||
maxSize: "20m",
|
||||
maxFiles: "14d",
|
||||
}
|
||||
|
||||
transports.push(
|
||||
new winston.transports.DailyRotateFile({
|
||||
level: "info",
|
||||
filename: "/home/work/log/egg-info-%DATE%.log",
|
||||
...config,
|
||||
})
|
||||
)
|
||||
transports.push(
|
||||
new winston.transports.DailyRotateFile({
|
||||
level: "debug",
|
||||
filename: "/home/work/log/egg-debug-%DATE%.log",
|
||||
...config,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const loggerIns = winston.createLogger({
|
||||
level: "silly",
|
||||
format: format.combine(
|
||||
format.colorize({
|
||||
level: !isProd,
|
||||
}), // 开发环境下输出彩色日志
|
||||
format.simple(), // 简单文本格式化
|
||||
format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
|
||||
format.printf(({ level, message, timestamp, requestId }) => {
|
||||
const singleLineMessage = isProd
|
||||
? message.replace(/\n/g, " ") // 将换行符替换为空格
|
||||
: message
|
||||
return `${timestamp} [${level}]${requestId ? ` [RequestId: ${requestId}]` : ""}: ${singleLineMessage}`
|
||||
})
|
||||
),
|
||||
transports,
|
||||
})
|
||||
|
||||
export default loggerIns
|
22
package.json
22
package.json
@ -16,26 +16,30 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
"@commitlint/cli": "^19.4.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@eslint/js": "^9.7.0",
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/node-schedule": "^2.1.7",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"bun-types": "latest",
|
||||
"eslint": "^9.7.0",
|
||||
"bun-types": "^1.1.24",
|
||||
"eslint": "^9.9.0",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"husky": "^9.1.1",
|
||||
"lint-staged": "^15.2.7",
|
||||
"husky": "^9.1.5",
|
||||
"lint-staged": "^15.2.9",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript-eslint": "^7.17.0"
|
||||
"typescript-eslint": "^8.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@egg/hooks": "^1.1.0",
|
||||
"@egg/logger": "^1.2.1",
|
||||
"@egg/net-tool": "^1.2.1",
|
||||
"@egg/path-tool": "^1.2.1",
|
||||
"node-schedule": "^2.1.1",
|
||||
"p-limit": "^6.1.0",
|
||||
"pocketbase": "^0.21.3",
|
||||
"pocketbase": "^0.21.4",
|
||||
"uuid": "^10.0.0",
|
||||
"winston": "^3.14.2",
|
||||
"winston-daily-rotate-file": "^5.0.0"
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { stringifyJson } from "@egg/hooks"
|
||||
|
||||
import db from "../../db"
|
||||
import { Context, DB, LarkServer, MsgProxy } from "../../types"
|
||||
import { safeJsonStringify } from "../../utils/pathTools"
|
||||
|
||||
const LOG_COLLECTION = "message_log"
|
||||
|
||||
@ -49,7 +50,7 @@ export const manageMessageReq = async (
|
||||
// 处理消息内容
|
||||
const finalContent =
|
||||
typeof body.content !== "string"
|
||||
? safeJsonStringify(body.content)
|
||||
? stringifyJson(body.content)
|
||||
: body.content
|
||||
|
||||
// 初始化发送结果对象
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { makeCheckPathTool } from "@egg/path-tool"
|
||||
|
||||
import { Context } from "../../types"
|
||||
import { makeCheckPathTool } from "../../utils/pathTools"
|
||||
|
||||
/**
|
||||
* 处理登录请求
|
||||
|
@ -1,7 +1,7 @@
|
||||
import logger from "@egg/logger"
|
||||
import pLimit from "p-limit"
|
||||
|
||||
import db from "../db"
|
||||
import loggerIns from "../log"
|
||||
import { LarkService } from "../services"
|
||||
|
||||
export const resetAccessToken = async () => {
|
||||
@ -23,7 +23,7 @@ export const resetAccessToken = async () => {
|
||||
)
|
||||
await Promise.allSettled(promiseList)
|
||||
} catch (error: any) {
|
||||
loggerIns
|
||||
logger
|
||||
.child({ requestId: "schedule" })
|
||||
.error(`resetAccessToken error: ${error.message}`)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { NetToolBase } from "@egg/net-tool"
|
||||
|
||||
import { LarkEvent } from "../../types"
|
||||
import { NetToolBase } from "../../utils/netTool"
|
||||
|
||||
class AttachService extends NetToolBase {
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { NetError, NetToolBase } from "@egg/net-tool"
|
||||
|
||||
import db from "../../db"
|
||||
import { NetError, NetToolBase } from "../../utils/netTool"
|
||||
|
||||
class LarkBaseService extends NetToolBase {
|
||||
constructor(appName: string, requestId: string) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { NetTool } from "@egg/net-tool"
|
||||
import { Logger } from "winston"
|
||||
|
||||
import { AttachService, LarkService } from "../services"
|
||||
import NetTool from "../utils/netTool"
|
||||
|
||||
export namespace Context {
|
||||
export interface Data {
|
||||
|
@ -1,9 +1,9 @@
|
||||
import loggerIns from "@egg/logger"
|
||||
import { NetTool } from "@egg/net-tool"
|
||||
import { v4 as uuid } from "uuid"
|
||||
|
||||
import loggerIns from "../log"
|
||||
import { AttachService, LarkService } from "../services"
|
||||
import { Context } from "../types"
|
||||
import NetTool from "./netTool"
|
||||
|
||||
/**
|
||||
* 生成请求上下文。
|
||||
|
424
utils/netTool.ts
424
utils/netTool.ts
@ -1,424 +0,0 @@
|
||||
import { Logger } from "winston"
|
||||
|
||||
import loggerIns from "../log"
|
||||
|
||||
interface NetRequestParams {
|
||||
url: string
|
||||
method: string
|
||||
queryParams?: any
|
||||
payload?: any
|
||||
additionalHeaders?: any
|
||||
}
|
||||
|
||||
interface NetErrorDetail {
|
||||
httpStatus: number
|
||||
code: number
|
||||
message: string
|
||||
}
|
||||
|
||||
export class NetError extends Error {
|
||||
public code: number
|
||||
public message: string
|
||||
public httpStatus: number
|
||||
|
||||
constructor({ code, message, httpStatus }: NetErrorDetail) {
|
||||
super(message)
|
||||
this.code = code
|
||||
this.message = message
|
||||
this.httpStatus = httpStatus
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络工具类,提供发送HTTP请求的方法。
|
||||
*/
|
||||
class NetToolBase {
|
||||
protected prefix: string
|
||||
protected headers: any
|
||||
protected getHeaders: () => any
|
||||
protected logger: Logger
|
||||
protected requestId: string
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {any} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
*/
|
||||
constructor({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: any
|
||||
getHeaders?: () => any
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
this.prefix = prefix || ""
|
||||
this.headers = headers || {}
|
||||
this.getHeaders = getHeaders || (() => ({}))
|
||||
this.requestId = requestId || ""
|
||||
this.logger = loggerIns.child({ requestId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录响应详情并返回响应日志对象。
|
||||
* @param response - 响应对象。
|
||||
* @param method - 请求使用的HTTP方法。
|
||||
* @param headers - 请求头。
|
||||
* @param requestBody - 请求体。
|
||||
* @param responseBody - 响应体。
|
||||
* @returns 响应日志对象。
|
||||
*/
|
||||
private logResponse(
|
||||
response: Response,
|
||||
method: string,
|
||||
headers: any,
|
||||
requestBody: any,
|
||||
responseBody: any
|
||||
) {
|
||||
const responseLog = {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
url: response.url,
|
||||
method: method,
|
||||
requestHeaders: headers,
|
||||
responseHeaders: response.headers,
|
||||
requestBody,
|
||||
responseBody,
|
||||
}
|
||||
this.logger.http(JSON.stringify(responseLog, null, 2))
|
||||
return responseLog
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送网络请求并返回一个解析为响应数据的Promise。
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param method - 请求使用的HTTP方法。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
* @throws 如果网络响应不成功或存在解析错误,则抛出错误。
|
||||
*/
|
||||
protected async request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
// 拼接完整的URL
|
||||
let fullUrl = `${this.prefix}${url}`
|
||||
if (queryParams) {
|
||||
if (typeof queryParams === "string") {
|
||||
fullUrl = `${fullUrl}?${queryParams}`
|
||||
} else {
|
||||
const queryString = new URLSearchParams(queryParams).toString()
|
||||
if (queryString) fullUrl = `${fullUrl}?${queryString}`
|
||||
}
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
const headers = {
|
||||
...this.headers,
|
||||
...(await this.getHeaders()),
|
||||
...additionalHeaders,
|
||||
}
|
||||
// 设置请求Header
|
||||
if (!(payload instanceof FormData)) {
|
||||
headers["Content-Type"] = "application/json"
|
||||
}
|
||||
|
||||
// 处理请求数据
|
||||
const body = payload instanceof FormData ? payload : JSON.stringify(payload)
|
||||
|
||||
// 发送请求
|
||||
const res = await fetch(fullUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
})
|
||||
// 获取响应数据
|
||||
let resData: any = null
|
||||
let resText: string = ""
|
||||
|
||||
try {
|
||||
resText = await res.text()
|
||||
resData = JSON.parse(resText)
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
// 记录响应
|
||||
this.logResponse(res, method, headers, payload, resData || resText)
|
||||
if (!res.ok) {
|
||||
if (resData?.message || resData?.msg) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: resData?.code,
|
||||
message: resData?.message || resData?.msg,
|
||||
})
|
||||
}
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: res.status,
|
||||
message: resText || "网络响应异常",
|
||||
})
|
||||
}
|
||||
// http 错误码正常,但解析异常
|
||||
if (!resData) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: 1,
|
||||
message: "解析响应数据异常",
|
||||
})
|
||||
}
|
||||
// 响应数据异常
|
||||
if ("code" in resData && resData.code !== 0) {
|
||||
throw new NetError({
|
||||
httpStatus: res.status,
|
||||
code: resData.code,
|
||||
message: resData.message || resData.msg || "网络请求失败",
|
||||
})
|
||||
}
|
||||
return resData as T
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({ url, method: "get", queryParams, additionalHeaders })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "post",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PUT请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "put",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送DELETE请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "delete",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PATCH请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "patch",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class NetTool extends NetToolBase {
|
||||
public request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
return super.request<T>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
public get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.get<T>(url, queryParams, additionalHeaders)
|
||||
}
|
||||
public post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.post<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.put<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.del<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.patch<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
/**
|
||||
* 创建一个表示400 Bad Request的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示400 Bad Request的响应对象。
|
||||
*/
|
||||
badRequest(message: string) {
|
||||
this.logger.error(`return a bad request response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 400, message, requestId: this.requestId },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示404 Not Found的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示404 Not Found的响应对象。
|
||||
*/
|
||||
notFound(message: string) {
|
||||
this.logger.error(`return a not found response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 404, message, requestId: this.requestId },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示500 Internal Server Error的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @param data - 错误数据。
|
||||
* @returns 一个表示500 Internal Server Error的响应对象。
|
||||
*/
|
||||
serverError(message: string, data?: any) {
|
||||
this.logger.error(`return a server error response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 500, message, data, requestId: this.requestId },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的响应对象。
|
||||
*
|
||||
* @param data - 响应数据。
|
||||
* @returns 一个表示200 OK的响应对象。
|
||||
*/
|
||||
ok(data?: any) {
|
||||
this.logger.info(`return a ok response: ${JSON.stringify(data)}`)
|
||||
return Response.json({
|
||||
code: 0,
|
||||
message: "success",
|
||||
data,
|
||||
requestId: this.requestId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export { NetToolBase }
|
||||
|
||||
export default NetTool
|
@ -1,65 +0,0 @@
|
||||
/**
|
||||
* 创建一个路径检查工具,用于精确匹配和前缀匹配路径。
|
||||
* @param {string} url - 要检查的基础 URL。
|
||||
* @param {string} [prefix] - 可选的路径前缀。
|
||||
* @returns {object} 包含路径检查方法的对象。
|
||||
*/
|
||||
export const makeCheckPathTool = (url: string, prefix?: string) => {
|
||||
const { pathname } = new URL(url)
|
||||
const makePath = (path: string) => `${prefix || ""}${path}`
|
||||
return {
|
||||
/**
|
||||
* 检查路径是否与基础 URL 的路径精确匹配。
|
||||
* @param {string} path - 要检查的路径。
|
||||
* @returns {boolean} 如果路径精确匹配则返回 true,否则返回 false。
|
||||
*/
|
||||
exactCheck: (path: string) => {
|
||||
return pathname === makePath(path)
|
||||
},
|
||||
/**
|
||||
* 检查路径是否以基础 URL 的路径为前缀。
|
||||
* @param {string} path - 要检查的路径。
|
||||
* @returns {boolean} 如果路径以基础 URL 的路径为前缀则返回 true,否则返回 false。
|
||||
*/
|
||||
startsWithCheck: (path: string) => pathname.startsWith(makePath(path)),
|
||||
/**
|
||||
* 检查完整路径是否与基础 URL 的路径精确匹配。
|
||||
* @param {string} path - 要检查的路径。
|
||||
* @returns {boolean} 如果完整路径与基础 URL 的路径精确匹配则返回 true,否则返回 false。
|
||||
*/
|
||||
fullCheck: (path: string) => pathname === path,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁剪路径字符串,如果路径长度超过20个字符,则只保留最后两级目录。
|
||||
*
|
||||
* @param {string} path - 要处理的路径字符串。
|
||||
* @returns {string} - 裁剪后的路径字符串,如果长度不超过20个字符则返回原路径。
|
||||
*/
|
||||
export const shortenPath = (path: string): string => {
|
||||
if (path.length <= 20) {
|
||||
return path
|
||||
}
|
||||
|
||||
const parts = path.split("/")
|
||||
if (parts.length <= 2) {
|
||||
return path
|
||||
}
|
||||
|
||||
return `.../${parts[parts.length - 2]}/${parts[parts.length - 1]}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地将对象转换为 JSON 字符串。
|
||||
* 如果转换失败,则返回对象的字符串表示。
|
||||
* @param {any} obj - 要转换的对象。
|
||||
* @returns {string} - JSON 字符串或对象的字符串表示。
|
||||
*/
|
||||
export const safeJsonStringify = (obj: any) => {
|
||||
try {
|
||||
return JSON.stringify(obj)
|
||||
} catch (e) {
|
||||
return String(obj)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user