🎨 优化文件结构 修复删群公告序号无效, close #112
This commit is contained in:
@@ -9,10 +9,10 @@ import md5 from "md5"
|
||||
let Vote = {}
|
||||
let time = 180 // 投票超时时间 单位秒
|
||||
|
||||
export class NewGroupVerify extends plugin {
|
||||
export class GroupVoteBan extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶投票禁言",
|
||||
name: "椰奶群管-投票禁言",
|
||||
dsc: "投票禁言某人",
|
||||
event: "message.group",
|
||||
priority: 5000,
|
||||
@@ -1,12 +1,9 @@
|
||||
import _ from "lodash"
|
||||
import moment from "moment"
|
||||
import { Config } from "../../components/index.js"
|
||||
import { Time_unit } from "../../constants/other.js"
|
||||
import { GroupAdmin as Ga, GroupBannedWords, QQApi, common, puppeteer } from "../../model/index.js"
|
||||
import { GroupAdmin as Ga, GroupBannedWords, common } from "../../model/index.js"
|
||||
import { cronValidate, translateChinaNum } from "../../tools/index.js"
|
||||
|
||||
// API请求错误文案
|
||||
const API_ERROR = "❎ 出错辣,请稍后重试"
|
||||
// 正则
|
||||
const Numreg = "[零一壹二两三四五六七八九十百千万亿\\d]+"
|
||||
const TimeUnitReg = Object.keys(Time_unit).join("|")
|
||||
@@ -20,7 +17,7 @@ const redisTask = await Ga.getRedisMuteTask() || false
|
||||
export class GroupAdmin extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群管",
|
||||
name: "椰奶群管-基础",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
@@ -44,18 +41,6 @@ export class GroupAdmin extends plugin {
|
||||
reg: "^#(设置|取消)管理(\\d+)?$",
|
||||
fnc: "SetAdmin"
|
||||
},
|
||||
{
|
||||
reg: "^#发群公告",
|
||||
fnc: "AddAnnounce"
|
||||
},
|
||||
{
|
||||
reg: "^#删群公告(\\d+)$",
|
||||
fnc: "DelAnnounce"
|
||||
},
|
||||
{
|
||||
reg: "^#查群公告$",
|
||||
fnc: "GetAnnounce"
|
||||
},
|
||||
{
|
||||
reg: "^#(修改|设置)头衔",
|
||||
fnc: "adminsetTitle"
|
||||
@@ -64,22 +49,6 @@ export class GroupAdmin extends plugin {
|
||||
reg: "^#申请头衔",
|
||||
fnc: "SetGroupSpecialTitle"
|
||||
},
|
||||
{
|
||||
reg: "^#(查)?(幸运)?字符(列表)?$",
|
||||
fnc: "qun_luckylist"
|
||||
},
|
||||
{
|
||||
reg: "^#抽(幸运)?字符$",
|
||||
fnc: "qun_lucky"
|
||||
},
|
||||
{
|
||||
reg: "^#替换(幸运)?字符(\\d+)$",
|
||||
fnc: "qun_luckyuse"
|
||||
},
|
||||
{
|
||||
reg: "^#(开启|关闭)(幸运)?字符$",
|
||||
fnc: "qun_luckyset"
|
||||
},
|
||||
{
|
||||
reg: "^#(获取|查看)?禁言列表$",
|
||||
fnc: "Mutelist"
|
||||
@@ -116,26 +85,6 @@ export class GroupAdmin extends plugin {
|
||||
reg: "^#(查看|获取)?群?发言(榜单|排行)((7|七)天)?",
|
||||
fnc: "SpeakRank"
|
||||
},
|
||||
{
|
||||
reg: "^#?(谁|哪个吊毛|哪个屌毛|哪个叼毛)是龙王$",
|
||||
fnc: "dragonKing"
|
||||
},
|
||||
{
|
||||
reg: "^#群星级$",
|
||||
fnc: "Group_xj"
|
||||
},
|
||||
{
|
||||
reg: "^#群数据((7|七)天)?$",
|
||||
fnc: "groupData"
|
||||
},
|
||||
{
|
||||
reg: "^#今日打卡$",
|
||||
fnc: "DaySigned"
|
||||
},
|
||||
{
|
||||
reg: "^#((今|昨|前|明|后)天|\\d{4}-\\d{1,2}-\\d{1,2})谁生日$",
|
||||
fnc: "groupBirthday"
|
||||
},
|
||||
{
|
||||
reg: "^#?(开启|关闭)加群通知$",
|
||||
fnc: "handleGroupAdd"
|
||||
@@ -144,14 +93,6 @@ export class GroupAdmin extends plugin {
|
||||
reg: "^#?(加|设|移)精$",
|
||||
fnc: "essenceMessage"
|
||||
},
|
||||
{
|
||||
reg: "^#?群管(加|删)白(名单)?",
|
||||
fnc: "whiteQQ"
|
||||
},
|
||||
{
|
||||
reg: "^#?(开启|关闭)白名单(自动)?解禁",
|
||||
fnc: "noBan"
|
||||
},
|
||||
{
|
||||
reg: Autisticreg, // 我要自闭
|
||||
fnc: "Autistic"
|
||||
@@ -235,44 +176,6 @@ export class GroupAdmin extends plugin {
|
||||
type ? e.reply(`✅ 已经把「${name}」设置为管理啦!!`) : e.reply(`✅ 已取消「${name}」的管理`)
|
||||
}
|
||||
|
||||
// 发群公告
|
||||
async AddAnnounce(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
// 获取发送的内容
|
||||
let msg = e.msg.replace(/#|发群公告/g, "").trim()
|
||||
if (!msg) return e.reply("❎ 公告不能为空")
|
||||
|
||||
let result = await new QQApi(e).setAnnounce(e.group_id, msg)
|
||||
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
if (result.ec != 0) {
|
||||
e.reply("❎ 发送失败\n" + JSON.stringify(result, null, "\t"))
|
||||
}
|
||||
}
|
||||
|
||||
// 查群公告
|
||||
async GetAnnounce(e) {
|
||||
let res = await new QQApi(e).getAnnouncelist(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
return e.reply(res)
|
||||
}
|
||||
|
||||
// 删群公告
|
||||
async DelAnnounce(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
let msg = e.msg.replace(/#|删群公告/, "").trim()
|
||||
if (!msg) return e.reply("❎ 序号不可为空")
|
||||
|
||||
let result = await new QQApi(e).delAnnounce(e.group_id, msg)
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
|
||||
if (result.ec == 0) {
|
||||
e.reply(`✅ 已删除「${result.text}」`)
|
||||
} else {
|
||||
e.reply("❎ 删除失败\n" + JSON.stringify(result, null, "\t"))
|
||||
}
|
||||
}
|
||||
|
||||
// 修改头衔
|
||||
async adminsetTitle(e) {
|
||||
if (!common.checkPermission(e, "master", "owner")) return
|
||||
@@ -313,58 +216,6 @@ export class GroupAdmin extends plugin {
|
||||
e.reply(`✅ 已将你的头衔更换为「${Title}」`, true)
|
||||
}
|
||||
|
||||
// 字符列表
|
||||
async qun_luckylist(e) {
|
||||
let data = await new QQApi(e).luckylist(e.group_id)
|
||||
if (!data) return e.reply(API_ERROR)
|
||||
if (data.retcode != 0) return e.reply("❎ 获取数据失败\n" + JSON.stringify(data))
|
||||
|
||||
let msg = data.data.word_list.map((item, index) => {
|
||||
let { wording, word_id, word_desc } = item.word_info
|
||||
return `${word_id}:${wording}\n寓意:${word_desc}`
|
||||
}).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 抽幸运字符
|
||||
async qun_lucky(e) {
|
||||
let res = await new QQApi(e).drawLucky(e.group_id)
|
||||
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode == 11004) return e.reply("❎ 今天已经抽过了,明天再来抽取吧")
|
||||
if (res.retcode != 0) return e.reply("❎ 错误\n" + JSON.stringify(res.data))
|
||||
|
||||
if (res.data.word_info) {
|
||||
let { wording, word_desc } = res.data.word_info.word_info
|
||||
e.reply(`恭喜您抽中了${wording}\n寓意为:${word_desc}`)
|
||||
} else {
|
||||
e.reply("恭喜您抽了中了个寂寞")
|
||||
}
|
||||
}
|
||||
|
||||
// 替换幸运字符
|
||||
async qun_luckyuse(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
let id = e.msg.replace(/#|替换(幸运)?字符/g, "")
|
||||
let res = await new QQApi(e).equipLucky(e.group_id, id)
|
||||
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply("❎替换失败\n" + JSON.stringify(res))
|
||||
e.reply("✅ OK")
|
||||
}
|
||||
|
||||
// 开启或关闭群字符
|
||||
async qun_luckyset(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
|
||||
let res = await new QQApi(e).swichLucky(e.group_id, /开启/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
|
||||
if (res.retcode == 11111) return e.reply("❎ 重复开启或关闭")
|
||||
if (res.retcode != 0) return e.reply("❎ 错误\n" + JSON.stringify(res))
|
||||
e.reply("✅ OK")
|
||||
}
|
||||
|
||||
// 获取禁言列表
|
||||
async Mutelist(e) {
|
||||
new Ga(e).getMuteList(e.group_id, true)
|
||||
@@ -519,163 +370,6 @@ export class GroupAdmin extends plugin {
|
||||
: e.reply(`❎ 该群定时${type ? "禁言" : "解禁"}已存在不可重复设置`)
|
||||
}
|
||||
|
||||
// 谁是龙王
|
||||
async dragonKing(e) {
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/interactive/honorlist?gc=${e.group_id}&type=1&_wv=3&_wwv=129`,
|
||||
headers: { Cookie: this.Bot.cookies["qun.qq.com"] },
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 数据版
|
||||
let res = await new QQApi(e).dragon(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
e.reply([
|
||||
`本群龙王:${res.nick}`,
|
||||
segment.image(`https://q1.qlogo.cn/g?b=qq&s=100&nk=${res.uin}`),
|
||||
`蝉联天数:${res.avatar_size}`
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* 群星级
|
||||
* @param e
|
||||
*/
|
||||
async Group_xj(e) {
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qqweb.qq.com/m/business/qunlevel/index.html?gc=${e.group_id}&from=0&_wv=1027`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
emulate: "QQTheme",
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后发送数据
|
||||
let result = await new QQApi(e).getCreditLevelInfo(e.group_id)
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
if (result.ec != 0) return e.reply("❎ 查询错误\n" + JSON.stringify(result))
|
||||
let { uiGroupLevel, group_name, group_uin } = result.info
|
||||
let str = "⭐"
|
||||
str = str.repeat(uiGroupLevel)
|
||||
e.reply([
|
||||
`群名:${group_name}\n`,
|
||||
`群号:${group_uin}\n`,
|
||||
`群星级:${str}`
|
||||
])
|
||||
}
|
||||
|
||||
// 群发言榜单
|
||||
async SpeakRank(e) {
|
||||
if (!common.checkPermission(e, "all", "admin")) return
|
||||
|
||||
// 图片截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/m/qun/activedata/speaking.html?gc=${e.group_id}&time=${/(7|七)天/.test(e.msg) ? 1 : 0}`,
|
||||
headers: { Cookie: this.Bot.cookies["qun.qq.com"] },
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后发送文字数据
|
||||
let res = await new QQApi(e).SpeakRank(e.group_id, /(7|七)天/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply("❎ 未知错误\n" + JSON.stringify(res))
|
||||
let msg = _.take(res.data.speakRank.map((item, index) =>
|
||||
`${index + 1}:${item.nickname}-${item.uin}\n连续活跃${item.active}天:发言${item.msgCount}次`
|
||||
), 10).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 今日打卡
|
||||
async DaySigned(e) {
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/v2/signin/list?gc=${e.group_id}`,
|
||||
emulate: "iPhone 6",
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后使用接口
|
||||
let res = await new QQApi(e).signInToday(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retCode != 0) return e.reply("❎ 未知错误\n" + JSON.stringify(res))
|
||||
|
||||
let list = res.response.page[0]
|
||||
if (list.total == 0) return e.reply("❎ 今天还没有人打卡")
|
||||
// 发送消息
|
||||
let msg = list.infos.map((item, index) => `${index + 1}:${item.uidGroupNick}-${item.uid}\n打卡时间:${moment(item.signedTimeStamp * 1000).format("YYYY-MM-DD HH:mm:ss")}`).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 查看某天谁生日
|
||||
async groupBirthday(e) {
|
||||
let date = e.msg.match(/^#?(今天|昨天|明天|后天|\d{4}-\d{1,2}-\d{1,2})谁生日$/)[1]
|
||||
if (date == "昨天") {
|
||||
date = moment().subtract(1, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "前天") {
|
||||
date = moment().subtract(2, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "明天") {
|
||||
date = moment().add(1, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "后天") {
|
||||
date = moment().add(2, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "今天") {
|
||||
date = moment().format("YYYY-MM-DD")
|
||||
}
|
||||
e.reply(
|
||||
await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/qqweb/m/qun/calendar/detail.html?_wv=1031&_bid=2340&src=3&gc=${e.group_id}&type=2&date=${date}`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
emulate: "iPhone 6",
|
||||
font: true
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// 群数据
|
||||
async groupData(e) {
|
||||
if (!common.checkPermission(e, "all", "admin")) return
|
||||
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/m/qun/activedata/active.html?_wv=3&_wwv=128&gc=${e.group_id}&src=2`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
click: /(7|七)天/.test(e.msg)
|
||||
? [
|
||||
{
|
||||
selector: "#app > div.tabbar > div.tabbar__time > div.tabbar__time__date",
|
||||
time: 500
|
||||
},
|
||||
{
|
||||
selector: "#app > div.tabbar > div.tabbar__date-selector > div > div:nth-child(3)",
|
||||
time: 1000
|
||||
}
|
||||
]
|
||||
: false,
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 数据
|
||||
let res = await new QQApi(e).groupData(e.group_id, /(7|七)天/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply(res.msg || JSON.stringify(res))
|
||||
let { groupInfo, activeData, msgInfo, joinData, exitData, applyData } = res.data
|
||||
e.reply(
|
||||
[
|
||||
`${groupInfo.groupName}(${groupInfo.groupCode})${/(7|七)天/.test(e.msg) ? "七天" : "昨天"}的群数据\n`,
|
||||
"------------消息条数---------\n",
|
||||
`消息条数:${msgInfo.total}\n`,
|
||||
"------------活跃人数---------\n",
|
||||
`活跃人数:${activeData.activeData}\n`,
|
||||
`总人数:${activeData.groupMember}\n`,
|
||||
`活跃比例:${activeData.ratio}%\n`,
|
||||
"-----------加退群人数--------\n",
|
||||
`申请人数:${joinData.total}\n`,
|
||||
`入群人数:${applyData.total}\n`,
|
||||
`退群人数:${exitData.total}\n`
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启或关闭加群通知
|
||||
* @param e
|
||||
@@ -724,38 +418,4 @@ export class GroupAdmin extends plugin {
|
||||
await e.group.muteMember(e.user_id, TabooTime * Company)
|
||||
e.reply("那我就不手下留情了~", true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 加白名单
|
||||
*/
|
||||
async whiteQQ() {
|
||||
if (!common.checkPermission(this.e, "master")) return
|
||||
|
||||
let type = /加/.test(this.e.msg) ? "add" : "del"
|
||||
let qq = this.e.at || (this.e.msg.match(/\d+/)?.[0] || "")
|
||||
qq = Number(qq) || String(qq)
|
||||
|
||||
if (!qq) return this.reply("❎ 请艾特或输入需要加白的QQ")
|
||||
|
||||
const { whiteQQ } = Config.groupAdmin
|
||||
const isWhite = whiteQQ.includes(qq)
|
||||
|
||||
if (isWhite && type === "add") return this.reply("❎ 此人已在群管白名单内")
|
||||
if (!isWhite && type === "del") return this.reply("❎ 此人未在群管白名单中")
|
||||
|
||||
Config.modifyarr("groupAdmin", "whiteQQ", qq, type)
|
||||
this.reply(`✅ 已${type === "add" ? "加入" : "删除"}${qq}到群管白名单`)
|
||||
}
|
||||
|
||||
async noBan() {
|
||||
if (!common.checkPermission(this.e, "master")) return
|
||||
let type = !!/开启/.test(this.e.msg)
|
||||
|
||||
const { noBan } = Config.groupAdmin
|
||||
if (noBan && type) return this.reply("❎ 白名单自动解禁已处于开启状态")
|
||||
if (!noBan && !type) return this.reply("❎ 白名单自动解禁已处于关闭状态")
|
||||
|
||||
Config.modify("groupAdmin", "noBan", type)
|
||||
this.reply(`✅ 已${type ? "开启" : "关闭"}白名单自动解禁`)
|
||||
}
|
||||
}
|
||||
|
||||
193
apps/groupAdmin/groupAdminOther.js
Normal file
193
apps/groupAdmin/groupAdminOther.js
Normal file
@@ -0,0 +1,193 @@
|
||||
import moment from "moment"
|
||||
import _ from "lodash"
|
||||
import { QQApi, common, puppeteer } from "../../model/index.js"
|
||||
// API请求错误文案
|
||||
const API_ERROR = "❎ 出错辣,请稍后重试"
|
||||
export class GroupAdminOther extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群管-其他",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: "^#?(谁|哪个吊毛|哪个屌毛|哪个叼毛)是龙王$",
|
||||
fnc: "dragonKing"
|
||||
},
|
||||
{
|
||||
reg: "^#群星级$",
|
||||
fnc: "Group_xj"
|
||||
},
|
||||
{
|
||||
reg: "^#群数据((7|七)天)?$",
|
||||
fnc: "groupData"
|
||||
},
|
||||
{
|
||||
reg: "^#今日打卡$",
|
||||
fnc: "DaySigned"
|
||||
},
|
||||
{
|
||||
reg: "^#((今|昨|前|明|后)天|\\d{4}-\\d{1,2}-\\d{1,2})谁生日$",
|
||||
fnc: "groupBirthday"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
// 谁是龙王
|
||||
async dragonKing(e) {
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/interactive/honorlist?gc=${e.group_id}&type=1&_wv=3&_wwv=129`,
|
||||
headers: { Cookie: this.Bot.cookies["qun.qq.com"] },
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 数据版
|
||||
let res = await new QQApi(e).dragon(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
e.reply([
|
||||
`本群龙王:${res.nick}`,
|
||||
segment.image(`https://q1.qlogo.cn/g?b=qq&s=100&nk=${res.uin}`),
|
||||
`蝉联天数:${res.avatar_size}`
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* 群星级
|
||||
* @param e
|
||||
*/
|
||||
async Group_xj(e) {
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qqweb.qq.com/m/business/qunlevel/index.html?gc=${e.group_id}&from=0&_wv=1027`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
emulate: "QQTheme",
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后发送数据
|
||||
let result = await new QQApi(e).getCreditLevelInfo(e.group_id)
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
if (result.ec != 0) return e.reply("❎ 查询错误\n" + JSON.stringify(result))
|
||||
let { uiGroupLevel, group_name, group_uin } = result.info
|
||||
let str = "⭐"
|
||||
str = str.repeat(uiGroupLevel)
|
||||
e.reply([
|
||||
`群名:${group_name}\n`,
|
||||
`群号:${group_uin}\n`,
|
||||
`群星级:${str}`
|
||||
])
|
||||
}
|
||||
|
||||
// 群发言榜单
|
||||
async SpeakRank(e) {
|
||||
if (!common.checkPermission(e, "all", "admin")) return
|
||||
|
||||
// 图片截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/m/qun/activedata/speaking.html?gc=${e.group_id}&time=${/(7|七)天/.test(e.msg) ? 1 : 0}`,
|
||||
headers: { Cookie: this.Bot.cookies["qun.qq.com"] },
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后发送文字数据
|
||||
let res = await new QQApi(e).SpeakRank(e.group_id, /(7|七)天/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply("❎ 未知错误\n" + JSON.stringify(res))
|
||||
let msg = _.take(res.data.speakRank.map((item, index) =>
|
||||
`${index + 1}:${item.nickname}-${item.uin}\n连续活跃${item.active}天:发言${item.msgCount}次`
|
||||
), 10).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 今日打卡
|
||||
async DaySigned(e) {
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/v2/signin/list?gc=${e.group_id}`,
|
||||
emulate: "iPhone 6",
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 出错后使用接口
|
||||
let res = await new QQApi(e).signInToday(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retCode != 0) return e.reply("❎ 未知错误\n" + JSON.stringify(res))
|
||||
|
||||
let list = res.response.page[0]
|
||||
if (list.total == 0) return e.reply("❎ 今天还没有人打卡")
|
||||
// 发送消息
|
||||
let msg = list.infos.map((item, index) => `${index + 1}:${item.uidGroupNick}-${item.uid}\n打卡时间:${moment(item.signedTimeStamp * 1000).format("YYYY-MM-DD HH:mm:ss")}`).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 查看某天谁生日
|
||||
async groupBirthday(e) {
|
||||
let date = e.msg.match(/^#?(今天|昨天|明天|后天|\d{4}-\d{1,2}-\d{1,2})谁生日$/)[1]
|
||||
if (date == "昨天") {
|
||||
date = moment().subtract(1, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "前天") {
|
||||
date = moment().subtract(2, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "明天") {
|
||||
date = moment().add(1, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "后天") {
|
||||
date = moment().add(2, "days").format("YYYY-MM-DD")
|
||||
} else if (date == "今天") {
|
||||
date = moment().format("YYYY-MM-DD")
|
||||
}
|
||||
e.reply(
|
||||
await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/qqweb/m/qun/calendar/detail.html?_wv=1031&_bid=2340&src=3&gc=${e.group_id}&type=2&date=${date}`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
emulate: "iPhone 6",
|
||||
font: true
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// 群数据
|
||||
async groupData(e) {
|
||||
if (!common.checkPermission(e, "all", "admin")) return
|
||||
|
||||
// 浏览器截图
|
||||
let screenshot = await puppeteer.Webpage({
|
||||
url: `https://qun.qq.com/m/qun/activedata/active.html?_wv=3&_wwv=128&gc=${e.group_id}&src=2`,
|
||||
cookie: common.getck("qun.qq.com", this.Bot, true),
|
||||
click: /(7|七)天/.test(e.msg)
|
||||
? [
|
||||
{
|
||||
selector: "#app > div.tabbar > div.tabbar__time > div.tabbar__time__date",
|
||||
time: 500
|
||||
},
|
||||
{
|
||||
selector: "#app > div.tabbar > div.tabbar__date-selector > div > div:nth-child(3)",
|
||||
time: 1000
|
||||
}
|
||||
]
|
||||
: false,
|
||||
font: true
|
||||
})
|
||||
if (screenshot) return e.reply(screenshot)
|
||||
// 数据
|
||||
let res = await new QQApi(e).groupData(e.group_id, /(7|七)天/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply(res.msg || JSON.stringify(res))
|
||||
let { groupInfo, activeData, msgInfo, joinData, exitData, applyData } = res.data
|
||||
e.reply(
|
||||
[
|
||||
`${groupInfo.groupName}(${groupInfo.groupCode})${/(7|七)天/.test(e.msg) ? "七天" : "昨天"}的群数据\n`,
|
||||
"------------消息条数---------\n",
|
||||
`消息条数:${msgInfo.total}\n`,
|
||||
"------------活跃人数---------\n",
|
||||
`活跃人数:${activeData.activeData}\n`,
|
||||
`总人数:${activeData.groupMember}\n`,
|
||||
`活跃比例:${activeData.ratio}%\n`,
|
||||
"-----------加退群人数--------\n",
|
||||
`申请人数:${joinData.total}\n`,
|
||||
`入群人数:${applyData.total}\n`,
|
||||
`退群人数:${exitData.total}\n`
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
63
apps/groupAdmin/groupAnnounce.js
Normal file
63
apps/groupAdmin/groupAnnounce.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import { QQApi, common } from "../../model/index.js"
|
||||
// API请求错误文案
|
||||
const API_ERROR = "❎ 出错辣,请稍后重试"
|
||||
export class GroupAnnounce extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群管-群公告",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: "^#发群公告",
|
||||
fnc: "AddAnnounce"
|
||||
},
|
||||
{
|
||||
reg: "^#删群公告(\\d+)$",
|
||||
fnc: "DelAnnounce"
|
||||
},
|
||||
{
|
||||
reg: "^#查群公告$",
|
||||
fnc: "GetAnnounce"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
// 发群公告
|
||||
async AddAnnounce(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
// 获取发送的内容
|
||||
let msg = e.msg.replace(/#|发群公告/g, "").trim()
|
||||
if (!msg) return e.reply("❎ 公告不能为空")
|
||||
|
||||
let result = await new QQApi(e).setAnnounce(e.group_id, msg)
|
||||
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
if (result.ec != 0) {
|
||||
e.reply("❎ 发送失败\n" + JSON.stringify(result, null, "\t"))
|
||||
}
|
||||
}
|
||||
|
||||
// 查群公告
|
||||
async GetAnnounce(e) {
|
||||
let res = await new QQApi(e).getAnnouncelist(e.group_id)
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
return e.reply(res)
|
||||
}
|
||||
|
||||
// 删群公告
|
||||
async DelAnnounce(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
let msg = e.msg.replace(/#|删群公告/g, "").trim()
|
||||
if (!msg) return e.reply("❎ 序号不可为空")
|
||||
let result = await new QQApi(e).delAnnounce(e.group_id, msg)
|
||||
if (!result) return e.reply(API_ERROR)
|
||||
|
||||
if (result.ec == 0) {
|
||||
e.reply(`✅ 已删除「${result.text}」`)
|
||||
} else {
|
||||
e.reply("❎ 删除失败\n" + JSON.stringify(result, null, "\t"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { common, GroupBannedWords } from "../../model/index.js"
|
||||
import { common, GroupBannedWords as groupBannedWords } from "../../model/index.js"
|
||||
import { Config } from "../../components/index.js"
|
||||
import _ from "lodash"
|
||||
|
||||
export class NewGroupBannedWords extends plugin {
|
||||
export class GroupBannedWords extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群违禁词",
|
||||
name: "椰奶群管-违禁词",
|
||||
event: "message.group",
|
||||
priority: 1,
|
||||
rule: [
|
||||
@@ -47,21 +47,21 @@ export class NewGroupBannedWords extends plugin {
|
||||
if (!e.message || e.isMaster || e.member?.is_owner || e.member?.is_admin || isWhite) {
|
||||
return false
|
||||
}
|
||||
const groupBannedWords = GroupBannedWords.initTextArr(e.group_id)
|
||||
if (_.isEmpty(groupBannedWords)) {
|
||||
const bannedWords = groupBannedWords.initTextArr(e.group_id)
|
||||
if (_.isEmpty(bannedWords)) {
|
||||
return false
|
||||
}
|
||||
const KeyWord = e.raw_message.trim()
|
||||
const trimmedKeyWord = this.#trimAlias(KeyWord)
|
||||
let data = null
|
||||
for (const [ k, v ] of groupBannedWords) {
|
||||
for (const [ k, v ] of bannedWords) {
|
||||
if (k.test(trimmedKeyWord)) {
|
||||
data = v
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!data) return false
|
||||
const muteTime = GroupBannedWords.getMuteTime(e.group_id)
|
||||
const muteTime = groupBannedWords.getMuteTime(e.group_id)
|
||||
const punishments = {
|
||||
1: () => e.member.kick(),
|
||||
2: () => this.#mute(muteTime),
|
||||
@@ -84,7 +84,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
}
|
||||
if (punishments[data.penaltyType]) {
|
||||
punishments[data.penaltyType]()
|
||||
const keyWordTran = await GroupBannedWords.keyWordTran(data.rawItem)
|
||||
const keyWordTran = await groupBannedWords.keyWordTran(data.rawItem)
|
||||
const senderCard = e.sender.card || e.sender.nickname
|
||||
const wordNum = keyWordTran.length - 2
|
||||
const replaceWord = "*".repeat(wordNum < 0 ? 0 : wordNum)
|
||||
@@ -139,7 +139,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
}
|
||||
}
|
||||
try {
|
||||
let res = GroupBannedWords.addBannedWords(
|
||||
let res = groupBannedWords.addBannedWords(
|
||||
e.group_id, word[3].trim(), word[1], word[2], e.user_id
|
||||
)
|
||||
e.reply([
|
||||
@@ -160,7 +160,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
word = word.replace(/#?删除违禁词/, "").trim()
|
||||
if (!word) return e.reply("需要删除的屏蔽词为空")
|
||||
try {
|
||||
let msg = await GroupBannedWords.delBannedWords(e.group_id, word)
|
||||
let msg = await groupBannedWords.delBannedWords(e.group_id, word)
|
||||
e.reply([ "✅ 成功删除:", msg ])
|
||||
} catch (error) {
|
||||
common.handleException(e, error)
|
||||
@@ -172,7 +172,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
word = word.replace(/#?查看违禁词/, "").trim()
|
||||
if (!word) return e.reply("需要查询的屏蔽词为空")
|
||||
try {
|
||||
const { words, matchType, penaltyType, addedBy, date } = GroupBannedWords.queryBannedWords(e.group_id, word)
|
||||
const { words, matchType, penaltyType, addedBy, date } = groupBannedWords.queryBannedWords(e.group_id, word)
|
||||
e.reply([
|
||||
"✅ 查询屏蔽词\n",
|
||||
"屏蔽词:",
|
||||
@@ -188,19 +188,19 @@ export class NewGroupBannedWords extends plugin {
|
||||
}
|
||||
|
||||
async list(e) {
|
||||
const groupBannedWords = GroupBannedWords.initTextArr(e.group_id)
|
||||
if (_.isEmpty(groupBannedWords)) {
|
||||
const bannedWords = groupBannedWords.initTextArr(e.group_id)
|
||||
if (_.isEmpty(bannedWords)) {
|
||||
return e.reply("❎ 没有违禁词")
|
||||
}
|
||||
let isRaw = /(原始)|(raw)/.test(e.msg)
|
||||
const msg = []
|
||||
for (const [ , v ] of groupBannedWords) {
|
||||
for (const [ , v ] of bannedWords) {
|
||||
const { matchType, penaltyType, addedBy, date, rawItem } = v
|
||||
msg.push([
|
||||
"屏蔽词:",
|
||||
isRaw ? rawItem : await GroupBannedWords.keyWordTran(rawItem),
|
||||
`\n匹配模式:${GroupBannedWords.matchTypeMap[matchType]}\n`,
|
||||
`处理方式:${GroupBannedWords.penaltyTypeMap[penaltyType]}\n`,
|
||||
isRaw ? rawItem : await bannedWords.keyWordTran(rawItem),
|
||||
`\n匹配模式:${bannedWords.matchTypeMap[matchType]}\n`,
|
||||
`处理方式:${bannedWords.penaltyTypeMap[penaltyType]}\n`,
|
||||
`添加人:${addedBy ?? "未知"}\n`,
|
||||
`添加时间:${date ?? "未知"}`
|
||||
])
|
||||
@@ -211,14 +211,14 @@ export class NewGroupBannedWords extends plugin {
|
||||
async muteTime(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) return false
|
||||
let time = e.msg.match(/\d+/)[0]
|
||||
GroupBannedWords.setMuteTime(e.group_id, time)
|
||||
groupBannedWords.setMuteTime(e.group_id, time)
|
||||
e.reply(`✅ 群${e.group_id}违禁词禁言时间已设置为${time}s`)
|
||||
}
|
||||
|
||||
// 增删查头衔屏蔽词
|
||||
async ProhibitedTitle(e) {
|
||||
// 获取现有的头衔屏蔽词
|
||||
let shieldingWords = GroupBannedWords.getTitleBannedWords(e.group_id)
|
||||
let shieldingWords = groupBannedWords.getTitleBannedWords(e.group_id)
|
||||
// 判断是否需要查看头衔屏蔽词
|
||||
if (/查看/.test(e.msg)) {
|
||||
// 返回已有的头衔屏蔽词列表
|
||||
@@ -249,7 +249,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
if (isAddition) {
|
||||
// 添加新的屏蔽词
|
||||
if (!_.isEmpty(newWords)) {
|
||||
GroupBannedWords.addTitleBannedWords(e.group_id, newWords)
|
||||
groupBannedWords.addTitleBannedWords(e.group_id, newWords)
|
||||
e.reply(`✅ 成功添加:${newWords.join(",")}`)
|
||||
}
|
||||
// 提示已有的屏蔽词
|
||||
@@ -259,7 +259,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
} else {
|
||||
// 删除已有的屏蔽词
|
||||
if (!_.isEmpty(existingWords)) {
|
||||
GroupBannedWords.delTitleBannedWords(e.group_id, existingWords)
|
||||
groupBannedWords.delTitleBannedWords(e.group_id, existingWords)
|
||||
e.reply(`✅ 成功删除:${existingWords.join(",")}`)
|
||||
}
|
||||
// 提示不在屏蔽词中的词
|
||||
@@ -272,7 +272,7 @@ export class NewGroupBannedWords extends plugin {
|
||||
// 修改头衔匹配模式
|
||||
async ProhibitedTitlePattern(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) return false
|
||||
let res = GroupBannedWords.setTitleFilterModeChange(e.group_id)
|
||||
let res = groupBannedWords.setTitleFilterModeChange(e.group_id)
|
||||
e.reply(`✅ 已修改匹配模式为${res ? "精确" : "模糊"}匹配`)
|
||||
}
|
||||
}
|
||||
|
||||
82
apps/groupAdmin/groupLuckyword.js
Normal file
82
apps/groupAdmin/groupLuckyword.js
Normal file
@@ -0,0 +1,82 @@
|
||||
import { QQApi, common } from "../../model/index.js"
|
||||
// API请求错误文案
|
||||
const API_ERROR = "❎ 出错辣,请稍后重试"
|
||||
export class GroupLuckyword extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群管-幸运字符",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: "^#(查)?(幸运)?字符(列表)?$",
|
||||
fnc: "qun_luckylist"
|
||||
},
|
||||
{
|
||||
reg: "^#抽(幸运)?字符$",
|
||||
fnc: "qun_lucky"
|
||||
},
|
||||
{
|
||||
reg: "^#替换(幸运)?字符(\\d+)$",
|
||||
fnc: "qun_luckyuse"
|
||||
},
|
||||
{
|
||||
reg: "^#(开启|关闭)(幸运)?字符$",
|
||||
fnc: "qun_luckyset"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
// 字符列表
|
||||
async qun_luckylist(e) {
|
||||
let data = await new QQApi(e).luckylist(e.group_id)
|
||||
if (!data) return e.reply(API_ERROR)
|
||||
if (data.retcode != 0) return e.reply("❎ 获取数据失败\n" + JSON.stringify(data))
|
||||
|
||||
let msg = data.data.word_list.map((item, index) => {
|
||||
let { wording, word_id, word_desc } = item.word_info
|
||||
return `${word_id}:${wording}\n寓意:${word_desc}`
|
||||
}).join("\n")
|
||||
e.reply(msg)
|
||||
}
|
||||
|
||||
// 抽幸运字符
|
||||
async qun_lucky(e) {
|
||||
let res = await new QQApi(e).drawLucky(e.group_id)
|
||||
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode == 11004) return e.reply("❎ 今天已经抽过了,明天再来抽取吧")
|
||||
if (res.retcode != 0) return e.reply("❎ 错误\n" + JSON.stringify(res.data))
|
||||
|
||||
if (res.data.word_info) {
|
||||
let { wording, word_desc } = res.data.word_info.word_info
|
||||
e.reply(`恭喜您抽中了${wording}\n寓意为:${word_desc}`)
|
||||
} else {
|
||||
e.reply("恭喜您抽了中了个寂寞")
|
||||
}
|
||||
}
|
||||
|
||||
// 替换幸运字符
|
||||
async qun_luckyuse(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
let id = e.msg.replace(/#|替换(幸运)?字符/g, "")
|
||||
let res = await new QQApi(e).equipLucky(e.group_id, id)
|
||||
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
if (res.retcode != 0) return e.reply("❎替换失败\n" + JSON.stringify(res))
|
||||
e.reply("✅ OK")
|
||||
}
|
||||
|
||||
// 开启或关闭群字符
|
||||
async qun_luckyset(e) {
|
||||
if (!common.checkPermission(e, "admin", "admin")) { return true }
|
||||
|
||||
let res = await new QQApi(e).swichLucky(e.group_id, /开启/.test(e.msg))
|
||||
if (!res) return e.reply(API_ERROR)
|
||||
|
||||
if (res.retcode == 11111) return e.reply("❎ 重复开启或关闭")
|
||||
if (res.retcode != 0) return e.reply("❎ 错误\n" + JSON.stringify(res))
|
||||
e.reply("✅ OK")
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,10 @@ import { sleep } from "../../tools/index.js"
|
||||
// 全局
|
||||
let temp = {}
|
||||
const ops = [ "+", "-" ]
|
||||
export class NewGroupVerify extends plugin {
|
||||
export class GroupVerify extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶入群验证",
|
||||
dsc: "重新验证和绕过验证",
|
||||
name: "椰奶群管-入群验证",
|
||||
event: "message.group",
|
||||
priority: 5,
|
||||
rule: [
|
||||
|
||||
56
apps/groupAdmin/groupWhiteListCtrl.js
Normal file
56
apps/groupAdmin/groupWhiteListCtrl.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import { common } from "../../model/index.js"
|
||||
import { Config } from "../../components/index.js"
|
||||
|
||||
export class groupWhiteListCtrl extends plugin {
|
||||
constructor() {
|
||||
super({
|
||||
name: "椰奶群管-白名单",
|
||||
event: "message.group",
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: "^#?群管(加|删)白(名单)?",
|
||||
fnc: "whiteQQ"
|
||||
},
|
||||
{
|
||||
reg: "^#?(开启|关闭)白名单(自动)?解禁",
|
||||
fnc: "noBan"
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加白名单
|
||||
*/
|
||||
async whiteQQ() {
|
||||
if (!common.checkPermission(this.e, "master")) return
|
||||
|
||||
let type = /加/.test(this.e.msg) ? "add" : "del"
|
||||
let qq = this.e.at || (this.e.msg.match(/\d+/)?.[0] || "")
|
||||
qq = Number(qq) || String(qq)
|
||||
|
||||
if (!qq) return this.reply("❎ 请艾特或输入需要加白的QQ")
|
||||
|
||||
const { whiteQQ } = Config.groupAdmin
|
||||
const isWhite = whiteQQ.includes(qq)
|
||||
|
||||
if (isWhite && type === "add") return this.reply("❎ 此人已在群管白名单内")
|
||||
if (!isWhite && type === "del") return this.reply("❎ 此人未在群管白名单中")
|
||||
|
||||
Config.modifyarr("groupAdmin", "whiteQQ", qq, type)
|
||||
this.reply(`✅ 已${type === "add" ? "加入" : "删除"}${qq}到群管白名单`)
|
||||
}
|
||||
|
||||
async noBan() {
|
||||
if (!common.checkPermission(this.e, "master")) return
|
||||
let type = !!/开启/.test(this.e.msg)
|
||||
|
||||
const { noBan } = Config.groupAdmin
|
||||
if (noBan && type) return this.reply("❎ 白名单自动解禁已处于开启状态")
|
||||
if (!noBan && !type) return this.reply("❎ 白名单自动解禁已处于关闭状态")
|
||||
|
||||
Config.modify("groupAdmin", "noBan", type)
|
||||
this.reply(`✅ 已${type ? "开启" : "关闭"}白名单自动解禁`)
|
||||
}
|
||||
}
|
||||
@@ -175,4 +175,4 @@ export default new class {
|
||||
Data.writeJSON(`${groupId}.json`, data, this.root)
|
||||
this.groupTitleCach.delete(groupId)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -3,23 +3,22 @@ import os from "os"
|
||||
|
||||
/** 获取当前内存占用 */
|
||||
export default function getMemUsage() {
|
||||
// 内存使用率
|
||||
let MemUsage = (1 - os.freemem() / os.totalmem()).toFixed(2)
|
||||
// 空闲内存
|
||||
let freemem = getFileSize(os.freemem())
|
||||
// 总共内存
|
||||
let totalmem = getFileSize(os.totalmem())
|
||||
// 使用内存
|
||||
let Usingmemory = getFileSize((os.totalmem() - os.freemem()))
|
||||
const freeMemory = os.freemem()
|
||||
const totalMemory = os.totalmem()
|
||||
|
||||
const memoryUsagePercentage = (1 - freeMemory / totalMemory).toFixed(2)
|
||||
const freeMem = getFileSize(freeMemory)
|
||||
const totalMem = getFileSize(totalMemory)
|
||||
const usingMemory = getFileSize(totalMemory - freeMemory)
|
||||
|
||||
return {
|
||||
...Circle(MemUsage),
|
||||
inner: Math.round(MemUsage * 100) + "%",
|
||||
...Circle(memoryUsagePercentage),
|
||||
inner: `${Math.round(memoryUsagePercentage * 100)}%`,
|
||||
title: "RAM",
|
||||
info: [
|
||||
`总共 ${totalmem}`,
|
||||
`已用 ${Usingmemory}`,
|
||||
`空闲 ${freemem}`
|
||||
`总共 ${totalMem}`,
|
||||
`已用 ${usingMemory}`,
|
||||
`空闲 ${freeMem}`
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +20,21 @@ export function addData(arr, data, maxLen = 60) {
|
||||
/**
|
||||
* 将文件大小从字节转化为可读性更好的格式,例如B、KB、MB、GB、TB。
|
||||
* @param {number} size - 带转化的字节数。
|
||||
* @param {boolean} [isByte] - 如果为 true,则最终的文件大小显示保留 B 的后缀.
|
||||
* @param {boolean} [isSuffix] - 如果为 true,则在所得到的大小后面加上 kb、mb、gb、tb 等后缀.
|
||||
* @param {boolean} [showByte] - 如果为 true,则最终的文件大小显示保留 B 的后缀.
|
||||
* @param {boolean} [showSuffix] - 如果为 true,则在所得到的大小后面加上 kb、mb、gb、tb 等后缀.
|
||||
* @returns {string} 文件大小格式转换后的字符串.
|
||||
*/
|
||||
export function getFileSize(size, isByte = true, isSuffix = true) { // 把字节转换成正常文件大小
|
||||
export function getFileSize(size, showByte = true, showSuffix = true) { // 把字节转换成正常文件大小
|
||||
if (size == null || size == undefined) return 0
|
||||
let num = 1024.00 // byte
|
||||
if (isByte && size < num) {
|
||||
if (showByte && size < num) {
|
||||
return size.toFixed(2) + "B"
|
||||
}
|
||||
if (size < Math.pow(num, 2)) {
|
||||
return (size / num).toFixed(2) + `K${isSuffix ? "b" : ""}`
|
||||
return (size / num).toFixed(2) + `K${showSuffix ? "b" : ""}`
|
||||
} // kb
|
||||
if (size < Math.pow(num, 3)) {
|
||||
return (size / Math.pow(num, 2)).toFixed(2) + `M${isSuffix ? "b" : ""}`
|
||||
return (size / Math.pow(num, 2)).toFixed(2) + `M${showSuffix ? "b" : ""}`
|
||||
} // M
|
||||
if (size < Math.pow(num, 4)) {
|
||||
return (size / Math.pow(num, 3)).toFixed(2) + "G"
|
||||
|
||||
@@ -25,47 +25,75 @@
|
||||
* // 输出: "1h 1m 5s"
|
||||
*/
|
||||
export default function formatDuration(time, format, repair = true) {
|
||||
const second = parseInt(time % 60)
|
||||
const minute = parseInt((time / 60) % 60)
|
||||
const hour = parseInt((time / (60 * 60)) % 24)
|
||||
const day = parseInt(time / (24 * 60 * 60))
|
||||
const timeObj = {
|
||||
const timeObj = computeTimeObject(time, repair)
|
||||
if (typeof format === "function") {
|
||||
return format(timeObj)
|
||||
}
|
||||
|
||||
if (format === "default") {
|
||||
return formatDefault(timeObj)
|
||||
}
|
||||
|
||||
if (typeof format === "string") {
|
||||
return formatTemplate(format, timeObj)
|
||||
}
|
||||
|
||||
return timeObj
|
||||
}
|
||||
// 默认格式化逻辑拆分到单独的函数,提高代码可维护性
|
||||
function formatDefault(timeObj) {
|
||||
const { day, hour, minute, second } = timeObj
|
||||
let result = ""
|
||||
|
||||
if (day > 0) {
|
||||
result += `${day}天`
|
||||
}
|
||||
if (hour > 0) {
|
||||
result += `${hour}小时`
|
||||
}
|
||||
if (minute > 0) {
|
||||
result += `${minute}分`
|
||||
}
|
||||
if (second > 0) {
|
||||
result += `${second}秒`
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 字符串模板格式化逻辑拆分到单独的函数
|
||||
function formatTemplate(format, timeObj) {
|
||||
const replaceRegexes = [
|
||||
{ pattern: /dd/g, value: timeObj.day },
|
||||
{ pattern: /hh/g, value: timeObj.hour },
|
||||
{ pattern: /mm/g, value: timeObj.minute },
|
||||
{ pattern: /ss/g, value: timeObj.second }
|
||||
]
|
||||
|
||||
// 优化字符串替换逻辑
|
||||
for (const { pattern, value } of replaceRegexes) {
|
||||
format = format.replace(pattern, value)
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算并返回表示时间的对象。
|
||||
* @param {number} time - 要计算的时间(以秒为单位)。
|
||||
* @param {boolean} [repair] - 修复小时、分钟和秒的显示格式的可选参数。如果设置为true,并且小时、分钟或秒小于10,则在值前面添加零。
|
||||
* @returns {{day: string, hour: string, minute: string, second: string}} - 包含天、小时、分钟和秒的时间对象。
|
||||
*/
|
||||
function computeTimeObject(time, repair = true) {
|
||||
const second = parseInt(time % 60, 10)
|
||||
const minute = Math.floor(time / 60)
|
||||
const hour = Math.floor(minute / 60)
|
||||
const day = Math.floor(time / (24 * 60 * 60))
|
||||
|
||||
return {
|
||||
day,
|
||||
hour: repair && hour < 10 ? `0${hour}` : hour,
|
||||
minute: repair && minute < 10 ? `0${minute}` : minute,
|
||||
second: repair && second < 10 ? `0${second}` : second
|
||||
}
|
||||
if (typeof format === "function") {
|
||||
return format(timeObj)
|
||||
}
|
||||
|
||||
if (format == "default") {
|
||||
let result = ""
|
||||
|
||||
if (day > 0) {
|
||||
result += `${day}天`
|
||||
}
|
||||
if (hour > 0) {
|
||||
result += `${timeObj.hour}小时`
|
||||
}
|
||||
if (minute > 0) {
|
||||
result += `${timeObj.minute}分`
|
||||
}
|
||||
if (second > 0) {
|
||||
result += `${timeObj.second}秒`
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
if (typeof format === "string") {
|
||||
format = format
|
||||
.replace(/dd/g, day)
|
||||
.replace(/hh/g, timeObj.hour)
|
||||
.replace(/mm/g, timeObj.minute)
|
||||
.replace(/ss/g, timeObj.second)
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
return timeObj
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user