fix: 执行顺序
This commit is contained in:
parent
cd29445387
commit
47ba0fee14
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit c052a84f274b4ed9fd924afd682a359ec4fde2f2
|
|
@ -1,13 +1,18 @@
|
||||||
|
import { PuppeteerLaunchOptions } from 'puppeteer';
|
||||||
import Puppeteer from './lib/puppeteer.js'
|
import Puppeteer from './lib/puppeteer.js'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param config 本地config.yaml的配置内容
|
* @param config
|
||||||
* @returns renderer 渲染器对象
|
* @returns renderer 渲染器对象
|
||||||
* @returns renderer.id 渲染器ID,对应renderer中选择的id
|
* @returns renderer.id 渲染器ID,对应renderer中选择的id
|
||||||
* @returns renderer.type 渲染类型,保留字段,暂时支持image
|
* @returns renderer.type 渲染类型,保留字段,暂时支持image
|
||||||
* @returns renderer.render 渲染入口
|
* @returns renderer.render 渲染入口
|
||||||
*/
|
*/
|
||||||
export default function (config) {
|
export default function (config?: PuppeteerLaunchOptions & {
|
||||||
|
chromiumPath: string;
|
||||||
|
puppeteerWS: any;
|
||||||
|
puppeteerTimeout: any;
|
||||||
|
}) {
|
||||||
// TODO Puppeteer待简化重构
|
// TODO Puppeteer待简化重构
|
||||||
return new Puppeteer(config)
|
return new Puppeteer(config)
|
||||||
}
|
}
|
|
@ -4,6 +4,22 @@ import { join } from 'node:path'
|
||||||
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs'
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs'
|
||||||
import { CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js'
|
import { CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js'
|
||||||
|
|
||||||
|
export function configInit() {
|
||||||
|
const path = CONFIG_INIT_PATH
|
||||||
|
const pathDef = CONFIG_DEFAULT_PATH
|
||||||
|
const files = readdirSync(pathDef).filter(file => file.endsWith('.yaml'))
|
||||||
|
mkdirSync(join(process.cwd(), path), {
|
||||||
|
'recursive': true
|
||||||
|
})
|
||||||
|
for (let file of files) {
|
||||||
|
if (!existsSync(`${path}${file}`)) {
|
||||||
|
copyFileSync(`${pathDef}${file}`, `${path}${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!existsSync("data")) mkdirSync("data")
|
||||||
|
if (!existsSync("resources")) mkdirSync("resources")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ********
|
* ********
|
||||||
* 配置文件
|
* 配置文件
|
||||||
|
@ -21,30 +37,6 @@ class ConfigController {
|
||||||
*/
|
*/
|
||||||
watcher = { config: {}, defSet: {} }
|
watcher = { config: {}, defSet: {} }
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
this.initCfg()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化配置
|
|
||||||
*/
|
|
||||||
initCfg() {
|
|
||||||
const path = CONFIG_INIT_PATH
|
|
||||||
const pathDef = CONFIG_DEFAULT_PATH
|
|
||||||
const files = readdirSync(pathDef).filter(file => file.endsWith('.yaml'))
|
|
||||||
for (let file of files) {
|
|
||||||
if (!existsSync(`${path}${file}`)) {
|
|
||||||
copyFileSync(`${pathDef}${file}`, `${path}${file}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!existsSync("data")) mkdirSync("data")
|
|
||||||
if (!existsSync("resources")) mkdirSync("resources")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机器人qq号
|
* 机器人qq号
|
||||||
*/
|
*/
|
||||||
|
@ -238,8 +230,7 @@ class ConfigController {
|
||||||
* 修改日志等级
|
* 修改日志等级
|
||||||
*/
|
*/
|
||||||
async change_bot() {
|
async change_bot() {
|
||||||
const { setLogger } = await import('./log.js')
|
//
|
||||||
setLogger && setLogger()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import log4js from 'log4js'
|
import log4js from 'log4js'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import cfg from './config.js'
|
import cfg from './config.js'
|
||||||
import fs from 'node:fs'
|
import { mkdirSync } from 'node:fs'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建日志
|
* 创建日志
|
||||||
|
@ -86,27 +85,18 @@ function createLog() {
|
||||||
/**
|
/**
|
||||||
* 设置日志样式
|
* 设置日志样式
|
||||||
*/
|
*/
|
||||||
export function setLogger() {
|
export function loggerInit() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
let file = './logs'
|
mkdirSync('./logs', {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if (!fs.existsSync(file)) {
|
|
||||||
fs.mkdirSync(file, {
|
|
||||||
'recursive': true
|
'recursive': true
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局变量 logger
|
* 全局变量 logger
|
||||||
*/
|
*/
|
||||||
global.logger = createLog() as any
|
global.logger = createLog() as any
|
||||||
|
|
||||||
logger.chalk = chalk
|
logger.chalk = chalk
|
||||||
logger.red = chalk.red
|
logger.red = chalk.red
|
||||||
logger.green = chalk.green
|
logger.green = chalk.green
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default class messageEvent extends EventListener {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
super({ event: 'message', prefix: undefined, once: undefined })
|
super({ event: 'message' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default class noticeEvent extends EventListener {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
super({ event: 'notice', prefix: undefined, once: undefined })
|
super({ event: 'notice' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default class offlineEvent extends EventListener {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
super({ event: 'system.offline', prefix: undefined, once: undefined })
|
super({ event: 'system.offline' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,8 +16,7 @@ export default class onlineEvent extends EventListener {
|
||||||
*/
|
*/
|
||||||
super({
|
super({
|
||||||
event: 'system.online',
|
event: 'system.online',
|
||||||
once: true,
|
once: true
|
||||||
prefix: undefined
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default class requestEvent extends EventListener {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
super({ event: 'request', prefix: undefined, once: undefined })
|
super({ event: 'request' })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,7 +29,15 @@ export default class EventListener {
|
||||||
* @param data.event 监听的事件
|
* @param data.event 监听的事件
|
||||||
* @param data.once 是否只监听一次
|
* @param data.once 是否只监听一次
|
||||||
*/
|
*/
|
||||||
constructor({ prefix, event, once }) {
|
constructor({
|
||||||
|
prefix,
|
||||||
|
event,
|
||||||
|
once
|
||||||
|
}: {
|
||||||
|
prefix?: string
|
||||||
|
event?: any
|
||||||
|
once?: any
|
||||||
|
}) {
|
||||||
prefix && (this.prefix = prefix)
|
prefix && (this.prefix = prefix)
|
||||||
once && (this.once = once)
|
once && (this.once = once)
|
||||||
this.event = event
|
this.event = event
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
* @param msg 消息
|
* @param msg 消息
|
||||||
* @param uin 指定bot发送,默认为Bot
|
* @param uin 指定bot发送,默认为Bot
|
||||||
*/
|
*/
|
||||||
export async function relpyPrivate(userId, msg, uin = Bot.uin) {
|
export async function relpyPrivate(userId: number | string, msg, uin = Bot.uin) {
|
||||||
userId = Number(userId)
|
userId = Number(userId)
|
||||||
let friend = Bot.fl.get(userId)
|
const friend = Bot.fl.get(userId)
|
||||||
if (friend) {
|
if (friend) {
|
||||||
logger.mark(`发送好友消息[${friend.nickname}](${userId})`)
|
logger.mark(`发送好友消息[${friend.nickname}](${userId})`)
|
||||||
return await Bot[uin]
|
return await Bot[uin]
|
||||||
|
|
|
@ -6,6 +6,10 @@ interface EventTypeBase {
|
||||||
* 是否是主人
|
* 是否是主人
|
||||||
*/
|
*/
|
||||||
isMaster: boolean;
|
isMaster: boolean;
|
||||||
|
/**
|
||||||
|
* 是否是管理员
|
||||||
|
*/
|
||||||
|
// isAdmin: boolean;
|
||||||
/**
|
/**
|
||||||
* 是否是群里
|
* 是否是群里
|
||||||
*/
|
*/
|
||||||
|
@ -21,11 +25,9 @@ interface EventTypeBase {
|
||||||
*/
|
*/
|
||||||
reply: (...arg: any[]) => Promise<any>;
|
reply: (...arg: any[]) => Promise<any>;
|
||||||
/**
|
/**
|
||||||
* @deprecated 已废弃
|
|
||||||
*/
|
*/
|
||||||
file: any;
|
file: any;
|
||||||
/**
|
/**
|
||||||
* @deprecated 已废弃
|
|
||||||
*/
|
*/
|
||||||
bot: typeof Client.prototype;
|
bot: typeof Client.prototype;
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +51,11 @@ interface EventTypeGroup extends EventTypeBase, GroupMessage {
|
||||||
*/
|
*/
|
||||||
group_id: number;
|
group_id: number;
|
||||||
/**
|
/**
|
||||||
* @deprecated 已废弃
|
* 群名
|
||||||
|
*/
|
||||||
|
group_name:string
|
||||||
|
/**
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
group: {
|
group: {
|
||||||
is_owner: any;
|
is_owner: any;
|
||||||
|
|
188
src/init.ts
188
src/init.ts
|
@ -1,19 +1,88 @@
|
||||||
import fs, { promises } from 'node:fs'
|
import { existsSync } from 'fs'
|
||||||
|
import { join } from 'path'
|
||||||
|
import { configInit } from './config/config'
|
||||||
|
import { loggerInit } from './config/log'
|
||||||
|
import { BOT_NAME } from './config'
|
||||||
|
import { redisInit } from './config/redis'
|
||||||
|
import { promises } from 'node:fs'
|
||||||
import yaml from 'yaml'
|
import yaml from 'yaml'
|
||||||
import { join } from 'node:path'
|
import { CONFIG_INIT_PATH } from './config/system.js'
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
import { BOT_NAME, CONFIG_INIT_PATH } from './config/system.js'
|
|
||||||
import { createQQ } from './config/qq.js'
|
|
||||||
import { setLogger } from './config/log.js'
|
|
||||||
import { redisInit } from './config/redis.js'
|
|
||||||
import { checkRun } from './config/check.js'
|
import { checkRun } from './config/check.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查node_modules
|
||||||
|
*/
|
||||||
|
if (!existsSync(join(process.cwd(), './node_modules'))) {
|
||||||
|
console.log('未安装依赖。。。。')
|
||||||
|
console.log('请先运行命令:pnpm install -P 安装依赖')
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化配置
|
||||||
|
*/
|
||||||
|
configInit()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志初始化
|
||||||
|
*/
|
||||||
|
loggerInit()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async function UpdateTitle() {
|
logger.mark(`${BOT_NAME} 启动中...`)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化客户端
|
||||||
|
*/
|
||||||
|
await redisInit()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置标题
|
||||||
|
*/
|
||||||
|
process.title = BOT_NAME
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置时区
|
||||||
|
*/
|
||||||
|
process.env.TZ = 'Asia/Shanghai'
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
process.on('SIGHUP', () => process.exit())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获未处理的错误
|
||||||
|
*/
|
||||||
|
process.on('uncaughtException', error => {
|
||||||
|
if (typeof logger == 'undefined') console.log(error)
|
||||||
|
else logger.error(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获未处理的Promise错误
|
||||||
|
*/
|
||||||
|
process.on('unhandledRejection', error => {
|
||||||
|
if (typeof logger == 'undefined') console.log(error)
|
||||||
|
else logger.error(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出事件
|
||||||
|
*/
|
||||||
|
process.on('exit', async () => {
|
||||||
|
if (typeof redis != 'undefined') {
|
||||||
|
await redis.save()
|
||||||
|
}
|
||||||
|
if (typeof logger == 'undefined') {
|
||||||
|
console.log(`${BOT_NAME} 已停止运行`)
|
||||||
|
} else {
|
||||||
|
logger.mark(logger.magenta(`${BOT_NAME} 已停止运行`))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加一些多余的标题内容
|
* 添加一些多余的标题内容
|
||||||
*/
|
*/
|
||||||
|
@ -65,107 +134,8 @@ async function UpdateTitle() {
|
||||||
* 设置标题
|
* 设置标题
|
||||||
*/
|
*/
|
||||||
process.title = title
|
process.title = title
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化事件
|
|
||||||
*/
|
|
||||||
export async function checkInit() {
|
|
||||||
/**
|
|
||||||
* 检查node_modules
|
|
||||||
*/
|
|
||||||
if (!fs.existsSync(join(process.cwd(), './node_modules'))) {
|
|
||||||
console.log('未安装依赖。。。。')
|
|
||||||
console.log('请先运行命令:pnpm install -P 安装依赖')
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查node_modules/icqq
|
|
||||||
*/
|
|
||||||
if (!fs.existsSync(join(process.cwd(), './node_modules/icqq'))) {
|
|
||||||
console.log('未安装icqq。。。。')
|
|
||||||
console.log('请先运行命令:pnpm install -P 安装依赖')
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查qq.yaml
|
|
||||||
*/
|
|
||||||
await createQQ()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日志设置
|
|
||||||
*/
|
|
||||||
setLogger()
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
logger.mark(`${BOT_NAME} 启动中...`)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化客户端
|
|
||||||
*/
|
|
||||||
await redisInit()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查程序
|
* 检查程序
|
||||||
*/
|
*/
|
||||||
await checkRun()
|
await checkRun()
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新标题
|
|
||||||
*/
|
|
||||||
await UpdateTitle()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置标题
|
|
||||||
*/
|
|
||||||
process.title = BOT_NAME
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置时区
|
|
||||||
*/
|
|
||||||
process.env.TZ = 'Asia/Shanghai'
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
process.on('SIGHUP', () => process.exit())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 捕获未处理的错误
|
|
||||||
*/
|
|
||||||
process.on('uncaughtException', error => {
|
|
||||||
if (typeof logger == 'undefined') console.log(error)
|
|
||||||
else logger.error(error)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 捕获未处理的Promise错误
|
|
||||||
*/
|
|
||||||
process.on('unhandledRejection', error => {
|
|
||||||
if (typeof logger == 'undefined') console.log(error)
|
|
||||||
else logger.error(error)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 退出事件
|
|
||||||
*/
|
|
||||||
process.on('exit', async () => {
|
|
||||||
if (typeof redis != 'undefined') {
|
|
||||||
await redis.save()
|
|
||||||
}
|
|
||||||
if (typeof logger == 'undefined') {
|
|
||||||
console.log(`${BOT_NAME} 已停止运行`)
|
|
||||||
} else {
|
|
||||||
logger.mark(logger.magenta(`${BOT_NAME} 已停止运行`))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化
|
|
||||||
*/
|
|
||||||
await checkInit()
|
|
||||||
|
|
15
src/main.ts
15
src/main.ts
|
@ -1,14 +1,7 @@
|
||||||
/**
|
|
||||||
* **********
|
|
||||||
* 配置初始化
|
|
||||||
* **********
|
|
||||||
*/
|
|
||||||
import './init.js'
|
import './init.js'
|
||||||
/**
|
|
||||||
* 引入模块
|
|
||||||
*/
|
|
||||||
import { plugin, segment, Client } from './core/index.js'
|
import { plugin, segment, Client } from './core/index.js'
|
||||||
import { Renderer } from './utils/index.js'
|
import { Renderer } from './utils/index.js'
|
||||||
|
import { createQQ } from './config/qq.js'
|
||||||
/**
|
/**
|
||||||
* global.plugin
|
* global.plugin
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +14,13 @@ global.segment = segment
|
||||||
* global.Renderer
|
* global.Renderer
|
||||||
*/
|
*/
|
||||||
global.Renderer = Renderer
|
global.Renderer = Renderer
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setTimeout(async () => {
|
||||||
|
await createQQ()
|
||||||
/**
|
/**
|
||||||
* run
|
* run
|
||||||
*/
|
*/
|
||||||
await Client.run()
|
await Client.run()
|
||||||
|
}, 0)
|
||||||
|
|
|
@ -3,24 +3,16 @@ export * from './puppeteer.js'
|
||||||
export * from './types.js'
|
export * from './types.js'
|
||||||
export * from './common.js'
|
export * from './common.js'
|
||||||
export * from './component.js'
|
export * from './component.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 旧版本
|
* 旧版本兼容性方法
|
||||||
*/
|
*/
|
||||||
import puppeteer from './puppeteer/puppeteer.js'
|
import puppeteer from './puppeteer/puppeteer.js'
|
||||||
export { puppeteer }
|
export { puppeteer }
|
||||||
|
|
||||||
/**
|
|
||||||
* ********
|
|
||||||
*
|
|
||||||
* **********
|
|
||||||
*/
|
|
||||||
import renderer from './renderer/loader.js'
|
import renderer from './renderer/loader.js'
|
||||||
import Renderer from './renderer/Renderer.js'
|
import Renderer from './renderer/Renderer.js'
|
||||||
import renderers from './renderers/index.js'
|
import renderers from './renderers/index.js'
|
||||||
import Renderers from './renderers/puppeteer.js'
|
import Renderers from './renderers/puppeteer.js'
|
||||||
export { Renderers, renderers, Renderer, renderer }
|
export { Renderers, renderers, Renderer, renderer }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* puppeteer/
|
* puppeteer/
|
||||||
* renderer/
|
* renderer/
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import Renderer from '../renderer/loader.js'
|
import Renderer from '../renderer/loader.js'
|
||||||
|
/**
|
||||||
|
* @deprecated 已废弃
|
||||||
|
*/
|
||||||
const renderer = Renderer.getRenderer()
|
const renderer = Renderer.getRenderer()
|
||||||
renderer.screenshot = async (name, data) => {
|
renderer.screenshot = async (name, data) => {
|
||||||
let img = await renderer.render(name, data)
|
const img = await renderer.render(name, data)
|
||||||
return img ? segment.image(img) : img
|
return img ? segment.image(img) : img
|
||||||
}
|
}
|
||||||
renderer.screenshots = async (name, data) => {
|
renderer.screenshots = async (name, data) => {
|
||||||
data.multiPage = true
|
data.multiPage = true
|
||||||
let imgs = (await renderer.render(name, data)) || []
|
const imgs = (await renderer.render(name, data)) || []
|
||||||
let ret = []
|
const ret = []
|
||||||
for (let img of imgs) {
|
for (let img of imgs) {
|
||||||
ret.push(img ? segment.image(img) : img)
|
ret.push(img ? segment.image(img) : img)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import template from 'art-template'
|
import template from 'art-template'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import fs from 'node:fs'
|
import fs, { writeFileSync } from 'node:fs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated 已废弃
|
||||||
|
*/
|
||||||
export default class Renderer {
|
export default class Renderer {
|
||||||
id = null
|
id = null
|
||||||
type = null
|
type = null
|
||||||
|
@ -10,14 +14,13 @@ export default class Renderer {
|
||||||
dir = './temp/html'
|
dir = './temp/html'
|
||||||
html = {}
|
html = {}
|
||||||
watcher = {}
|
watcher = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染器
|
* 渲染器
|
||||||
* @param data.id 渲染器ID
|
* @param data.id 渲染器ID
|
||||||
* @param data.type 渲染器类型
|
* @param data.type 渲染器类型
|
||||||
* @param data.render 渲染器入口
|
* @param data.render 渲染器入口
|
||||||
*/
|
*/
|
||||||
constructor(data) {
|
constructor(data?: { id?: any; type?: any; render?: any }) {
|
||||||
/** 渲染器ID */
|
/** 渲染器ID */
|
||||||
this.id = data.id || 'renderer'
|
this.id = data.id || 'renderer'
|
||||||
/** 渲染器类型 */
|
/** 渲染器类型 */
|
||||||
|
@ -26,13 +29,12 @@ export default class Renderer {
|
||||||
this.render = this[data.render || 'render']
|
this.render = this[data.render || 'render']
|
||||||
this.createDir(this.dir)
|
this.createDir(this.dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建文件夹
|
* 创建文件夹
|
||||||
* @param dirname
|
* @param dirname
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
createDir(dirname) {
|
createDir(dirname: string) {
|
||||||
if (fs.existsSync(dirname)) {
|
if (fs.existsSync(dirname)) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
|
@ -42,7 +44,6 @@ export default class Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板
|
* 模板
|
||||||
* @param name
|
* @param name
|
||||||
|
@ -50,8 +51,8 @@ export default class Renderer {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
dealTpl(name, data) {
|
dealTpl(name, data) {
|
||||||
let { tplFile, saveId = name } = data
|
const { tplFile, saveId = name } = data
|
||||||
let savePath = `./temp/html/${name}/${saveId}.html`
|
const savePath = `./temp/html/${name}/${saveId}.html`
|
||||||
/** 读取html模板 */
|
/** 读取html模板 */
|
||||||
if (!this.html[tplFile]) {
|
if (!this.html[tplFile]) {
|
||||||
this.createDir(`./temp/html/${name}`)
|
this.createDir(`./temp/html/${name}`)
|
||||||
|
@ -63,18 +64,14 @@ export default class Renderer {
|
||||||
}
|
}
|
||||||
this.watch(tplFile)
|
this.watch(tplFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.resPath = `./resources/`
|
data.resPath = `./resources/`
|
||||||
|
|
||||||
/** 替换模板 */
|
/** 替换模板 */
|
||||||
let tmpHtml = template.render(this.html[tplFile], data)
|
const tmpHtml = template.render(this.html[tplFile], data)
|
||||||
|
|
||||||
/** 保存模板 */
|
/** 保存模板 */
|
||||||
fs.writeFileSync(savePath, tmpHtml)
|
writeFileSync(savePath, tmpHtml)
|
||||||
logger.debug(`[图片生成][使用模板] ${savePath}`)
|
logger.debug(`[图片生成][使用模板] ${savePath}`)
|
||||||
return savePath
|
return savePath
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听配置文件
|
* 监听配置文件
|
||||||
* @param tplFile
|
* @param tplFile
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# 如需自定义,复制此文件为 config.yaml 进行配置
|
|
||||||
# 更新配置后需要重启
|
|
||||||
|
|
||||||
# chromium 地址,可填写系统的edge/chromium路径,例如(根据实际情况调整):
|
|
||||||
# chromiumPath: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
|
|
||||||
chromiumPath:
|
|
||||||
|
|
||||||
# puppeteer websocket 地址。连接单独存在的 chromium。
|
|
||||||
# puppeteerWS: 'ws://browserless:3000'
|
|
||||||
puppeteerWS:
|
|
||||||
|
|
||||||
# headless
|
|
||||||
headless: 'new'
|
|
||||||
|
|
||||||
# puppeteer启动args,注意args的--前缀
|
|
||||||
args:
|
|
||||||
- --disable-gpu
|
|
||||||
- --disable-setuid-sandbox
|
|
||||||
- --no-sandbox
|
|
||||||
- --no-zygote
|
|
||||||
|
|
||||||
# puppeteer截图超时时间
|
|
||||||
puppeteerTimeout:
|
|
|
@ -2,26 +2,25 @@ import fs from 'node:fs'
|
||||||
import yaml from 'yaml'
|
import yaml from 'yaml'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { ConfigController as cfg } from '../../config/index.js'
|
import { ConfigController as cfg } from '../../config/index.js'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载渲染器
|
* 加载渲染器
|
||||||
|
* @deprecated 已废弃
|
||||||
*/
|
*/
|
||||||
class RendererLoader {
|
class RendererLoader {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
renderers = new Map()
|
renderers = new Map()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
dir = './renderers'
|
dir = './renderers'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
watcher = {}
|
watcher = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
|
@ -31,7 +30,6 @@ class RendererLoader {
|
||||||
await render.load()
|
await render.load()
|
||||||
return render
|
return render
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -39,15 +37,20 @@ class RendererLoader {
|
||||||
const subFolders = fs
|
const subFolders = fs
|
||||||
.readdirSync(this.dir, { withFileTypes: true })
|
.readdirSync(this.dir, { withFileTypes: true })
|
||||||
.filter(dirent => dirent.isDirectory())
|
.filter(dirent => dirent.isDirectory())
|
||||||
for (let subFolder of subFolders) {
|
for (const subFolder of subFolders) {
|
||||||
let name = subFolder.name
|
const name = subFolder.name
|
||||||
try {
|
try {
|
||||||
const rendererFn = await import('../renderers/index.js')
|
const rendererFn = await import('../renderers/index.js')
|
||||||
let configFile = `./config.yaml`
|
const configFile = join(
|
||||||
let rendererCfg = fs.existsSync(configFile)
|
process.cwd(),
|
||||||
|
'config',
|
||||||
|
'config',
|
||||||
|
'puppeteer.yaml'
|
||||||
|
)
|
||||||
|
const rendererCfg = fs.existsSync(configFile)
|
||||||
? yaml.parse(fs.readFileSync(configFile, 'utf8'))
|
? yaml.parse(fs.readFileSync(configFile, 'utf8'))
|
||||||
: {}
|
: {}
|
||||||
let renderer = rendererFn.default(rendererCfg)
|
const renderer = rendererFn.default(rendererCfg)
|
||||||
if (
|
if (
|
||||||
!renderer.id ||
|
!renderer.id ||
|
||||||
!renderer.type ||
|
!renderer.type ||
|
||||||
|
@ -64,7 +67,6 @@ class RendererLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
|
@ -74,10 +76,12 @@ class RendererLoader {
|
||||||
// TODO 渲染器降级
|
// TODO 渲染器降级
|
||||||
return this.renderers.get(name)
|
return this.renderers.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated 已废弃
|
||||||
|
*/
|
||||||
export default await RendererLoader.init()
|
export default await RendererLoader.init()
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
|
import { PuppeteerLaunchOptions } from 'puppeteer';
|
||||||
import Puppeteer from './puppeteer.js'
|
import Puppeteer from './puppeteer.js'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param config 本地config.yaml的配置内容
|
* @deprecated 已废弃
|
||||||
|
* @param config
|
||||||
* @returns renderer 渲染器对象
|
* @returns renderer 渲染器对象
|
||||||
* @returns renderer.id 渲染器ID,对应renderer中选择的id
|
* @returns renderer.id 渲染器ID,对应renderer中选择的id
|
||||||
* @returns renderer.type 渲染类型,保留字段,暂时支持image
|
* @returns renderer.type 渲染类型,保留字段,暂时支持image
|
||||||
* @returns renderer.render 渲染入口
|
* @returns renderer.render 渲染入口
|
||||||
*/
|
*/
|
||||||
export default function (config) {
|
export default function (config?: PuppeteerLaunchOptions & {
|
||||||
|
chromiumPath: string;
|
||||||
|
puppeteerWS: any;
|
||||||
|
puppeteerTimeout: any;
|
||||||
|
}) {
|
||||||
// TODO Puppeteer待简化重构
|
// TODO Puppeteer待简化重构
|
||||||
return new Puppeteer(config)
|
return new Puppeteer(config)
|
||||||
}
|
}
|
|
@ -1,15 +1,30 @@
|
||||||
import Renderer from "../renderer/Renderer.js"
|
|
||||||
import os from "node:os"
|
import os from "node:os"
|
||||||
import lodash from "lodash"
|
import lodash from "lodash"
|
||||||
import puppeteer, { Browser } from "puppeteer"
|
import puppeteer, { Browser, PuppeteerLaunchOptions } from "puppeteer"
|
||||||
// 暂时保留对原config的兼容
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import Renderer from "../renderer/Renderer.js"
|
||||||
|
/**
|
||||||
|
* 暂时保留对原config的兼容
|
||||||
|
*/
|
||||||
import { ConfigController as cfg } from "../../config/index.js"
|
import { ConfigController as cfg } from "../../config/index.js"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
|
|
||||||
// mac地址
|
|
||||||
|
/**
|
||||||
|
* mac地址
|
||||||
|
*/
|
||||||
let mac = ""
|
let mac = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @deprecated 已废弃
|
||||||
|
*/
|
||||||
export default class Puppeteer extends Renderer {
|
export default class Puppeteer extends Renderer {
|
||||||
browser: false | Browser = false
|
browser: false | Browser = false
|
||||||
lock = false
|
lock = false
|
||||||
|
@ -27,7 +42,11 @@ export default class Puppeteer extends Renderer {
|
||||||
*
|
*
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
constructor(config) {
|
constructor(config?: PuppeteerLaunchOptions & {
|
||||||
|
chromiumPath: string
|
||||||
|
puppeteerWS: any
|
||||||
|
puppeteerTimeout: any
|
||||||
|
}) {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -182,16 +201,16 @@ export default class Puppeteer extends Renderer {
|
||||||
* @param data.pageGotoParams 页面goto时的参数
|
* @param data.pageGotoParams 页面goto时的参数
|
||||||
* @return img 不做segment包裹
|
* @return img 不做segment包裹
|
||||||
*/
|
*/
|
||||||
async screenshot(name, data: any = {}) {
|
async screenshot(name:string, data: any = {}) {
|
||||||
if (!await this.browserInit())
|
if (!await this.browserInit())
|
||||||
return false
|
return false
|
||||||
const pageHeight = data.multiPageHeight || 4000
|
const pageHeight = data.multiPageHeight || 4000
|
||||||
|
|
||||||
let savePath = this.dealTpl(name, data)
|
const savePath = this.dealTpl(name, data)
|
||||||
if (!savePath) return false
|
if (!savePath) return false
|
||||||
|
|
||||||
let buff: any = ""
|
let buff: any = ""
|
||||||
let start = Date.now()
|
const start = Date.now()
|
||||||
|
|
||||||
let ret = []
|
let ret = []
|
||||||
this.shoting.push(name)
|
this.shoting.push(name)
|
||||||
|
@ -213,16 +232,16 @@ export default class Puppeteer extends Renderer {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const page = await this.browser.newPage()
|
const page = await this.browser.newPage()
|
||||||
let pageGotoParams = lodash.extend({ timeout: 120000 }, data.pageGotoParams || {})
|
const pageGotoParams = lodash.extend({ timeout: 120000 }, data.pageGotoParams || {})
|
||||||
await page.goto(`file://${_path}${lodash.trim(savePath, ".")}`, pageGotoParams)
|
await page.goto(`file://${_path}${lodash.trim(savePath, ".")}`, pageGotoParams)
|
||||||
let body = await page.$("#container") || await page.$("body")
|
const body = await page.$("#container") || await page.$("body")
|
||||||
|
|
||||||
// 计算页面高度
|
// 计算页面高度
|
||||||
const boundingBox = await body.boundingBox()
|
const boundingBox = await body.boundingBox()
|
||||||
// 分页数
|
// 分页数
|
||||||
let num = 1
|
let num = 1
|
||||||
|
|
||||||
let randData = {
|
const randData = {
|
||||||
type: data.imgType || "jpeg",
|
type: data.imgType || "jpeg",
|
||||||
omitBackground: data.omitBackground || false,
|
omitBackground: data.omitBackground || false,
|
||||||
quality: data.quality || 90,
|
quality: data.quality || 90,
|
||||||
|
@ -322,10 +341,10 @@ export default class Puppeteer extends Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 停止
|
||||||
* @param browser
|
* @param browser
|
||||||
*/
|
*/
|
||||||
async stop(browser) {
|
async stop(browser: Browser) {
|
||||||
try {
|
try {
|
||||||
await browser.close()
|
await browser.close()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
Loading…
Reference in New Issue