From db55e7702ede1d1dce5e84579e27fad211d05747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=8C=8C?= Date: Sat, 9 Dec 2023 23:12:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=20xlsx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 11 +- plugins/genshin/README.md | 4 +- plugins/genshin/apps/gcLog.js | 32 +--- plugins/genshin/defSet/bot/help.yaml | 2 +- plugins/genshin/model/exportLog.js | 218 --------------------------- 5 files changed, 9 insertions(+), 258 deletions(-) diff --git a/package.json b/package.json index c3c454d..b606dd2 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "chalk": "^5.3.0", "chokidar": "^3.5.3", "https-proxy-agent": "7.0.2", - "icqq": "^0.6.3", + "icqq": "^0.6.5", "image-size": "^1.0.2", "inquirer": "^9.2.12", "lodash": "^4.17.21", @@ -30,17 +30,16 @@ "moment": "^2.29.4", "node-fetch": "^3.3.2", "node-schedule": "^2.1.1", - "node-xlsx": "^0.23.0", "oicq": "^2.3.1", "pm2": "^5.3.0", - "puppeteer": "^21.5.1", - "redis": "^4.6.10", - "sequelize": "^6.34.0", + "puppeteer": "^21.6.0", + "redis": "^4.6.11", + "sequelize": "^6.35.1", "sqlite3": "^5.1.6", "yaml": "^2.3.4" }, "devDependencies": { - "eslint": "^8.53.0", + "eslint": "^8.55.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.0", "eslint-plugin-n": "^16.3.1", diff --git a/plugins/genshin/README.md b/plugins/genshin/README.md index a88631e..0f6beb0 100644 --- a/plugins/genshin/README.md +++ b/plugins/genshin/README.md @@ -52,9 +52,7 @@ |#武器统计|统计抽卡数据,按卡池统计| |#常驻统计|统计抽卡数据,按卡池统计| |#记录帮助|抽卡记录导入说明| -|#导出记录|抽卡记录xlsx导出| -|#导出记录json|抽卡记录json导出| -|xlsx文件导入|xlsx导入,统一可交换祈愿记录v2.2| +|#导出记录|抽卡记录json导出| |json文件导入|json导入,统一可交换祈愿记录v2.2| | 其他指令 | 说明| diff --git a/plugins/genshin/apps/gcLog.js b/plugins/genshin/apps/gcLog.js index a0cb7b5..d5dfded 100644 --- a/plugins/genshin/apps/gcLog.js +++ b/plugins/genshin/apps/gcLog.js @@ -22,10 +22,6 @@ export class gcLog extends plugin { reg: '^#txt日志文件导入记录$', fnc: 'logFile' }, - { - reg: '^#xlsx文件导入记录$', - fnc: 'logXlsx' - }, { reg: '^#json文件导入记录$', fnc: 'logJson' @@ -35,7 +31,7 @@ export class gcLog extends plugin { fnc: 'getLog' }, { - reg: '^#*(原神|星铁)?导出记录(excel|xlsx|json)*$', + reg: '^#*(原神|星铁)?导出记录(json)?$', fnc: 'exportLog' }, { @@ -72,10 +68,6 @@ export class gcLog extends plugin { this.e.msg = '#txt日志文件导入记录' if (name.includes('output')) return true } - if (/(.*)[1-9][0-9]{8}(.*).xlsx$/ig.test(name)) { - this.e.msg = '#xlsx文件导入记录' - return true - } if (/(.*)[1-9][0-9]{8}(.*).json/ig.test(name)) { this.e.msg = '#json文件导入记录' return true @@ -142,27 +134,7 @@ export class gcLog extends plugin { } let exportLog = new ExportLog(this.e) - - if (this.e.msg.includes('json')) { - return await exportLog.exportJson() - } else { - await this.e.reply('如需要将此记录导入到其他平台,请导出json格式文件') - return await exportLog.exportXlsx() - } - } - - async logXlsx () { - if (!this.e.isPrivate) { - await this.e.reply('请私聊发送日志文件', false, { at: true }) - return true - } - - if (!this.e.file) { - await this.e.reply('请发送xlsx文件') - return true - } - await this.e.reply('如果是星铁记录,请在【原始数据】工作表复制【gacha_type】列,粘贴并把此标题重命名为【srgf_gacha_type】,否则可能无法正确识别') - await new ExportLog(this.e).logXlsx() + return await exportLog.exportJson() } async logJson () { diff --git a/plugins/genshin/defSet/bot/help.yaml b/plugins/genshin/defSet/bot/help.yaml index a653a8a..2683d7b 100644 --- a/plugins/genshin/defSet/bot/help.yaml +++ b/plugins/genshin/defSet/bot/help.yaml @@ -40,7 +40,7 @@ desc: 按卡池统计抽卡数据 - icon: excel title: 导出记录、导入记录 - desc: 导出导入xlsx、json抽卡记录 + desc: 导出导入json抽卡记录 - icon: 纠缠之缘 title: 十连 十连2 定轨 十连武器 desc: 真实模拟抽卡 diff --git a/plugins/genshin/model/exportLog.js b/plugins/genshin/model/exportLog.js index 70b05c8..9bfef28 100644 --- a/plugins/genshin/model/exportLog.js +++ b/plugins/genshin/model/exportLog.js @@ -6,8 +6,6 @@ import moment from 'moment' import GachaLog from './gachaLog.js' import lodash from 'lodash' -let xlsx = {} - export default class ExportLog extends base { constructor(e) { super(e) @@ -56,12 +54,6 @@ export default class ExportLog extends base { } } - async initXlsx() { - if (!lodash.isEmpty(xlsx)) return xlsx - - xlsx = await import('node-xlsx') - } - async exportJson() { if (!this.e.isSr) { await common.downFile('https://api.uigf.org/dict/genshin/chs.json', './temp/uigf/genshin.json') @@ -107,44 +99,6 @@ export default class ExportLog extends base { fs.unlink(saveFile, () => { }) } - async exportXlsx() { - await this.getUid() - - if (!this.uid) return false - - await this.initXlsx() - - logger.mark(`${this.e.logFnc} 开始导出${this.uid}.xlsx`) - - let res = this.getAllList() - - /** 处理卡池数据 */ - let xlsxData = this.xlsxDataPool(res) - /** 处理所有数据 */ - xlsxData.push(this.xlsxDataAll(res)) - - /** node-xlsx导出的buffer有点大.. */ - let buffer = xlsx.build(xlsxData) - let saveFile = `${this.path}${this.uid}/${this.uid}.xlsx` - - fs.writeFileSync(saveFile, Buffer.from(buffer)) - - logger.mark(`${this.e.logFnc} 导出成功${this.uid}.xlsx`) - - this.e.reply(`记录文件${this.uid}.xlsx上传中,请耐心等待...`) - - res = await this.e.friend.sendFile(saveFile).catch((err) => { - this.e.reply(`发送文件${this.uid}.xlsx失败,请稍后再试`) - logger.error(`${this.e.logFnc} 发送文件失败 ${JSON.stringify(err)}`) - }) - - let line = xlsxData[xlsxData.length - 1].data.length - 1 - if (res) this.e.reply(`${this.uid}.xlsx上传成功,共${line}条\n请接收文件`) - - /** 删除文件 */ - fs.unlink(saveFile, () => { }) - } - async getUid() { let gachLog = new GachaLog(this.e) let uid = await gachLog.getUid() @@ -215,178 +169,6 @@ export default class ExportLog extends base { return JSON.parse(fs.readFileSync(json, 'utf8')) } - xlsxDataPool(data) { - let xlsxData = [] - - for (let v of this.pool(this.game)) { - let poolData = [ - [ - '时间', '名称', '物品类型', '星级', '祈愿类型' - ] - ] - for (let log of data[v.type]) { - poolData.push([ - log.time, log.name, log.item_type, log.rank_type, log.gacha_type - ]) - } - - let sheetOptions = { - '!cols': [{ wch: 20 }, { wch: 20 }, { wch: 10 }, { wch: 10 }, { wch: 10 }] - } - xlsxData.push({ name: `${v.typeName}祈愿`, data: poolData, options: sheetOptions }) - } - - return xlsxData - } - - xlsxDataAll(data) { - let ui = this.e.isSr ? 'sr' : 'ui' - let list = [ - [ - 'count', 'gacha_type', 'id', 'item_id', 'item_type', 'lang', 'name', 'rank_type', 'time', 'uid', `${ui}gf_gacha_type` - ] - ] - for (let v of data.list) { - let tmp = [] - if (this.e.isSr) v.srgf_gacha_type = v.gacha_type - for (let i of list[0]) { - if (i == 'id' || i == `${ui}gf_gacha_type`) v[i] = String(v[i]) - tmp.push(v[i]) - } - list.push(tmp) - } - let sheetOptions = { - '!cols': [{ wch: 10 }, { wch: 10 }, { wch: 20 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 20 }, { wch: 10 }, { wch: 20 }, { wch: 10 }, { wch: 10 }] - } - - return { name: '原始数据', data: list, options: sheetOptions } - } - - /** xlsx导入抽卡记录 */ - async logXlsx() { - await this.initXlsx() - - let uid = /[1-9][0-9]{8}/g.exec(this.e.file.name)[0] - let textPath = `${this.path}${this.e.file.name}` - /** 获取文件下载链接 */ - let fileUrl = await this.e.friend.getFileUrl(this.e.file.fid) - - let ret = await common.downFile(fileUrl, textPath) - if (!ret) { - this.e.reply('下载xlsx文件错误') - return false - } - - let list = xlsx.parse(textPath) - list = lodash.keyBy(list, 'name') - - // 适配StarRailExport导出的xlsx,该xlsx没有原始数据表. - let rawData = list['原始数据'] ? list['原始数据'] : list['rawData']; - if (!list['原始数据'] && list['rawData']) { - // 获取rawData的time字段(第9列)的索引 - const timeIndex = 8; - - // 对rawData进行排序(按照time字段,除第一行外) - const headerRow = rawData.data[0]; // 保存标题行 - const dataToSort = rawData.data.slice(1); // 除第一行外的数据 - - dataToSort.sort((a, b) => { - return moment(a[timeIndex]).format('x') - moment(b[timeIndex]).format('x'); - }); - - // 重新构建rawData的数据,包括标题行 - rawData.data = [headerRow, ...dataToSort]; - - // 将数据写回原文件,重新读取 - fs.writeFileSync(textPath, xlsx.build([rawData])); - list = lodash.keyBy(xlsx.parse(textPath), 'name'); - rawData = list['rawData']; - } - - if (!rawData) { - this.e.reply('xlsx文件内容错误:非统一祈愿记录标准') - return false - } - - if (rawData.data[0].includes('srgf_gacha_type')) { - this.e.isSr = true - this.game = 'sr' - } - /** 处理xlsx数据 */ - let data = this.dealXlsx(rawData.data); - if (!data) return false - - /** 保存json */ - let msg = [] - for (let type in data) { - let typeName = this.typeName(this.game) - if (!typeName[type]) continue - let gachLog = new GachaLog(this.e) - gachLog.uid = uid - gachLog.type = type - gachLog.writeJson(data[type]) - - msg.push(`${typeName[type]}记录:${data[type].length}条`) - } - - /** 删除文件 */ - fs.unlink(textPath, () => { }) - - await this.e.reply(`${this.e.file.name},${this.e.isSr ? '星铁' : '原神'}记录导入成功\n${msg.join('\n')}`) - } - - dealXlsx(list) { - let ui = this.e.isSr ? 'sr' : 'ui' - /** 必要字段 */ - let reqField = ['gacha_type', 'item_type', 'name', 'time', `${ui}gf_gacha_type`] - /** 不是必要字段 */ - let noReqField = ['id', 'uid', 'count', 'item_id', 'lang', 'rank_type'] - - let field = {} - for (let i in list[0]) { - field[list[0][i]] = i - } - - /** 判断字段 */ - for (let v of reqField) { - if (!field[v]) { - let tips = v === 'srgf_gacha_type' ? '\n请在【原始数据】工作表复制【gacha_type】列,粘贴并把此标题重命名为【srgf_gacha_type】' : '' - this.e.reply(`xlsx文件内容错误:缺少必要字段${v}${tips}`) - return - } - } - - /** 倒序 */ - if (moment(list[1][field.time]).format('x') < moment(list[list.length - 1][field.time]).format('x')) { - list = list.reverse() - } - - let data = {} - for (let v of list) { - if (v[field.name] == 'name') continue - if (!data[v[field[`${ui}gf_gacha_type`]]]) data[v[field[`${ui}gf_gacha_type`]]] = [] - - let tmp = {} - /** 加入必要字段 */ - for (let re of reqField) { - tmp[re] = v[field[re]] - } - - /** 加入非必要字段 */ - for (let noRe of noReqField) { - if (field[noRe]) { - tmp[noRe] = v[field[noRe]] - } else { - tmp[noRe] = '' - } - } - - data[v[field[`${ui}gf_gacha_type`]]].push(tmp) - } - - return data - } - /** json导入抽卡记录 */ async logJson() { let uid = /[1-9][0-9]{8}/g.exec(this.e.file.name)[0]