221 lines
5.5 KiB
TypeScript
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
|