zhaoyingbo 850cf6af51
Some checks failed
/ release (push) Failing after 21s
style(lark-msg): 格式化代码
2024-10-12 03:05:20 +00:00

221 lines
5.5 KiB
TypeScript

import logger from "@egg/logger"
import _ from "lodash"
import { Logger } from "winston"
import { baseErrorCard, basePendingCard, baseSuccessCard } from "./component"
type FunctionMap = Record<
string,
{ Xname: string; Xauthor: string; Xicon: string }
>
type CardMap = Record<string, any>
type TempMap = Record<string, string>
class LarkCard {
protected requestId: string
protected funcName: string
protected functionMap: FunctionMap
protected cardMap: CardMap
protected tempMap: TempMap
protected stringify: boolean
protected logger: Logger
/**
* 构造函数
* @param funcName 函数名
* @param stringify 是否序列化为字符串
* @param requestId 请求 ID
* @param cardMap 卡片映射
* @param tempMap 模板映射
* @param functionMap 函数映射
*/
constructor(
funcName: string,
stringify: boolean,
requestId: string,
cardMap: CardMap,
tempMap: TempMap,
functionMap: FunctionMap
) {
this.stringify = stringify
this.requestId = requestId
this.funcName = funcName
this.functionMap = functionMap
this.cardMap = {
success: baseSuccessCard,
error: baseErrorCard,
pending: basePendingCard,
...cardMap,
}
this.tempMap = tempMap
this.logger = logger.child({ requestId })
}
/**
* 设置函数名
* @param funcName 函数名
*/
setFunction(funcName: string) {
this.funcName = funcName
}
/**
* 设置是否序列化为字符串
* @param stringify 是否序列化为字符串
*/
setStringify(stringify: boolean) {
this.stringify = stringify
}
/**
* 创建一个子卡片
* @param func 函数名
* @param stringify 是否序列化为字符串
* @returns 子卡片实例
*/
child(func: string, stringify: boolean = true) {
return new LarkCard(
func,
stringify,
this.requestId,
this.cardMap,
this.tempMap,
this.functionMap
)
}
/**
* 生成卡片消息
* @param cardKey 卡片ID
* @param variables 变量
* @returns 卡片内容或JSON字符串
*/
genCard(
cardKey: keyof typeof this.cardMap,
variables: { [key: string]: any }
) {
const card = this.cardMap[cardKey]
if (!card) {
this.logger.error(`Card ${cardKey} not found`)
throw new Error(`Card ${cardKey} not found`)
}
const finalVariables: Record<string, any> = {
...variables,
requestId: this.requestId,
...this.functionMap[this.funcName],
}
this.logger.debug(
`Card ${cardKey} final variables: ${JSON.stringify(finalVariables)}`
)
/**
* 替换字符串中的变量
* @param str 字符串
* @returns 替换后的字符串
*/
const replaceVariables = (str: string): string => {
const variablePattern = /\$\{(\w+)\}/g
const matches = str.match(variablePattern)
if (matches && matches.length === 1 && matches[0] === str) {
// 如果字符串中只有一个变量,且整个字符串就是这个变量
const variableName = matches[0].slice(2, -1) // 去掉 ${ 和 }
return finalVariables[variableName] || ""
} else {
// 否则只替换字符串中的变量部分
return str.replace(variablePattern, (_, v) => finalVariables[v] || "")
}
}
/**
* 遍历并替换对象中的变量
* @param obj 对象
* @returns 替换后的对象
*/
const traverseAndReplace = (obj: any): any => {
if (_.isString(obj)) {
return replaceVariables(obj)
} else if (_.isArray(obj)) {
return obj.map(traverseAndReplace)
} else if (_.isObject(obj)) {
return _.mapValues(obj, traverseAndReplace)
}
return obj
}
const content = traverseAndReplace(card)
this.logger.debug(
`Card ${cardKey} final content: ${JSON.stringify(content)}`
)
return this.stringify ? JSON.stringify(content) : content
}
/**
* 生成成功卡片
* @param content 卡片内容
* @returns 成功卡片内容或JSON字符串
*/
genSuccessCard(content: any) {
return this.genCard("success", { content })
}
/**
* 生成错误卡片
* @param content 卡片内容
* @returns 错误卡片内容或JSON字符串
*/
genErrorCard(content: any) {
return this.genCard("error", { content })
}
/**
* 生成待处理卡片
* @param content 卡片内容
* @returns 待处理卡片内容或JSON字符串
*/
genPendingCard(content: any) {
return this.genCard("pending", { content })
}
/**
* 生成模板卡片
* @param tempKey 模板ID
* @param variables 变量
* @returns 模板卡片内容或JSON字符串
*/
genTempCard(tempKey: string, variables: { [key: string]: any }) {
const tempId = this.tempMap[tempKey]
if (!tempId) {
this.logger.error(`Temp ${tempKey} not found`)
throw new Error(`Temp ${tempKey} not found`)
}
const finalVariables: Record<string, any> = {
...variables,
requestId: this.requestId,
...this.functionMap[this.funcName],
}
this.logger.debug(
`Temp ${tempKey} final variables: ${JSON.stringify(finalVariables)}`
)
const content = {
type: "template",
data: {
config: {
update_multi: true,
enable_forward: false,
},
template_id: tempId,
template_variable: finalVariables,
},
}
this.logger.debug(
`Temp ${tempKey} final content: ${JSON.stringify(content)}`
)
return this.stringify ? JSON.stringify(content) : content
}
}
export default LarkCard