feat: 格式化&修正类型
This commit is contained in:
parent
94b0df3b23
commit
5e0c0dc756
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Node dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
|
||||||
|
# 旧版文件夹
|
||||||
|
config
|
||||||
|
docker
|
||||||
|
lib
|
||||||
|
plugins
|
||||||
|
renderers
|
||||||
|
|
||||||
|
# 旧版文件
|
||||||
|
|
||||||
|
CHANGELOG.md
|
||||||
|
docker-compose.yaml
|
||||||
|
miao.js
|
||||||
|
|
||||||
|
|
||||||
|
# 缓存目录
|
||||||
|
data
|
||||||
|
trss.js
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"semi": false,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 80,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": false,
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"endOfLine": "auto",
|
||||||
|
"quoteProps": "consistent",
|
||||||
|
"vueIndentScriptAndStyle": true
|
||||||
|
}
|
18
README.md
18
README.md
|
@ -12,19 +12,17 @@ git clone --depth=1 -b system https://github.com/yoimiya-kokomi/Miao-Yunzai.git
|
||||||
|
|
||||||
## 功能列表
|
## 功能列表
|
||||||
|
|
||||||
|
| 功能 | 指令 | 说明 |
|
||||||
| 功能 | 指令 | 说明 |
|
| ---- | ------------------- | ---- |
|
||||||
|-------| ----- |------ |
|
|
||||||
| 日志 | #更新日志 #运行日志 | 嘎嘎 |
|
| 日志 | #更新日志 #运行日志 | 嘎嘎 |
|
||||||
| 更新| #更新 #全部更新 | 嘎嘎 |
|
| 更新 | #更新 #全部更新 | 嘎嘎 |
|
||||||
| 状态 | #状态 | 嘎嘎 |
|
| 状态 | #状态 | 嘎嘎 |
|
||||||
| 运行 | #重启 #关机 | 嘎嘎 |
|
| 运行 | #重启 #关机 | 嘎嘎 |
|
||||||
| 娱乐 | #复读 | 嘎嘎|
|
| 娱乐 | #复读 | 嘎嘎 |
|
||||||
| 表情 | #添加xxx | 嘎嘎|
|
| 表情 | #添加xxx | 嘎嘎 |
|
||||||
|
|
||||||
|
|
||||||
## 图片开发
|
## 图片开发
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run image
|
npm run image
|
||||||
```
|
```
|
||||||
|
|
293
apps/add.ts
293
apps/add.ts
|
@ -1,10 +1,17 @@
|
||||||
|
import {
|
||||||
import fs from 'node:fs'
|
createWriteStream,
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
readdirSync,
|
||||||
|
unlink,
|
||||||
|
writeFileSync
|
||||||
|
} from 'node:fs'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { pipeline } from 'stream'
|
|
||||||
import { promisify } from 'util'
|
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
import { pipeline } from 'stream'
|
||||||
|
import { promisify } from 'util'
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
import { makeForwardMsg } from 'yunzai/core'
|
import { makeForwardMsg } from 'yunzai/core'
|
||||||
|
@ -18,15 +25,16 @@ export class add extends Plugin {
|
||||||
path = './data/textJson/'
|
path = './data/textJson/'
|
||||||
facePath = './data/face/'
|
facePath = './data/face/'
|
||||||
isGlobal = false
|
isGlobal = false
|
||||||
|
keyWord = null
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
name: '添加表情',
|
name: '添加表情',
|
||||||
dsc: '添加表情,文字等',
|
dsc: '添加表情,文字等',
|
||||||
*/
|
*/
|
||||||
super();
|
super()
|
||||||
this.priority = 50000
|
this.priority = 50000
|
||||||
this.rule = [
|
this.rule = [
|
||||||
{
|
{
|
||||||
|
@ -49,46 +57,49 @@ export class add extends Plugin {
|
||||||
{
|
{
|
||||||
reg: /#(全局)?(表情|词条)(.*)/,
|
reg: /#(全局)?(表情|词条)(.*)/,
|
||||||
fnc: this.list.name
|
fnc: this.list.name
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
/** 处理消息 */
|
/** 处理消息 */
|
||||||
if (this.e.atBot && this.e.msg && this.e?.msg.includes('添加') && !this.e?.msg.includes('#')) {
|
if (
|
||||||
|
this.e.atBot &&
|
||||||
|
this.e.msg &&
|
||||||
|
this.e?.msg.includes('添加') &&
|
||||||
|
!this.e?.msg.includes('#')
|
||||||
|
) {
|
||||||
this.e.msg = '#' + this.e.msg
|
this.e.msg = '#' + this.e.msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async init() {
|
async init() {
|
||||||
if (!fs.existsSync(this.path)) {
|
if (!existsSync(this.path)) {
|
||||||
fs.mkdirSync(this.path)
|
mkdirSync(this.path)
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(this.facePath)) {
|
if (!existsSync(this.facePath)) {
|
||||||
fs.mkdirSync(this.facePath)
|
mkdirSync(this.facePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
get grpKey() {
|
get grpKey() {
|
||||||
return `Yz:group_id:${this.e.user_id}`
|
return `Yz:group_id:${this.e.user_id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async add() {
|
async add() {
|
||||||
this.isGlobal = this.e?.msg.includes("全局");
|
this.isGlobal = this.e?.msg.includes('全局')
|
||||||
await this.getGroupId()
|
await this.getGroupId()
|
||||||
|
|
||||||
if (!this.group_id) {
|
if (!this.group_id) {
|
||||||
|
@ -119,13 +130,13 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async getGroupId() {
|
async getGroupId() {
|
||||||
/** 添加全局表情,存入到机器人qq文件中 */
|
/** 添加全局表情,存入到机器人qq文件中 */
|
||||||
if (this.isGlobal) {
|
if (this.isGlobal) {
|
||||||
this.group_id = this.e.bot.uin;
|
this.group_id = this.e.bot.uin
|
||||||
return this.e.bot.uin;
|
return this.e.bot.uin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.e.isGroup) {
|
if (this.e.isGroup) {
|
||||||
|
@ -137,7 +148,7 @@ export class add extends Plugin {
|
||||||
// redis获取
|
// redis获取
|
||||||
let groupId = await redis.get(this.grpKey)
|
let groupId = await redis.get(this.grpKey)
|
||||||
if (groupId) {
|
if (groupId) {
|
||||||
this.group_id = groupId
|
this.group_id = Number(groupId)
|
||||||
return this.group_id
|
return this.group_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +156,7 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
checkAuth() {
|
checkAuth() {
|
||||||
if (this.e.isMaster) return true
|
if (this.e.isMaster) return true
|
||||||
|
@ -177,7 +188,7 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
checkKeyWord() {
|
checkKeyWord() {
|
||||||
if (this.e.img && this.e.img.length > 1) {
|
if (this.e.img && this.e.img.length > 1) {
|
||||||
|
@ -186,7 +197,9 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.e.at) {
|
if (this.e.at) {
|
||||||
let at = lodash.filter(this.e.message, (o) => { return o.type == 'at' && o.qq != this.e.bot.uin })
|
let at = lodash.filter(this.e.message, o => {
|
||||||
|
return o.type == 'at' && o.qq != this.e.bot.uin
|
||||||
|
})
|
||||||
if (at.length > 1) {
|
if (at.length > 1) {
|
||||||
this.e.reply('添加错误:只能@一个人当关键词')
|
this.e.reply('添加错误:只能@一个人当关键词')
|
||||||
return false
|
return false
|
||||||
|
@ -203,7 +216,7 @@ export class add extends Plugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单独添加
|
* 单独添加
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async singleAdd() {
|
async singleAdd() {
|
||||||
if (this.e.message.length != 2) return false
|
if (this.e.message.length != 2) return false
|
||||||
|
@ -211,7 +224,7 @@ export class add extends Plugin {
|
||||||
if (!this.e.msg || !msg.image) return false
|
if (!this.e.msg || !msg.image) return false
|
||||||
|
|
||||||
// #全局添加文字+表情包,无法正确添加到全局路径
|
// #全局添加文字+表情包,无法正确添加到全局路径
|
||||||
this.e.isGlobal = this.isGlobal;
|
this.e.isGlobal = this.isGlobal
|
||||||
let keyWord = this.e.msg.replace(/#|#|图片|表情|添加|全局/g, '').trim()
|
let keyWord = this.e.msg.replace(/#|#|图片|表情|添加|全局/g, '').trim()
|
||||||
if (!keyWord) return false
|
if (!keyWord) return false
|
||||||
|
|
||||||
|
@ -231,9 +244,10 @@ export class add extends Plugin {
|
||||||
* 获取添加关键词
|
* 获取添加关键词
|
||||||
*/
|
*/
|
||||||
getKeyWord() {
|
getKeyWord() {
|
||||||
this.e.isGlobal = this.e.msg.includes("全局");
|
this.e.isGlobal = this.e.msg.includes('全局')
|
||||||
|
|
||||||
this.keyWord = this.e.toString()
|
this.keyWord = this.e
|
||||||
|
.toString()
|
||||||
.trim()
|
.trim()
|
||||||
/** 过滤#添加 */
|
/** 过滤#添加 */
|
||||||
.replace(/#|#|图片|表情|添加|删除|全局/g, '')
|
.replace(/#|#|图片|表情|添加|删除|全局/g, '')
|
||||||
|
@ -251,8 +265,8 @@ export class add extends Plugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 过滤别名
|
* 过滤别名
|
||||||
* @param msg
|
* @param msg
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
trimAlias(msg) {
|
trimAlias(msg) {
|
||||||
let groupCfg = cfg.getGroup(this.group_id)
|
let groupCfg = cfg.getGroup(this.group_id)
|
||||||
|
@ -271,10 +285,10 @@ export class add extends Plugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加内容
|
* 添加内容
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async addContext() {
|
async addContext() {
|
||||||
this.isGlobal = this.e.isGlobal || this.getContext()?.addContext?.isGlobal;
|
this.isGlobal = this.e.isGlobal || this.getContext()?.addContext?.isGlobal
|
||||||
await this.getGroupId()
|
await this.getGroupId()
|
||||||
/** 关键词 */
|
/** 关键词 */
|
||||||
let keyWord = this.keyWord || this.getContext()?.addContext?.keyWord
|
let keyWord = this.keyWord || this.getContext()?.addContext?.keyWord
|
||||||
|
@ -287,23 +301,23 @@ export class add extends Plugin {
|
||||||
this.finish('addContext')
|
this.finish('addContext')
|
||||||
|
|
||||||
for (let i in message) {
|
for (let i in message) {
|
||||||
if (message[i].type == "at") {
|
if (message[i].type == 'at') {
|
||||||
if (message[i].qq == this.e.bot.uin) {
|
if (message[i].qq == this.e.bot.uin) {
|
||||||
this.e.reply("添加内容不能@机器人!");
|
this.e.reply('添加内容不能@机器人!')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message[i].type == "file") {
|
if (message[i].type == 'file') {
|
||||||
this.e.reply("添加错误:禁止添加文件");
|
this.e.reply('添加错误:禁止添加文件')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存用户信息用于追溯添加者
|
// 保存用户信息用于追溯添加者
|
||||||
message[i].from_user = {
|
message[i].from_user = {
|
||||||
card: this.e.sender.card,
|
card: this.e.sender.card,
|
||||||
nickname: this.e.sender.nickname,
|
nickname: this.e.sender.nickname,
|
||||||
user_id: this.e.sender.user_id,
|
user_id: this.e.sender.user_id
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.length == 1 && message[0].type == 'image') {
|
if (message.length == 1 && message[0].type == 'image') {
|
||||||
|
@ -338,10 +352,10 @@ export class add extends Plugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加成功回复消息
|
* 添加成功回复消息
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getRetMsg() {
|
getRetMsg() {
|
||||||
let retMsg = this.getContext()
|
const retMsg = this.getContext()
|
||||||
let msg = ''
|
let msg = ''
|
||||||
if (retMsg?.addContext?.message) {
|
if (retMsg?.addContext?.message) {
|
||||||
msg = retMsg.addContext.message
|
msg = retMsg.addContext.message
|
||||||
|
@ -349,7 +363,9 @@ export class add extends Plugin {
|
||||||
for (let i in msg) {
|
for (let i in msg) {
|
||||||
if (msg[i].type == 'text' && msg[i].text.includes('添加')) {
|
if (msg[i].type == 'text' && msg[i].text.includes('添加')) {
|
||||||
msg[i].text = this.trimAlias(msg[i].text)
|
msg[i].text = this.trimAlias(msg[i].text)
|
||||||
msg[i].text = msg[i].text.trim().replace(/#|#|图片|表情|添加|全局/g, '')
|
msg[i].text = msg[i].text
|
||||||
|
.trim()
|
||||||
|
.replace(/#|#|图片|表情|添加|全局/g, '')
|
||||||
if (!msg[i].text) delete msg[i]
|
if (!msg[i].text) delete msg[i]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -370,7 +386,7 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
saveJson() {
|
saveJson() {
|
||||||
let obj = {}
|
let obj = {}
|
||||||
|
@ -378,36 +394,39 @@ export class add extends Plugin {
|
||||||
obj[k] = v
|
obj[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(`${this.path}${this.group_id}.json`, JSON.stringify(obj, '', '\t'))
|
writeFileSync(
|
||||||
|
`${this.path}${this.group_id}.json`,
|
||||||
|
JSON.stringify(obj, '', '\t')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
saveGlobalJson() {
|
saveGlobalJson() {
|
||||||
let obj = {};
|
let obj = {}
|
||||||
for (let [k, v] of textArr[this.e.bot.uin]) {
|
for (let [k, v] of textArr[this.e.bot.uin]) {
|
||||||
obj[k] = v;
|
obj[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(
|
writeFileSync(
|
||||||
`${this.path}${this.e.bot.uin}.json`,
|
`${this.path}${this.e.bot.uin}.json`,
|
||||||
JSON.stringify(obj, "", "\t")
|
JSON.stringify(obj, '', '\t')
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* @param keyWord
|
* @param keyWord
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async saveImg(url, keyWord) {
|
async saveImg(url, keyWord) {
|
||||||
let groupCfg = cfg.getGroup(this.group_id)
|
let groupCfg = cfg.getGroup(this.group_id)
|
||||||
let savePath = `${this.facePath}${this.group_id}/`
|
let savePath = `${this.facePath}${this.group_id}/`
|
||||||
|
|
||||||
if (!fs.existsSync(savePath)) {
|
if (!existsSync(savePath)) {
|
||||||
fs.mkdirSync(savePath)
|
mkdirSync(savePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
|
@ -428,21 +447,21 @@ export class add extends Plugin {
|
||||||
let type = response.headers.get('content-type').split('/')[1]
|
let type = response.headers.get('content-type').split('/')[1]
|
||||||
if (type == 'jpeg') type = 'jpg'
|
if (type == 'jpeg') type = 'jpg'
|
||||||
|
|
||||||
if (fs.existsSync(`${savePath}${keyWord}.${type}`)) {
|
if (existsSync(`${savePath}${keyWord}.${type}`)) {
|
||||||
keyWord = `${keyWord}_${moment().format('X')}`
|
keyWord = `${keyWord}_${moment().format('X')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
savePath = `${savePath}${keyWord}.${type}`
|
savePath = `${savePath}${keyWord}.${type}`
|
||||||
|
|
||||||
const streamPipeline = promisify(pipeline)
|
const streamPipeline = promisify(pipeline)
|
||||||
await streamPipeline(response.body, fs.createWriteStream(savePath))
|
await streamPipeline(response.body, createWriteStream(savePath))
|
||||||
|
|
||||||
return savePath
|
return savePath
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async getText() {
|
async getText() {
|
||||||
if (!this.e.message) return false
|
if (!this.e.message) return false
|
||||||
|
@ -457,7 +476,8 @@ export class add extends Plugin {
|
||||||
|
|
||||||
this.initGlobalTextArr()
|
this.initGlobalTextArr()
|
||||||
|
|
||||||
let keyWord = this.e.toString()
|
let keyWord = this.e
|
||||||
|
.toString()
|
||||||
.replace(/#|#/g, '')
|
.replace(/#|#/g, '')
|
||||||
.replace(`{at:${this.e.bot.uin}}`, '')
|
.replace(`{at:${this.e.bot.uin}}`, '')
|
||||||
.trim()
|
.trim()
|
||||||
|
@ -468,7 +488,11 @@ export class add extends Plugin {
|
||||||
if (isNaN(keyWord)) {
|
if (isNaN(keyWord)) {
|
||||||
num = keyWord.trim().match(/[0-9]+$/)?.[0]
|
num = keyWord.trim().match(/[0-9]+$/)?.[0]
|
||||||
|
|
||||||
if (!isNaN(num) && !textArr[this.group_id].has(keyWord) && !textArr[this.e.bot.uin].has(keyWord)) {
|
if (
|
||||||
|
!isNaN(num) &&
|
||||||
|
!textArr[this.group_id].has(keyWord) &&
|
||||||
|
!textArr[this.e.bot.uin].has(keyWord)
|
||||||
|
) {
|
||||||
keyWord = lodash.trimEnd(keyWord, num).trim()
|
keyWord = lodash.trimEnd(keyWord, num).trim()
|
||||||
num--
|
num--
|
||||||
}
|
}
|
||||||
|
@ -489,7 +513,7 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg[0] && msg[0].local) {
|
if (msg[0] && msg[0].local) {
|
||||||
if (fs.existsSync(msg[0].local)) {
|
if (existsSync(msg[0].local)) {
|
||||||
let tmp = segment.image(msg[0].local)
|
let tmp = segment.image(msg[0].local)
|
||||||
tmp.asface = msg[0].asface
|
tmp.asface = msg[0].asface
|
||||||
msg = tmp
|
msg = tmp
|
||||||
|
@ -502,7 +526,9 @@ export class add extends Plugin {
|
||||||
if (Array.isArray(msg)) {
|
if (Array.isArray(msg)) {
|
||||||
msg.forEach(m => {
|
msg.forEach(m => {
|
||||||
/** 去除回复@@ */
|
/** 去除回复@@ */
|
||||||
if (m?.type == 'at') { delete m.text }
|
if (m?.type == 'at') {
|
||||||
|
delete m.text
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,9 +542,9 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param keyWord
|
* @param keyWord
|
||||||
* @param num
|
* @param num
|
||||||
*/
|
*/
|
||||||
expiredMsg(keyWord, num) {
|
expiredMsg(keyWord, num) {
|
||||||
logger.mark(`[发送表情]${this.e.logText} ${keyWord} 表情已过期失效`)
|
logger.mark(`[发送表情]${this.e.logText} ${keyWord} 表情已过期失效`)
|
||||||
|
@ -537,7 +563,7 @@ export class add extends Plugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化已添加内容
|
* 初始化已添加内容
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
initTextArr() {
|
initTextArr() {
|
||||||
if (textArr[this.group_id]) return
|
if (textArr[this.group_id]) return
|
||||||
|
@ -545,12 +571,12 @@ export class add extends Plugin {
|
||||||
textArr[this.group_id] = new Map()
|
textArr[this.group_id] = new Map()
|
||||||
|
|
||||||
let path = `${this.path}${this.group_id}.json`
|
let path = `${this.path}${this.group_id}.json`
|
||||||
if (!fs.existsSync(path)) {
|
if (!existsSync(path)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let text = JSON.parse(fs.readFileSync(path, 'utf8'))
|
let text = JSON.parse(readFileSync(path, 'utf8'))
|
||||||
for (let i in text) {
|
for (let i in text) {
|
||||||
if (text[i][0] && !Array.isArray(text[i][0])) {
|
if (text[i][0] && !Array.isArray(text[i][0])) {
|
||||||
text[i] = [text[i]]
|
text[i] = [text[i]]
|
||||||
|
@ -567,8 +593,10 @@ export class add extends Plugin {
|
||||||
/** 加载表情 */
|
/** 加载表情 */
|
||||||
let facePath = `${this.facePath}${this.group_id}`
|
let facePath = `${this.facePath}${this.group_id}`
|
||||||
|
|
||||||
if (fs.existsSync(facePath)) {
|
if (existsSync(facePath)) {
|
||||||
const files = fs.readdirSync(`${this.facePath}${this.group_id}`).filter(file => /\.(jpeg|jpg|png|gif)$/g.test(file))
|
const files = readdirSync(`${this.facePath}${this.group_id}`).filter(
|
||||||
|
file => /\.(jpeg|jpg|png|gif)$/g.test(file)
|
||||||
|
)
|
||||||
for (let val of files) {
|
for (let val of files) {
|
||||||
let tmp = val.split('.')
|
let tmp = val.split('.')
|
||||||
tmp[0] = tmp[0].replace(/_[0-9]{10}$/, '')
|
tmp[0] = tmp[0].replace(/_[0-9]{10}$/, '')
|
||||||
|
@ -576,91 +604,97 @@ export class add extends Plugin {
|
||||||
|
|
||||||
if (textArr[this.group_id].has(tmp[0])) continue
|
if (textArr[this.group_id].has(tmp[0])) continue
|
||||||
|
|
||||||
textArr[this.group_id].set(tmp[0], [[{
|
textArr[this.group_id].set(tmp[0], [
|
||||||
local: `${facePath}/${val}`,
|
[
|
||||||
asface: true
|
{
|
||||||
}]])
|
local: `${facePath}/${val}`,
|
||||||
|
asface: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
this.saveJson()
|
this.saveJson()
|
||||||
} else {
|
} else {
|
||||||
fs.mkdirSync(facePath)
|
mkdirSync(facePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化全局已添加内容
|
* 初始化全局已添加内容
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
initGlobalTextArr() {
|
initGlobalTextArr() {
|
||||||
if (textArr[this.e.bot.uin]) return;
|
if (textArr[this.e.bot.uin]) return
|
||||||
|
|
||||||
textArr[this.e.bot.uin] = new Map();
|
textArr[this.e.bot.uin] = new Map()
|
||||||
|
|
||||||
let globalPath = `${this.path}${this.e.bot.uin}.json`;
|
let globalPath = `${this.path}${this.e.bot.uin}.json`
|
||||||
if (!fs.existsSync(globalPath)) {
|
if (!existsSync(globalPath)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let text = JSON.parse(fs.readFileSync(globalPath, "utf8"));
|
let text = JSON.parse(readFileSync(globalPath, 'utf8'))
|
||||||
|
|
||||||
for (let i in text) {
|
for (let i in text) {
|
||||||
if (text[i][0] && !Array.isArray(text[i][0])) {
|
if (text[i][0] && !Array.isArray(text[i][0])) {
|
||||||
text[i] = [text[i]];
|
text[i] = [text[i]]
|
||||||
}
|
}
|
||||||
textArr[this.e.bot.uin].set(String(i), text[i]);
|
textArr[this.e.bot.uin].set(String(i), text[i])
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`json格式错误:${globalPath}`);
|
logger.error(`json格式错误:${globalPath}`)
|
||||||
delete textArr[this.e.bot.uin];
|
delete textArr[this.e.bot.uin]
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 加载表情 */
|
/** 加载表情 */
|
||||||
let globalFacePath = `${this.facePath}${this.e.bot.uin}`;
|
let globalFacePath = `${this.facePath}${this.e.bot.uin}`
|
||||||
|
|
||||||
if (fs.existsSync(globalFacePath)) {
|
if (existsSync(globalFacePath)) {
|
||||||
const files = fs
|
const files = fs
|
||||||
.readdirSync(`${this.facePath}${this.e.bot.uin}`)
|
.readdirSync(`${this.facePath}${this.e.bot.uin}`)
|
||||||
.filter((file) => /\.(jpeg|jpg|png|gif)$/g.test(file));
|
.filter(file => /\.(jpeg|jpg|png|gif)$/g.test(file))
|
||||||
|
|
||||||
for (let val of files) {
|
for (let val of files) {
|
||||||
let tmp = val.split(".");
|
let tmp = val.split('.')
|
||||||
tmp[0] = tmp[0].replace(/_[0-9]{10}$/, "");
|
tmp[0] = tmp[0].replace(/_[0-9]{10}$/, '')
|
||||||
if (/at|image/g.test(val)) continue;
|
if (/at|image/g.test(val)) continue
|
||||||
|
|
||||||
if (textArr[this.e.bot.uin].has(tmp[0])) continue;
|
if (textArr[this.e.bot.uin].has(tmp[0])) continue
|
||||||
|
|
||||||
textArr[this.e.bot.uin].set(tmp[0], [
|
textArr[this.e.bot.uin].set(tmp[0], [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
local: `${globalFacePath}/${val}`,
|
local: `${globalFacePath}/${val}`,
|
||||||
asface: true,
|
asface: true
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
this.saveGlobalJson();
|
this.saveGlobalJson()
|
||||||
} else {
|
} else {
|
||||||
fs.mkdirSync(globalFacePath);
|
mkdirSync(globalFacePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async del() {
|
async del() {
|
||||||
this.isGlobal = this.e?.msg.includes("全局");
|
this.isGlobal = this.e?.msg.includes('全局')
|
||||||
await this.getGroupId()
|
await this.getGroupId()
|
||||||
if (!this.group_id) return false
|
if (!this.group_id) return false
|
||||||
if (!this.checkAuth()) return
|
if (!this.checkAuth()) return
|
||||||
|
|
||||||
this.initTextArr()
|
this.initTextArr()
|
||||||
|
|
||||||
let keyWord = this.e.toString().replace(/#|#|图片|表情|删除|全部|全局/g, '')
|
let keyWord = this.e
|
||||||
|
.toString()
|
||||||
|
.replace(/#|#|图片|表情|删除|全部|全局/g, '')
|
||||||
|
|
||||||
keyWord = this.trimAlias(keyWord)
|
keyWord = this.trimAlias(keyWord)
|
||||||
|
|
||||||
|
@ -736,7 +770,7 @@ export class add extends Plugin {
|
||||||
img = item[0]
|
img = item[0]
|
||||||
}
|
}
|
||||||
if (img.local) {
|
if (img.local) {
|
||||||
fs.unlink(img.local, () => { })
|
unlink(img.local, () => {})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -744,10 +778,10 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async list() {
|
async list() {
|
||||||
this.isGlobal = this.e?.msg.includes("全局");
|
this.isGlobal = this.e?.msg.includes('全局')
|
||||||
|
|
||||||
let page = 1
|
let page = 1
|
||||||
let pageSize = 100
|
let pageSize = 100
|
||||||
|
@ -794,7 +828,9 @@ export class add extends Plugin {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = [], result = [], num = 0
|
let msg = [],
|
||||||
|
result = [],
|
||||||
|
num = 0
|
||||||
for (let i in arr) {
|
for (let i in arr) {
|
||||||
if (num >= page * pageSize) break
|
if (num >= page * pageSize) break
|
||||||
|
|
||||||
|
@ -816,11 +852,11 @@ export class add extends Plugin {
|
||||||
result.push([msg[i]])
|
result.push([msg[i]])
|
||||||
}
|
}
|
||||||
/** 计算页数 */
|
/** 计算页数 */
|
||||||
let book = count / pageSize;
|
let book = count / pageSize
|
||||||
if (book % 1 === 0) {
|
if (book % 1 === 0) {
|
||||||
book = result;
|
book = result
|
||||||
} else {
|
} else {
|
||||||
book = Math.floor(book) + 1;
|
book = Math.floor(book) + 1
|
||||||
}
|
}
|
||||||
if (type == 'list' && msg.length >= pageSize) {
|
if (type == 'list' && msg.length >= pageSize) {
|
||||||
result.push(`更多内容请翻页查看\n如:#表情列表${Number(page) + 1}`)
|
result.push(`更多内容请翻页查看\n如:#表情列表${Number(page) + 1}`)
|
||||||
|
@ -837,17 +873,19 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
pagination(pageNo, pageSize, array) {
|
pagination(pageNo, pageSize, array) {
|
||||||
let offset = (pageNo - 1) * pageSize
|
let offset = (pageNo - 1) * pageSize
|
||||||
return offset + pageSize >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + pageSize)
|
return offset + pageSize >= array.length
|
||||||
|
? array.slice(offset, array.length)
|
||||||
|
: array.slice(offset, offset + pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关键词转换成可发送消息
|
* 关键词转换成可发送消息
|
||||||
* @param msg
|
* @param msg
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async keyWordTran(msg) {
|
async keyWordTran(msg) {
|
||||||
/** 图片 */
|
/** 图片 */
|
||||||
|
@ -864,7 +902,9 @@ export class add extends Plugin {
|
||||||
|
|
||||||
for (let qq of tmp) {
|
for (let qq of tmp) {
|
||||||
qq = qq.match(/[1-9][0-9]{4,14}/g)[0]
|
qq = qq.match(/[1-9][0-9]{4,14}/g)[0]
|
||||||
let member = await await this.e.bot.getGroupMemberInfo(this.group_id, Number(qq)).catch(() => { })
|
let member = await await this.e.bot
|
||||||
|
.getGroupMemberInfo(this.group_id, Number(qq))
|
||||||
|
.catch(() => {})
|
||||||
let name = member?.card ?? member?.nickname
|
let name = member?.card ?? member?.nickname
|
||||||
if (!name) continue
|
if (!name) continue
|
||||||
msg = msg.replace(`{at:${qq}}`, `@${name}`)
|
msg = msg.replace(`{at:${qq}}`, `@${name}`)
|
||||||
|
@ -883,8 +923,8 @@ export class add extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async faceDetail() {
|
async faceDetail() {
|
||||||
if (!this.e.message) return false
|
if (!this.e.message) return false
|
||||||
|
@ -913,7 +953,6 @@ export class add extends Plugin {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// process faces into replyArr in type:
|
// process faces into replyArr in type:
|
||||||
let replyArr = []
|
let replyArr = []
|
||||||
for (let i = 0; i < faces.length; i++) {
|
for (let i = 0; i < faces.length; i++) {
|
||||||
|
@ -944,7 +983,11 @@ export class add extends Plugin {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let forwardMsg = await makeForwardMsg(this.e, replyArr, `表情${keyWord}详情`)
|
let forwardMsg = await makeForwardMsg(
|
||||||
|
this.e,
|
||||||
|
replyArr,
|
||||||
|
`表情${keyWord}详情`
|
||||||
|
)
|
||||||
|
|
||||||
this.e.reply(forwardMsg)
|
this.e.reply(forwardMsg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
|
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
export class disFriPoke extends Plugin {
|
export class disFriPoke extends Plugin {
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
name: '禁止私聊',
|
name: '禁止私聊',
|
||||||
dsc: '对私聊禁用做处理当开启私聊禁用时只接收cookie以及抽卡链接',
|
dsc: '对私聊禁用做处理当开启私聊禁用时只接收cookie以及抽卡链接',
|
||||||
*/
|
*/
|
||||||
super()
|
super()
|
||||||
this.event = 'notice.friend.poke'
|
this.event = 'notice.friend.poke'
|
||||||
this.priority = 0
|
this.priority = 0
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* default
|
* default
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
if (!cfg.other?.disablePrivate) return
|
if (!cfg.other?.disablePrivate) return
|
||||||
if (this.e.isMaster) return
|
if (this.e.isMaster) return
|
||||||
this.e.reply(cfg.other.disableMsg)
|
this.e.reply(cfg.other.disableMsg)
|
||||||
return 'return'
|
return 'return'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class disPri extends Plugin {
|
export class disPri extends Plugin {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -19,8 +18,8 @@ export class disPri extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
if (!cfg.other?.disablePrivate) return
|
if (!cfg.other?.disablePrivate) return
|
||||||
|
@ -29,7 +28,7 @@ export class disPri extends Plugin {
|
||||||
|
|
||||||
/** 发送日志文件,xlsx,json */
|
/** 发送日志文件,xlsx,json */
|
||||||
if (this.e.file) {
|
if (this.e.file) {
|
||||||
if (!/(.*)\.txt|xlsx|json/ig.test(this.e.file?.name)) {
|
if (!/(.*)\.txt|xlsx|json/gi.test(this.e.file?.name)) {
|
||||||
this.sendTips()
|
this.sendTips()
|
||||||
return 'return'
|
return 'return'
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,16 +37,21 @@ export class disPri extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 绑定ck,抽卡链接 */
|
/** 绑定ck,抽卡链接 */
|
||||||
let wordReg = /(.*)(ltoken|_MHYUUID|authkey=)(.*)|导出记录(json)*|(记录|安卓|苹果|ck|cookie|体力)帮助|^帮助$|^#*(删除|我的)ck$|^#(我的)?(uid|UID)[0-9]{0,2}$/g
|
let wordReg =
|
||||||
|
/(.*)(ltoken|_MHYUUID|authkey=)(.*)|导出记录(json)*|(记录|安卓|苹果|ck|cookie|体力)帮助|^帮助$|^#*(删除|我的)ck$|^#(我的)?(uid|UID)[0-9]{0,2}$/g
|
||||||
/** 自定义通行字符 */
|
/** 自定义通行字符 */
|
||||||
let disableAdopt = cfg.other?.disableAdopt
|
let disableAdopt = cfg.other?.disableAdopt
|
||||||
if (!Array.isArray(disableAdopt)) {
|
if (!Array.isArray(disableAdopt)) {
|
||||||
disableAdopt = []
|
disableAdopt = []
|
||||||
}
|
}
|
||||||
disableAdopt = disableAdopt.filter(str => str != null && str !== '');
|
disableAdopt = disableAdopt.filter(str => str != null && str !== '')
|
||||||
let disableReg = `(.*)(${disableAdopt.join('|')})(.*)`
|
let disableReg = `(.*)(${disableAdopt.join('|')})(.*)`
|
||||||
if (this.e.raw_message) {
|
if (this.e.raw_message) {
|
||||||
if (!new RegExp(wordReg).test(this.e.raw_message) && (disableAdopt.length === 0 || !new RegExp(disableReg).test(this.e.raw_message))) {
|
if (
|
||||||
|
!new RegExp(wordReg).test(this.e.raw_message) &&
|
||||||
|
(disableAdopt.length === 0 ||
|
||||||
|
!new RegExp(disableReg).test(this.e.raw_message))
|
||||||
|
) {
|
||||||
this.sendTips()
|
this.sendTips()
|
||||||
return 'return'
|
return 'return'
|
||||||
}
|
}
|
||||||
|
@ -55,8 +59,8 @@ export class disPri extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async sendTips() {
|
async sendTips() {
|
||||||
/** 冷却cd 10s */
|
/** 冷却cd 10s */
|
||||||
|
@ -72,4 +76,4 @@ export class disPri extends Plugin {
|
||||||
|
|
||||||
redis.setEx(key, cd, '1')
|
redis.setEx(key, cd, '1')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
|
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { sleep } from 'yunzai/utils'
|
import { sleep } from 'yunzai/utils'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class friend extends Plugin {
|
export class friend extends Plugin {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -16,18 +15,18 @@ export class friend extends Plugin {
|
||||||
dsc: '自动同意好友',
|
dsc: '自动同意好友',
|
||||||
*/
|
*/
|
||||||
super()
|
super()
|
||||||
this.event = 'request.friend'
|
this.event = 'request.friend'
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (this.e.sub_type == 'add' || this.e.sub_type == 'single') {
|
if (this.e.sub_type == 'add' || this.e.sub_type == 'single') {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (cfg.other.autoFriend == 1) {
|
if (cfg.other.autoFriend == 1) {
|
||||||
logger.mark(`[自动同意][添加好友] ${this.e.user_id}`)
|
logger.mark(`[自动同意][添加好友] ${this.e.user_id}`)
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class invite extends Plugin {
|
export class invite extends Plugin {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -15,17 +14,17 @@ export class invite extends Plugin {
|
||||||
dsc: '主人邀请自动进群',
|
dsc: '主人邀请自动进群',
|
||||||
*/
|
*/
|
||||||
super()
|
super()
|
||||||
this.event = 'request.group.invite'
|
this.event = 'request.group.invite'
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
if(/group/.test(this.event)){
|
if (/group/.test(this.event)) {
|
||||||
this.e.isGroup = true
|
this.e.isGroup = true
|
||||||
}
|
}
|
||||||
if(!this.e.isGroup) return
|
if (!this.e.isGroup) return
|
||||||
//
|
//
|
||||||
if (!cfg.masterQQ || !cfg.masterQQ.includes(String(this.e.user_id))) {
|
if (!cfg.masterQQ || !cfg.masterQQ.includes(String(this.e.user_id))) {
|
||||||
logger.mark(`[邀请加群]:${this.e.group_name}:${this.e.group_id}`)
|
logger.mark(`[邀请加群]:${this.e.group_name}:${this.e.group_id}`)
|
||||||
|
@ -33,8 +32,10 @@ export class invite extends Plugin {
|
||||||
}
|
}
|
||||||
logger.mark(`[主人邀请加群]:${this.e.group_name}:${this.e.group_id}`)
|
logger.mark(`[主人邀请加群]:${this.e.group_name}:${this.e.group_id}`)
|
||||||
this.e.approve(true)
|
this.e.approve(true)
|
||||||
this.e.bot.sendPrivateMsg(this.e.user_id, `已同意加群:${this.e.group_name}`).catch((err) => {
|
this.e.bot
|
||||||
logger.error(err)
|
.sendPrivateMsg(this.e.user_id, `已同意加群:${this.e.group_name}`)
|
||||||
})
|
.catch(err => {
|
||||||
|
logger.error(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Plugin, segment } from 'yunzai/core'
|
import { Plugin, segment } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class newcomer extends Plugin {
|
export class newcomer extends Plugin {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -12,13 +12,13 @@ export class newcomer extends Plugin {
|
||||||
dsc: '新人入群欢迎',
|
dsc: '新人入群欢迎',
|
||||||
*/
|
*/
|
||||||
super()
|
super()
|
||||||
this.event = 'notice.group.increase'
|
this.event = 'notice.group.increase'
|
||||||
this.priority = 5000
|
this.priority = 5000
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接受到消息都会执行一次
|
* 接受到消息都会执行一次
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
/** 定义入群欢迎内容 */
|
/** 定义入群欢迎内容 */
|
||||||
|
@ -38,4 +38,3 @@ export class newcomer extends Plugin {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
export class outNotice extends Plugin {
|
export class outNotice extends Plugin {
|
||||||
tips = '退群了'
|
tips = '退群了'
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
name: '退群通知',
|
name: '退群通知',
|
||||||
dsc: 'xx退群了',
|
dsc: 'xx退群了',
|
||||||
*/
|
*/
|
||||||
super()
|
super()
|
||||||
this.event = 'notice.group.decrease'
|
this.event = 'notice.group.decrease'
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async accept() {
|
||||||
|
if (this.e.user_id == this.e.bot.uin) return
|
||||||
|
let name = null,
|
||||||
|
msg = null
|
||||||
|
if (this.e.member) {
|
||||||
|
name = this.e.member.card || this.e.member.nickname
|
||||||
}
|
}
|
||||||
/**
|
if (name) {
|
||||||
*
|
msg = `${name}(${this.e.user_id}) ${this.tips}`
|
||||||
* @returns
|
} else {
|
||||||
*/
|
msg = `${this.e.user_id} ${this.tips}`
|
||||||
async accept() {
|
|
||||||
if (this.e.user_id == this.e.bot.uin) return
|
|
||||||
let name = null, msg = null
|
|
||||||
if (this.e.member) {
|
|
||||||
name = this.e.member.card || this.e.member.nickname
|
|
||||||
}
|
|
||||||
if (name) {
|
|
||||||
msg = `${name}(${this.e.user_id}) ${this.tips}`
|
|
||||||
} else {
|
|
||||||
msg = `${this.e.user_id} ${this.tips}`
|
|
||||||
}
|
|
||||||
logger.mark(`[退出通知]${this.e.logText} ${msg}`)
|
|
||||||
await this.reply(msg)
|
|
||||||
}
|
}
|
||||||
|
logger.mark(`[退出通知]${this.e.logText} ${msg}`)
|
||||||
|
await this.reply(msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class quit extends Plugin {
|
export class quit extends Plugin {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -16,17 +16,17 @@ export class quit extends Plugin {
|
||||||
this.event = 'notice.group.increase'
|
this.event = 'notice.group.increase'
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async accept() {
|
async accept() {
|
||||||
if (this.e.user_id != this.e.bot.uin) return
|
if (this.e.user_id != this.e.bot.uin) return
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
let other = cfg.other
|
let other = cfg.other
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (other.autoQuit <= 0) return
|
if (other.autoQuit <= 0) return
|
||||||
/**
|
/**
|
||||||
|
@ -44,19 +44,19 @@ export class quit extends Plugin {
|
||||||
*/
|
*/
|
||||||
if (Array.from(gl).length <= other.autoQuit && !this.e.group.is_owner) {
|
if (Array.from(gl).length <= other.autoQuit && !this.e.group.is_owner) {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
await this.e.reply('禁止拉群,已自动退出')
|
await this.e.reply('禁止拉群,已自动退出')
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
logger.mark(`[自动退群] ${this.e.group_id}`)
|
logger.mark(`[自动退群] ${this.e.group_id}`)
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
this.e.group.quit()
|
this.e.group.quit()
|
||||||
}, 2000)
|
}, 2000)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class example2 extends Plugin {
|
export class example2 extends Plugin {
|
||||||
constructor () {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
name: '复读',
|
name: '复读',
|
||||||
dsc: '复读用户发送的内容,然后撤回',
|
dsc: '复读用户发送的内容,然后撤回',
|
||||||
|
@ -18,9 +18,9 @@ export class example2 extends Plugin {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async repeat () {
|
async repeat() {
|
||||||
/** 设置上下文,后续接收到内容会执行doRep方法 */
|
/** 设置上下文,后续接收到内容会执行doRep方法 */
|
||||||
this.setContext('doRep')
|
this.setContext('doRep')
|
||||||
/** 回复 */
|
/** 回复 */
|
||||||
|
@ -29,7 +29,7 @@ export class example2 extends Plugin {
|
||||||
/**
|
/**
|
||||||
* 接受内容
|
* 接受内容
|
||||||
*/
|
*/
|
||||||
doRep () {
|
doRep() {
|
||||||
/** 复读内容 */
|
/** 复读内容 */
|
||||||
this.reply(this.e.message, false, { recallMsg: 5 })
|
this.reply(this.e.message, false, { recallMsg: 5 })
|
||||||
/** 结束上下文 */
|
/** 结束上下文 */
|
||||||
|
|
|
@ -15,4 +15,28 @@ export * from './status.js'
|
||||||
export * from './update.js'
|
export * from './update.js'
|
||||||
export * from './example2.js'
|
export * from './example2.js'
|
||||||
export * from './event/newcomer.js'
|
export * from './event/newcomer.js'
|
||||||
export * from './event/outNotice.js'
|
export * from './event/outNotice.js'
|
||||||
|
|
||||||
|
import { Messages, Segment } from 'yunzai/core'
|
||||||
|
import { imgae } from '../image.tsx'
|
||||||
|
import { movies } from '../data.ts'
|
||||||
|
const message = new Messages()
|
||||||
|
message.response(/^你好/, async e => {
|
||||||
|
const UID = e.user_id
|
||||||
|
// render 是异步的,因此此处也是异步的
|
||||||
|
const img = await imgae.createHello(UID, {
|
||||||
|
data: { name: 'word' },
|
||||||
|
movies
|
||||||
|
})
|
||||||
|
// 判断是否成功
|
||||||
|
if (typeof img !== 'boolean') {
|
||||||
|
// 图片
|
||||||
|
e.reply(Segment.image(img))
|
||||||
|
} else {
|
||||||
|
e.reply('你好')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const word = message.ok
|
||||||
|
|
||||||
|
export { word }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import net from 'net'
|
import net from 'net'
|
||||||
import fs from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
import YAML from 'yaml'
|
import YAML from 'yaml'
|
||||||
import { exec } from 'child_process'
|
import { exec } from 'child_process'
|
||||||
|
|
||||||
|
@ -10,28 +10,31 @@ import { exec } from 'child_process'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param port
|
* @param port
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const isPortTaken = async (port) => {
|
const isPortTaken = async port => {
|
||||||
return new Promise((resolve) => {
|
return new Promise(resolve => {
|
||||||
const tester = net.createServer()
|
const tester = net
|
||||||
|
.createServer()
|
||||||
.once('error', () => resolve(true))
|
.once('error', () => resolve(true))
|
||||||
.once('listening', () => tester.once('close', () => resolve(false)).close())
|
.once('listening', () =>
|
||||||
.listen(port);
|
tester.once('close', () => resolve(false)).close()
|
||||||
});
|
)
|
||||||
};
|
.listen(port)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class Restart extends Plugin {
|
export class Restart extends Plugin {
|
||||||
key = 'Yz:restart'
|
key = 'Yz:restart'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +60,7 @@ export class Restart extends Plugin {
|
||||||
async init() {
|
async init() {
|
||||||
const data = await redis.get(this.key)
|
const data = await redis.get(this.key)
|
||||||
if (data) {
|
if (data) {
|
||||||
const restart = JSON.parse(data)
|
const restart = JSON.parse(data)
|
||||||
const uin = restart?.uin || Bot.uin
|
const uin = restart?.uin || Bot.uin
|
||||||
let time = restart.time || new Date().getTime()
|
let time = restart.time || new Date().getTime()
|
||||||
time = (new Date().getTime() - time) / 1000
|
time = (new Date().getTime() - time) / 1000
|
||||||
|
@ -80,9 +83,11 @@ export class Restart extends Plugin {
|
||||||
async restart() {
|
async restart() {
|
||||||
let restart_port
|
let restart_port
|
||||||
try {
|
try {
|
||||||
restart_port = YAML.parse(fs.readFileSync(`./config/config/bot.yaml`, `utf-8`))
|
restart_port = YAML.parse(
|
||||||
|
readFileSync(`./config/config/bot.yaml`, `utf-8`)
|
||||||
|
)
|
||||||
restart_port = restart_port.restart_port || 27881
|
restart_port = restart_port.restart_port || 27881
|
||||||
} catch { }
|
} catch {}
|
||||||
await this.e.reply('开始执行重启,请稍等...')
|
await this.e.reply('开始执行重启,请稍等...')
|
||||||
logger.mark(`${this.e.logFnc} 开始执行重启,请稍等...`)
|
logger.mark(`${this.e.logFnc} 开始执行重启,请稍等...`)
|
||||||
|
|
||||||
|
@ -97,7 +102,9 @@ export class Restart extends Plugin {
|
||||||
await redis.set(this.key, data, { EX: 120 })
|
await redis.set(this.key, data, { EX: 120 })
|
||||||
if (await isPortTaken(restart_port || 27881)) {
|
if (await isPortTaken(restart_port || 27881)) {
|
||||||
try {
|
try {
|
||||||
const result = await fetch(`http://localhost:${restart_port || 27881}/restart`).then(res=>res.text())
|
const result = await fetch(
|
||||||
|
`http://localhost:${restart_port || 27881}/restart`
|
||||||
|
).then(res => res.text())
|
||||||
if (result !== `OK`) {
|
if (result !== `OK`) {
|
||||||
redis.del(this.key)
|
redis.del(this.key)
|
||||||
this.e.reply(`操作失败!`)
|
this.e.reply(`操作失败!`)
|
||||||
|
@ -144,7 +151,7 @@ export class Restart extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
async execSync(cmd) {
|
async execSync(cmd) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(resolve => {
|
||||||
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
|
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
|
||||||
resolve({ error, stdout, stderr })
|
resolve({ error, stdout, stderr })
|
||||||
})
|
})
|
||||||
|
@ -154,9 +161,11 @@ export class Restart extends Plugin {
|
||||||
async stop() {
|
async stop() {
|
||||||
let restart_port
|
let restart_port
|
||||||
try {
|
try {
|
||||||
restart_port = YAML.parse(fs.readFileSync(`./config/config/bot.yaml`, `utf-8`))
|
restart_port = YAML.parse(
|
||||||
|
readFileSync(`./config/config/bot.yaml`, `utf-8`)
|
||||||
|
)
|
||||||
restart_port = restart_port.restart_port || 27881
|
restart_port = restart_port.restart_port || 27881
|
||||||
} catch { }
|
} catch {}
|
||||||
if (await isPortTaken(restart_port || 27881)) {
|
if (await isPortTaken(restart_port || 27881)) {
|
||||||
try {
|
try {
|
||||||
logger.mark('关机成功,已停止运行')
|
logger.mark('关机成功,已停止运行')
|
||||||
|
@ -179,7 +188,7 @@ export class Restart extends Plugin {
|
||||||
await this.e.reply('关机成功,已停止运行')
|
await this.e.reply('关机成功,已停止运行')
|
||||||
|
|
||||||
let npm = await this.checkPnpm()
|
let npm = await this.checkPnpm()
|
||||||
exec(`${npm} stop`, { windowsHide: true }, (error, stdout, stderr) => {
|
exec(`${npm} stop`, { windowsHide: true }, error => {
|
||||||
if (error) {
|
if (error) {
|
||||||
this.e.reply(`操作失败!\n${error.stack}`)
|
this.e.reply(`操作失败!\n${error.stack}`)
|
||||||
logger.error(`关机失败\n${error.stack}`)
|
logger.error(`关机失败\n${error.stack}`)
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
import {makeForwardMsg} from 'yunzai/core'
|
import { makeForwardMsg } from 'yunzai/core'
|
||||||
import fs from "node:fs"
|
import { readFileSync } from 'node:fs'
|
||||||
import lodash from "lodash"
|
import lodash from 'lodash'
|
||||||
import moment from "moment"
|
import moment from 'moment'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tudo
|
* tudo
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class sendLog extends Plugin {
|
export class sendLog extends Plugin {
|
||||||
lineNum = 100
|
lineNum = 100
|
||||||
maxNum = 1000
|
maxNum = 1000
|
||||||
errFile = "logs/error.log"
|
errFile = 'logs/error.log'
|
||||||
logFile = `logs/command.${moment().format("YYYY-MM-DD")}.log`
|
logFile = `logs/command.${moment().format('YYYY-MM-DD')}.log`
|
||||||
|
keyWord = null
|
||||||
constructor() {
|
constructor() {
|
||||||
/**
|
/**
|
||||||
name: "发送日志",
|
name: "发送日志",
|
||||||
|
@ -26,65 +27,68 @@ export class sendLog extends Plugin {
|
||||||
{
|
{
|
||||||
reg: /^#(运行|错误)*日志[0-9]*(.*)/,
|
reg: /^#(运行|错误)*日志[0-9]*(.*)/,
|
||||||
fnc: this.sendLog.name,
|
fnc: this.sendLog.name,
|
||||||
permission: "master"
|
permission: 'master'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async sendLog() {
|
async sendLog() {
|
||||||
let lineNum = this.e.msg.match(/\d+/g)
|
let lineNum = this.e.msg.match(/\d+/g)
|
||||||
if (lineNum) {
|
if (lineNum) {
|
||||||
this.lineNum = lineNum[0]
|
this.lineNum = Number(lineNum[0])
|
||||||
} else {
|
} else {
|
||||||
this.keyWord = this.e.msg.replace(/#|运行|错误|日志|\d/g, "")
|
this.keyWord = this.e.msg.replace(/#|运行|错误|日志|\d/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
let logFile = this.logFile
|
let logFile = this.logFile
|
||||||
let type = "运行"
|
let type = '运行'
|
||||||
if (this.e.msg.includes("错误")) {
|
if (this.e.msg.includes('错误')) {
|
||||||
logFile = this.errFile
|
logFile = this.errFile
|
||||||
type = "错误"
|
type = '错误'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.keyWord) type = this.keyWord
|
if (this.keyWord) type = this.keyWord
|
||||||
|
|
||||||
const log = this.getLog(logFile)
|
const log = this.getLog(logFile)
|
||||||
|
|
||||||
if (lodash.isEmpty(log))
|
if (lodash.isEmpty(log)) {
|
||||||
return this.reply(`暂无相关日志:${type}`)
|
return this.reply(`暂无相关日志:${type}`)
|
||||||
|
}
|
||||||
|
|
||||||
return this.reply(await makeForwardMsg(this.e, [log.join("\n")], `最近${log.length}条${type}日志`))
|
const data = await makeForwardMsg(
|
||||||
|
this.e,
|
||||||
|
[log.join('\n')],
|
||||||
|
`最近${log.length}条${type}日志`
|
||||||
|
)
|
||||||
|
return this.reply(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param logFile
|
* @param logFile
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getLog(logFile) {
|
getLog(logFile) {
|
||||||
let log = fs.readFileSync(logFile, { encoding: "utf-8" })
|
const data = readFileSync(logFile, { encoding: 'utf-8' })
|
||||||
log = log.split("\n")
|
let log = data.split('\n')
|
||||||
|
|
||||||
if (this.keyWord) {
|
if (this.keyWord) {
|
||||||
for (const i in log)
|
for (const i in log) if (!log[i].includes(this.keyWord)) delete log[i]
|
||||||
if (!log[i].includes(this.keyWord))
|
|
||||||
delete log[i]
|
|
||||||
} else {
|
} else {
|
||||||
log = lodash.slice(log, (Number(this.lineNum) + 1) * -1)
|
log = lodash.slice(log, (Number(this.lineNum) + 1) * -1)
|
||||||
}
|
}
|
||||||
log = log.reverse()
|
log = log.reverse()
|
||||||
|
|
||||||
const tmp = []
|
const tmp = []
|
||||||
for (let i of log) {
|
for (let i of log) {
|
||||||
if (!i) continue
|
if (!i) continue
|
||||||
if (this.keyWord && tmp.length >= this.maxNum) return
|
if (this.keyWord && tmp.length >= this.maxNum) return
|
||||||
/* eslint-disable no-control-regex */
|
/* eslint-disable no-control-regex */
|
||||||
i = i.replace(/\x1b[[0-9;]*m/g, "")
|
i = i.replace(/\x1b[[0-9;]*m/g, '')
|
||||||
i = i.replace(/\r|\n/, "")
|
i = i.replace(/\r|\n/, '')
|
||||||
tmp.push(i)
|
tmp.push(i)
|
||||||
}
|
}
|
||||||
return tmp
|
return tmp
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { ConfigController as cfg } from 'yunzai/config'
|
import { ConfigController as cfg } from 'yunzai/config'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { Plugin } from 'yunzai/core'
|
import { Plugin } from 'yunzai/core'
|
||||||
|
@ -8,7 +7,7 @@ import { Plugin } from 'yunzai/core'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class status extends Plugin {
|
export class status extends Plugin {
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +25,8 @@ export class status extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async status() {
|
async status() {
|
||||||
if (this.e.isMaster) return this.statusMaster()
|
if (this.e.isMaster) return this.statusMaster()
|
||||||
|
@ -41,22 +40,27 @@ export class status extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
async statusMaster() {
|
async statusMaster() {
|
||||||
let runTime = moment().diff(moment.unix(this.e.bot.stat.start_time), 'seconds')
|
let runTime = moment().diff(
|
||||||
|
moment.unix(this.e.bot.stat.start_time),
|
||||||
|
'seconds'
|
||||||
|
)
|
||||||
let Day = Math.floor(runTime / 3600 / 24)
|
let Day = Math.floor(runTime / 3600 / 24)
|
||||||
let Hour = Math.floor((runTime / 3600) % 24)
|
let Hour = Math.floor((runTime / 3600) % 24)
|
||||||
let Min = Math.floor((runTime / 60) % 60)
|
let Min = Math.floor((runTime / 60) % 60)
|
||||||
|
|
||||||
|
let data = ''
|
||||||
if (Day > 0) {
|
if (Day > 0) {
|
||||||
runTime = `${Day}天${Hour}小时${Min}分钟`
|
data = `${Day}天${Hour}小时${Min}分钟`
|
||||||
} else {
|
} else {
|
||||||
runTime = `${Hour}小时${Min}分钟`
|
data = `${Hour}小时${Min}分钟`
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = (bytes) => {
|
let format = bytes => {
|
||||||
return (bytes / 1024 / 1024).toFixed(2) + 'MB'
|
return (bytes / 1024 / 1024).toFixed(2) + 'MB'
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = '-------状态-------'
|
let msg = '-------状态-------'
|
||||||
msg += `\n运行时间:${runTime}`
|
msg += `\n运行时间:${data}`
|
||||||
msg += `\n内存使用:${format(process.memoryUsage().rss)}`
|
msg += `\n内存使用:${format(process.memoryUsage().rss)}`
|
||||||
msg += `\n当前版本:v${cfg.package.version}`
|
msg += `\n当前版本:v${cfg.package.version}`
|
||||||
msg += '\n-------累计-------'
|
msg += '\n-------累计-------'
|
||||||
|
@ -72,7 +76,13 @@ export class status extends Plugin {
|
||||||
await this.e.reply(msg)
|
await this.e.reply(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCount(groupId:number | string = '') {
|
date = null
|
||||||
|
month = null
|
||||||
|
key = null
|
||||||
|
msgKey = null
|
||||||
|
screenshotKey = null
|
||||||
|
|
||||||
|
async getCount(groupId: number | string = '') {
|
||||||
this.date = moment().format('MMDD')
|
this.date = moment().format('MMDD')
|
||||||
this.month = Number(moment().month()) + 1
|
this.month = Number(moment().month()) + 1
|
||||||
|
|
||||||
|
@ -100,22 +110,25 @@ export class status extends Plugin {
|
||||||
let date = moment().startOf('week').add(i, 'days').format('MMDD')
|
let date = moment().startOf('week').add(i, 'days').format('MMDD')
|
||||||
|
|
||||||
week.msg += Number(await redis.get(`${this.msgKey.day}${date}`)) ?? 0
|
week.msg += Number(await redis.get(`${this.msgKey.day}${date}`)) ?? 0
|
||||||
week.screenshot += Number(await redis.get(`${this.screenshotKey.day}${date}`)) ?? 0
|
week.screenshot +=
|
||||||
|
Number(await redis.get(`${this.screenshotKey.day}${date}`)) ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let count = {
|
let count = {
|
||||||
total: {
|
total: {
|
||||||
msg: await redis.get(`${this.key}sendMsg:total`) || 0,
|
msg: (await redis.get(`${this.key}sendMsg:total`)) || 0,
|
||||||
screenshot: await redis.get(`${this.key}screenshot:total`) || 0
|
screenshot: (await redis.get(`${this.key}screenshot:total`)) || 0
|
||||||
},
|
},
|
||||||
today: {
|
today: {
|
||||||
msg: await redis.get(`${this.msgKey.day}${this.date}`) || 0,
|
msg: (await redis.get(`${this.msgKey.day}${this.date}`)) || 0,
|
||||||
screenshot: await redis.get(`${this.screenshotKey.day}${this.date}`) || 0
|
screenshot:
|
||||||
|
(await redis.get(`${this.screenshotKey.day}${this.date}`)) || 0
|
||||||
},
|
},
|
||||||
week,
|
week,
|
||||||
month: {
|
month: {
|
||||||
msg: await redis.get(`${this.msgKey.month}${this.month}`) || 0,
|
msg: (await redis.get(`${this.msgKey.month}${this.month}`)) || 0,
|
||||||
screenshot: await redis.get(`${this.screenshotKey.month}${this.month}`) || 0
|
screenshot:
|
||||||
|
(await redis.get(`${this.screenshotKey.month}${this.month}`)) || 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +141,12 @@ export class status extends Plugin {
|
||||||
msg += `\n生成图片:${count.total.screenshot}次`
|
msg += `\n生成图片:${count.total.screenshot}次`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count.month.msg > 200) {
|
if (Number(count.month.msg) > 200) {
|
||||||
msg += '\n-------本周-------'
|
msg += '\n-------本周-------'
|
||||||
msg += `\n发送消息:${count.week.msg}条`
|
msg += `\n发送消息:${count.week.msg}条`
|
||||||
msg += `\n生成图片:${count.week.screenshot}次`
|
msg += `\n生成图片:${count.week.screenshot}次`
|
||||||
}
|
}
|
||||||
if (moment().format('D') >= 8 && count.month.msg > 400) {
|
if (Number(moment().format('D')) >= 8 && Number(count.month.msg) > 400) {
|
||||||
msg += '\n-------本月-------'
|
msg += '\n-------本月-------'
|
||||||
msg += `\n发送消息:${count.month.msg}条`
|
msg += `\n发送消息:${count.month.msg}条`
|
||||||
msg += `\n生成图片:${count.month.screenshot}次`
|
msg += `\n生成图片:${count.month.screenshot}次`
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Plugin ,makeForwardMsg} from 'yunzai/core'
|
import { Plugin, makeForwardMsg } from 'yunzai/core'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import fs from 'node:fs'
|
import { existsSync, readdirSync } from 'node:fs'
|
||||||
import { BOT_NAME } from 'yunzai/config'
|
import { BOT_NAME } from 'yunzai/config'
|
||||||
import { exec, execSync } from 'child_process'
|
import { exec, execSync } from 'child_process'
|
||||||
import { Restart } from './restart.js'
|
import { Restart } from './restart.js'
|
||||||
import { sleep } from 'yunzai/utils'
|
import { sleep } from 'yunzai/utils'
|
||||||
let uping = false
|
let uping = false
|
||||||
|
@ -67,20 +67,24 @@ export class update extends Plugin {
|
||||||
if (!plugin) return ''
|
if (!plugin) return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(`plugins/${plugin}/.git`)) return false
|
if (!existsSync(`plugins/${plugin}/.git`)) return false
|
||||||
|
|
||||||
this.typeName = plugin
|
this.typeName = plugin
|
||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
async execSync(cmd) {
|
async execSync(cmd) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(resolve => {
|
||||||
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
|
exec(cmd, { windowsHide: true }, (error, stdout, stderr) => {
|
||||||
resolve({ error, stdout, stderr })
|
resolve({ error, stdout, stderr })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isUp = null
|
||||||
|
isNowUp = null
|
||||||
|
oldCommitId = null
|
||||||
|
|
||||||
async runUpdate(plugin = '') {
|
async runUpdate(plugin = '') {
|
||||||
this.isNowUp = false
|
this.isNowUp = false
|
||||||
|
|
||||||
|
@ -162,22 +166,26 @@ export class update extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errMsg.includes('be overwritten by merge')) {
|
if (errMsg.includes('be overwritten by merge')) {
|
||||||
return this.e.reply(`${msg}\n存在冲突:\n${errMsg}\n请解决冲突后再更新,或者执行#强制更新,放弃本地修改`)
|
return this.e.reply(
|
||||||
|
`${msg}\n存在冲突:\n${errMsg}\n请解决冲突后再更新,或者执行#强制更新,放弃本地修改`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stdout.includes('CONFLICT')) {
|
if (stdout.includes('CONFLICT')) {
|
||||||
return this.e.reply(`${msg}\n存在冲突:\n${errMsg}${stdout}\n请解决冲突后再更新,或者执行#强制更新,放弃本地修改`)
|
return this.e.reply(
|
||||||
|
`${msg}\n存在冲突:\n${errMsg}${stdout}\n请解决冲突后再更新,或者执行#强制更新,放弃本地修改`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.e.reply([errMsg, stdout])
|
return this.e.reply([errMsg, stdout])
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAll() {
|
async updateAll() {
|
||||||
const dirs = fs.readdirSync('./plugins/')
|
const dirs = readdirSync('./plugins/')
|
||||||
|
|
||||||
const MSG = (message)=>{
|
const MSG = message => {
|
||||||
// 收集
|
// 收集
|
||||||
this.messages.push(message)
|
this.messages.push(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
const testReg = /^#静默全部(强制)?更新$/.test(this.e.msg)
|
const testReg = /^#静默全部(强制)?更新$/.test(this.e.msg)
|
||||||
|
@ -203,7 +211,6 @@ export class update extends Plugin {
|
||||||
// await this.e.reply('即将执行重启,以应用更新')
|
// await this.e.reply('即将执行重启,以应用更新')
|
||||||
setTimeout(() => this.restart(), 2000)
|
setTimeout(() => this.restart(), 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restart() {
|
restart() {
|
||||||
|
@ -243,13 +250,21 @@ export class update extends Plugin {
|
||||||
cm = 'git config -l'
|
cm = 'git config -l'
|
||||||
if (plugin) cm = `cd "plugins/${plugin}" && ${cm}`
|
if (plugin) cm = `cd "plugins/${plugin}" && ${cm}`
|
||||||
end = await execSync(cm, { encoding: 'utf-8' })
|
end = await execSync(cm, { encoding: 'utf-8' })
|
||||||
end = end.match(/remote\..*\.url=.+/g).join('\n\n').replace(/remote\..*\.url=/g, '').replace(/\/\/([^@]+)@/, '//')
|
end = end
|
||||||
|
.match(/remote\..*\.url=.+/g)
|
||||||
|
.join('\n\n')
|
||||||
|
.replace(/remote\..*\.url=/g, '')
|
||||||
|
.replace(/\/\/([^@]+)@/, '//')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error.toString())
|
logger.error(error.toString())
|
||||||
await this.e.reply(error.toString())
|
await this.e.reply(error.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeForwardMsg(this.e, [log, end], `${plugin || 'Miao-Yunzai'} 更新日志,共${line}条`)
|
return makeForwardMsg(
|
||||||
|
this.e,
|
||||||
|
[log, end],
|
||||||
|
`${plugin || 'Miao-Yunzai'} 更新日志,共${line}条`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateLog() {
|
async updateLog() {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
|
|
||||||
export default function List({ children }) {
|
export default function List({ children }) {
|
||||||
return (
|
return <ul className="divide-y divide-slate-100">{children}</ul>
|
||||||
<ul className="divide-y divide-slate-100">
|
}
|
||||||
{children}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,66 +1,87 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
|
|
||||||
export interface MovieType {
|
export interface MovieType {
|
||||||
id: number, //
|
id: number //
|
||||||
image:string, //
|
image: string //
|
||||||
title:string, // Prognosis Negative
|
title: string // Prognosis Negative
|
||||||
starRating: string, // 2.66
|
starRating: string // 2.66
|
||||||
rating:string, // PG-13
|
rating: string // PG-13
|
||||||
year:string, // 2021
|
year: string // 2021
|
||||||
genre:string, // Comedy
|
genre: string // Comedy
|
||||||
runtime:string, // 1h 46m
|
runtime: string // 1h 46m
|
||||||
cast:string // Simon Pegg, Zach Galifianakis
|
cast: string // Simon Pegg, Zach Galifianakis
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ListItem({ movie }: {movie:MovieType}) {
|
export default function ListItem({ movie }: { movie: MovieType }) {
|
||||||
return (
|
return (
|
||||||
<article className="flex items-start space-x-6 p-6">
|
<article className="flex items-start space-x-6 p-6">
|
||||||
<img src={movie.image} alt="" width="60" height="88" className="flex-none rounded-md bg-slate-100" />
|
<img
|
||||||
<div className="min-w-0 relative flex-auto">
|
src={movie.image}
|
||||||
<h2 className="font-semibold text-slate-900 truncate pr-20">{movie.title}</h2>
|
alt=""
|
||||||
<dl className="mt-2 flex flex-wrap text-sm leading-6 font-medium">
|
width="60"
|
||||||
<div className="absolute top-0 right-0 flex items-center space-x-1">
|
height="88"
|
||||||
<dt className="text-sky-500">
|
className="flex-none rounded-md bg-slate-100"
|
||||||
<span className="sr-only">Star rating</span>
|
/>
|
||||||
<svg width="16" height="20" fill="currentColor">
|
<div className="min-w-0 relative flex-auto">
|
||||||
<path d="M7.05 3.691c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.372 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.539 1.118l-2.8-2.034a1 1 0 00-1.176 0l-2.8 2.034c-.783.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.363-1.118L.98 9.483c-.784-.57-.381-1.81.587-1.81H5.03a1 1 0 00.95-.69L7.05 3.69z" />
|
<h2 className="font-semibold text-slate-900 truncate pr-20">
|
||||||
</svg>
|
{movie.title}
|
||||||
</dt>
|
</h2>
|
||||||
<dd>{movie.starRating}</dd>
|
<dl className="mt-2 flex flex-wrap text-sm leading-6 font-medium">
|
||||||
</div>
|
<div className="absolute top-0 right-0 flex items-center space-x-1">
|
||||||
<div>
|
<dt className="text-sky-500">
|
||||||
<dt className="sr-only">Rating</dt>
|
<span className="sr-only">Star rating</span>
|
||||||
<dd className="px-1.5 ring-1 ring-slate-200 rounded">{movie.rating}</dd>
|
<svg width="16" height="20" fill="currentColor">
|
||||||
</div>
|
<path d="M7.05 3.691c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.372 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.539 1.118l-2.8-2.034a1 1 0 00-1.176 0l-2.8 2.034c-.783.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.363-1.118L.98 9.483c-.784-.57-.381-1.81.587-1.81H5.03a1 1 0 00.95-.69L7.05 3.69z" />
|
||||||
<div className="ml-2">
|
</svg>
|
||||||
<dt className="sr-only">Year</dt>
|
</dt>
|
||||||
<dd>{movie.year}</dd>
|
<dd>{movie.starRating}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt className="sr-only">Genre</dt>
|
<dt className="sr-only">Rating</dt>
|
||||||
<dd className="flex items-center">
|
<dd className="px-1.5 ring-1 ring-slate-200 rounded">
|
||||||
<svg width="2" height="2" fill="currentColor" className="mx-2 text-slate-300" aria-hidden="true">
|
{movie.rating}
|
||||||
<circle cx="1" cy="1" r="1" />
|
</dd>
|
||||||
</svg>
|
</div>
|
||||||
{movie.genre}
|
<div className="ml-2">
|
||||||
</dd>
|
<dt className="sr-only">Year</dt>
|
||||||
</div>
|
<dd>{movie.year}</dd>
|
||||||
<div>
|
</div>
|
||||||
<dt className="sr-only">Runtime</dt>
|
<div>
|
||||||
<dd className="flex items-center">
|
<dt className="sr-only">Genre</dt>
|
||||||
<svg width="2" height="2" fill="currentColor" className="mx-2 text-slate-300" aria-hidden="true">
|
<dd className="flex items-center">
|
||||||
<circle cx="1" cy="1" r="1" />
|
<svg
|
||||||
</svg>
|
width="2"
|
||||||
{movie.runtime}
|
height="2"
|
||||||
</dd>
|
fill="currentColor"
|
||||||
</div>
|
className="mx-2 text-slate-300"
|
||||||
<div className="flex-none w-full mt-2 font-normal">
|
aria-hidden="true"
|
||||||
<dt className="sr-only">Cast</dt>
|
>
|
||||||
<dd className="text-slate-400">{movie.cast}</dd>
|
<circle cx="1" cy="1" r="1" />
|
||||||
</div>
|
</svg>
|
||||||
</dl>
|
{movie.genre}
|
||||||
</div>
|
</dd>
|
||||||
</article>
|
</div>
|
||||||
)
|
<div>
|
||||||
}
|
<dt className="sr-only">Runtime</dt>
|
||||||
|
<dd className="flex items-center">
|
||||||
|
<svg
|
||||||
|
width="2"
|
||||||
|
height="2"
|
||||||
|
fill="currentColor"
|
||||||
|
className="mx-2 text-slate-300"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<circle cx="1" cy="1" r="1" />
|
||||||
|
</svg>
|
||||||
|
{movie.runtime}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
<div className="flex-none w-full mt-2 font-normal">
|
||||||
|
<dt className="sr-only">Cast</dt>
|
||||||
|
<dd className="text-slate-400">{movie.cast}</dd>
|
||||||
|
</div>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
export default function Nav({ children }) {
|
export default function Nav({ children }) {
|
||||||
return (
|
return (
|
||||||
<nav className="py-4 px-6 text-sm font-medium">
|
<nav className="py-4 px-6 text-sm font-medium">
|
||||||
<ul className="flex space-x-3">
|
<ul className="flex space-x-3">{children}</ul>
|
||||||
{children}
|
</nav>
|
||||||
</ul>
|
)
|
||||||
</nav>
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
export default function NavItem({ href, children }) {
|
export default function NavItem({ href, children }) {
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href={href}
|
href={href}
|
||||||
className={`block px-3 py-2 rounded-md bg-sky-500 text-white`}
|
className={`block px-3 py-2 rounded-md bg-sky-500 text-white`}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
2
data.ts
2
data.ts
|
@ -13,4 +13,4 @@ export const movies = [
|
||||||
runtime: '1h 46m',
|
runtime: '1h 46m',
|
||||||
cast: 'Simon Pegg, Zach Galifianakis '
|
cast: 'Simon Pegg, Zach Galifianakis '
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
52
image.tsx
52
image.tsx
|
@ -1,33 +1,33 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Picture } from 'yunzai/utils'
|
import { Picture } from 'yunzai/utils'
|
||||||
import { createDynamic } from 'yunzai/utils'
|
|
||||||
import { PropsType } from './views/hello.tsx'
|
import { PropsType } from './views/hello.tsx'
|
||||||
|
import { createDynamic } from 'yunzai/utils'
|
||||||
const require = createDynamic(import.meta.url)
|
const require = createDynamic(import.meta.url)
|
||||||
export class Image extends Picture {
|
export class Image extends Picture {
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
// start
|
// start
|
||||||
this.Pup.start()
|
this.Pup.start()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 为指定用户生成html 生成指定数据下的html文件
|
* 为指定用户生成html 生成指定数据下的html文件
|
||||||
* @param uid 用户编号
|
* @param uid 用户编号
|
||||||
* @param Props 组件参数
|
* @param Props 组件参数
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async createHello(uid: number, Props: PropsType) {
|
async createHello(uid: number, Props: PropsType) {
|
||||||
// 此作用域可被重复执行,此处将变成动态组件 - 这是危险的!
|
// 非生产环境将触发 动态组件效果
|
||||||
const Hello = (await require('./views/hello.tsx')).default;
|
const Hello = (
|
||||||
// 生成 html 地址 或 html字符串
|
await require('./views/hello.tsx', process.env.NODE_ENV != 'production')
|
||||||
const Address = this.Com.create(<Hello {...Props} />, {
|
).default
|
||||||
// html/hello/uid.html
|
// 生成 html 地址 或 html字符串
|
||||||
join_dir: 'hello',
|
const Address = this.Com.create(<Hello {...Props} />, {
|
||||||
html_name: `${uid}.html`,
|
// html/hello/uid.html
|
||||||
})
|
join_dir: 'hello',
|
||||||
return this.Pup.render(Address, {
|
html_name: `${uid}.html`
|
||||||
tab: ''
|
})
|
||||||
})
|
return this.Pup.render(Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 初始化 图片生成对象
|
// 初始化 图片生成对象
|
||||||
export const imgae = new Image()
|
export const imgae = new Image()
|
||||||
|
|
2
index.ts
2
index.ts
|
@ -1 +1 @@
|
||||||
export * as apps from './apps/index.js'
|
export * as apps from './apps/index.js'
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "system-plugin",
|
"name": "system-plugin",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {},
|
"scripts": {
|
||||||
"dependencies": {},
|
"format": "prettier --write ."
|
||||||
"devDependencies": {}
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "^3.0.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
16
routes.tsx
16
routes.tsx
|
@ -1,17 +1,17 @@
|
||||||
import React from "react"
|
import React from 'react'
|
||||||
import { movies } from "./data"
|
import { movies } from './data'
|
||||||
import { createDynamic } from 'yunzai/utils'
|
import { createDynamic } from 'yunzai/utils'
|
||||||
const require = createDynamic(import.meta.url)
|
const require = createDynamic(import.meta.url)
|
||||||
const Hello = (await require('./views/hello.tsx')).default;
|
const Hello = (await require('./views/hello.tsx')).default
|
||||||
const Music = (await require('./views/music.tsx')).default;
|
const Music = (await require('./views/music.tsx')).default
|
||||||
const Config = [
|
const Config = [
|
||||||
{
|
{
|
||||||
url: "/hello",
|
url: '/hello',
|
||||||
element: <Hello data={{ name: "word" }} movies={movies} />
|
element: <Hello data={{ name: 'word' }} movies={movies} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
url: "/music",
|
url: '/music',
|
||||||
element: <Music />
|
element: <Music />
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
export default Config
|
export default Config
|
||||||
|
|
8
tes.ts
8
tes.ts
|
@ -1,8 +0,0 @@
|
||||||
|
|
||||||
// const require = async (basePath: string) => {
|
|
||||||
// const now = () => `?update=${Date.now()}`
|
|
||||||
// return (await import(`${basePath}${now()}`))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const Hello = await require('./views/hello.tsx')
|
|
||||||
// const Music = await require(`./views/music.tsx`)
|
|
|
@ -18,22 +18,24 @@ const require = createRequire(import.meta.url)
|
||||||
const url: string = require('../resources/example.png')
|
const url: string = require('../resources/example.png')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param param0
|
* @param param0
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export default function App({ data, movies }: PropsType) {
|
export default function App({ data, movies }: PropsType) {
|
||||||
return (
|
return (
|
||||||
<div className="divide-y divide-slate-100 m-8 shadow-2xl">
|
<section className="flex flex-col">
|
||||||
<img className='h-40 w-40' src={url}></img>
|
<div className="divide-y divide-slate-100 m-8 shadow-2xl">
|
||||||
<Nav>
|
<img className="h-40 w-40" src={url}></img>
|
||||||
<NavItem href="./music" >New {data.name}</NavItem>
|
<Nav>
|
||||||
</Nav>
|
<NavItem href="./music">New {data.name}</NavItem>
|
||||||
<List>
|
</Nav>
|
||||||
{movies.map((movie) => (
|
<List>
|
||||||
<ListItem key={movie.id} movie={movie} />
|
{movies.map(movie => (
|
||||||
))}
|
<ListItem key={movie.id} movie={movie} />
|
||||||
</List>
|
))}
|
||||||
</div>
|
</List>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
236
views/music.tsx
236
views/music.tsx
|
@ -1,87 +1,171 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
import { createRequire } from 'module'
|
import { createRequire } from 'module'
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
// 图片
|
// 图片
|
||||||
const url: string = require('../resources/example.png')
|
const url: string = require('../resources/example.png')
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return <>
|
return (
|
||||||
<div className="bg-white border-slate-100 dark:bg-slate-800 dark:border-slate-500 border-b rounded-t-xl p-4 pb-6 sm:p-10 sm:pb-8 lg:p-6 xl:p-10 xl:pb-8 space-y-6 sm:space-y-8 lg:space-y-6 xl:space-y-8">
|
<>
|
||||||
<div className="flex items-center space-x-4">
|
<div className="bg-white border-slate-100 dark:bg-slate-800 dark:border-slate-500 border-b rounded-t-xl p-4 pb-6 sm:p-10 sm:pb-8 lg:p-6 xl:p-10 xl:pb-8 space-y-6 sm:space-y-8 lg:space-y-6 xl:space-y-8">
|
||||||
<img src={url} alt="" width="88" height="88" className="flex-none rounded-lg bg-slate-100" loading="lazy" />
|
<div className="flex items-center space-x-4">
|
||||||
<div className="min-w-0 flex-auto space-y-1 font-semibold">
|
<img
|
||||||
<p className="text-cyan-500 dark:text-cyan-400 text-sm leading-6">
|
src={url}
|
||||||
<abbr title="Episode">Ep.</abbr> 128
|
alt=""
|
||||||
</p>
|
width="88"
|
||||||
<h2 className="text-slate-500 dark:text-slate-400 text-sm leading-6 truncate">
|
height="88"
|
||||||
Scaling CSS at Heroku with Utility Classes
|
className="flex-none rounded-lg bg-slate-100"
|
||||||
</h2>
|
loading="lazy"
|
||||||
<p className="text-slate-900 dark:text-slate-50 text-lg">
|
/>
|
||||||
Full Stack Radio
|
<div className="min-w-0 flex-auto space-y-1 font-semibold">
|
||||||
</p>
|
<p className="text-cyan-500 dark:text-cyan-400 text-sm leading-6">
|
||||||
</div>
|
<abbr title="Episode">Ep.</abbr> 128
|
||||||
</div>
|
</p>
|
||||||
<div className="space-y-2">
|
<h2 className="text-slate-500 dark:text-slate-400 text-sm leading-6 truncate">
|
||||||
<div className="relative">
|
Scaling CSS at Heroku with Utility Classes
|
||||||
<div className="bg-slate-100 dark:bg-slate-700 rounded-full overflow-hidden">
|
</h2>
|
||||||
<div className="bg-cyan-500 dark:bg-cyan-400 w-1/2 h-2" role="progressbar" ></div>
|
<p className="text-slate-900 dark:text-slate-50 text-lg">
|
||||||
</div>
|
Full Stack Radio
|
||||||
<div className="ring-cyan-500 dark:ring-cyan-400 ring-2 absolute left-1/2 top-1/2 w-4 h-4 -mt-2 -ml-2 flex items-center justify-center bg-white rounded-full shadow">
|
</p>
|
||||||
<div className="w-1.5 h-1.5 bg-cyan-500 dark:bg-cyan-400 rounded-full ring-1 ring-inset ring-slate-900/5"></div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-between text-sm leading-6 font-medium tabular-nums">
|
|
||||||
<div className="text-cyan-500 dark:text-slate-100">24:16</div>
|
|
||||||
<div className="text-slate-500 dark:text-slate-400">75:50</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-slate-50 text-slate-500 dark:bg-slate-600 dark:text-slate-200 rounded-b-xl flex items-center">
|
<div className="space-y-2">
|
||||||
<div className="flex-auto flex items-center justify-evenly">
|
<div className="relative">
|
||||||
<button type="button" aria-label="Add to favorites">
|
<div className="bg-slate-100 dark:bg-slate-700 rounded-full overflow-hidden">
|
||||||
<svg width="24" height="24">
|
<div
|
||||||
<path d="M7 6.931C7 5.865 7.853 5 8.905 5h6.19C16.147 5 17 5.865 17 6.931V19l-5-4-5 4V6.931Z" fill="currentColor" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
className="bg-cyan-500 dark:bg-cyan-400 w-1/2 h-2"
|
||||||
</svg>
|
role="progressbar"
|
||||||
</button>
|
></div>
|
||||||
<button type="button" className="hidden sm:block lg:hidden xl:block" aria-label="Previous">
|
|
||||||
<svg width="24" height="24" fill="none">
|
|
||||||
<path d="m10 12 8-6v12l-8-6Z" fill="currentColor" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
<path d="M6 6v12" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button type="button" aria-label="Rewind 10 seconds">
|
|
||||||
<svg width="24" height="24" fill="none">
|
|
||||||
<path d="M6.492 16.95c2.861 2.733 7.5 2.733 10.362 0 2.861-2.734 2.861-7.166 0-9.9-2.862-2.733-7.501-2.733-10.362 0A7.096 7.096 0 0 0 5.5 8.226" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
<path d="M5 5v3.111c0 .491.398.889.889.889H9" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button type="button" className="bg-white text-slate-900 dark:bg-slate-100 dark:text-slate-700 flex-none -my-2 mx-auto w-20 h-20 rounded-full ring-1 ring-slate-900/5 shadow-md flex items-center justify-center" aria-label="Pause">
|
<div className="ring-cyan-500 dark:ring-cyan-400 ring-2 absolute left-1/2 top-1/2 w-4 h-4 -mt-2 -ml-2 flex items-center justify-center bg-white rounded-full shadow">
|
||||||
<svg width="30" height="32" fill="currentColor">
|
<div className="w-1.5 h-1.5 bg-cyan-500 dark:bg-cyan-400 rounded-full ring-1 ring-inset ring-slate-900/5"></div>
|
||||||
<rect x="6" y="4" width="4" height="24" rx="2" />
|
|
||||||
<rect x="20" y="4" width="4" height="24" rx="2" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div className="flex-auto flex items-center justify-evenly">
|
|
||||||
<button type="button" aria-label="Skip 10 seconds">
|
|
||||||
<svg width="24" height="24" fill="none">
|
|
||||||
<path d="M17.509 16.95c-2.862 2.733-7.501 2.733-10.363 0-2.861-2.734-2.861-7.166 0-9.9 2.862-2.733 7.501-2.733 10.363 0 .38.365.711.759.991 1.176" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
<path d="M19 5v3.111c0 .491-.398.889-.889.889H15" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button type="button" className="hidden sm:block lg:hidden xl:block" aria-label="Next">
|
|
||||||
<svg width="24" height="24" fill="none">
|
|
||||||
<path d="M14 12 6 6v12l8-6Z" fill="currentColor" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
<path d="M18 6v12" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<button type="button" className="rounded-lg text-xs leading-6 font-semibold px-2 ring-2 ring-inset ring-slate-500 text-slate-500 dark:text-slate-100 dark:ring-0 dark:bg-slate-500">
|
|
||||||
1x
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm leading-6 font-medium tabular-nums">
|
||||||
|
<div className="text-cyan-500 dark:text-slate-100">24:16</div>
|
||||||
|
<div className="text-slate-500 dark:text-slate-400">75:50</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-slate-50 text-slate-500 dark:bg-slate-600 dark:text-slate-200 rounded-b-xl flex items-center">
|
||||||
|
<div className="flex-auto flex items-center justify-evenly">
|
||||||
|
<button type="button" aria-label="Add to favorites">
|
||||||
|
<svg width="24" height="24">
|
||||||
|
<path
|
||||||
|
d="M7 6.931C7 5.865 7.853 5 8.905 5h6.19C16.147 5 17 5.865 17 6.931V19l-5-4-5 4V6.931Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="hidden sm:block lg:hidden xl:block"
|
||||||
|
aria-label="Previous"
|
||||||
|
>
|
||||||
|
<svg width="24" height="24" fill="none">
|
||||||
|
<path
|
||||||
|
d="m10 12 8-6v12l-8-6Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M6 6v12"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button type="button" aria-label="Rewind 10 seconds">
|
||||||
|
<svg width="24" height="24" fill="none">
|
||||||
|
<path
|
||||||
|
d="M6.492 16.95c2.861 2.733 7.5 2.733 10.362 0 2.861-2.734 2.861-7.166 0-9.9-2.862-2.733-7.501-2.733-10.362 0A7.096 7.096 0 0 0 5.5 8.226"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M5 5v3.111c0 .491.398.889.889.889H9"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="bg-white text-slate-900 dark:bg-slate-100 dark:text-slate-700 flex-none -my-2 mx-auto w-20 h-20 rounded-full ring-1 ring-slate-900/5 shadow-md flex items-center justify-center"
|
||||||
|
aria-label="Pause"
|
||||||
|
>
|
||||||
|
<svg width="30" height="32" fill="currentColor">
|
||||||
|
<rect x="6" y="4" width="4" height="24" rx="2" />
|
||||||
|
<rect x="20" y="4" width="4" height="24" rx="2" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div className="flex-auto flex items-center justify-evenly">
|
||||||
|
<button type="button" aria-label="Skip 10 seconds">
|
||||||
|
<svg width="24" height="24" fill="none">
|
||||||
|
<path
|
||||||
|
d="M17.509 16.95c-2.862 2.733-7.501 2.733-10.363 0-2.861-2.734-2.861-7.166 0-9.9 2.862-2.733 7.501-2.733 10.363 0 .38.365.711.759.991 1.176"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M19 5v3.111c0 .491-.398.889-.889.889H15"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="hidden sm:block lg:hidden xl:block"
|
||||||
|
aria-label="Next"
|
||||||
|
>
|
||||||
|
<svg width="24" height="24" fill="none">
|
||||||
|
<path
|
||||||
|
d="M14 12 6 6v12l8-6Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M18 6v12"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded-lg text-xs leading-6 font-semibold px-2 ring-2 ring-inset ring-slate-500 text-slate-500 dark:text-slate-100 dark:ring-0 dark:bg-slate-500"
|
||||||
|
>
|
||||||
|
1x
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue