删除 xlsx

This commit is contained in:
🌌 2023-12-09 23:12:53 +08:00
parent 76c63405bb
commit db55e7702e
5 changed files with 9 additions and 258 deletions

View File

@ -21,7 +21,7 @@
"chalk": "^5.3.0", "chalk": "^5.3.0",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"https-proxy-agent": "7.0.2", "https-proxy-agent": "7.0.2",
"icqq": "^0.6.3", "icqq": "^0.6.5",
"image-size": "^1.0.2", "image-size": "^1.0.2",
"inquirer": "^9.2.12", "inquirer": "^9.2.12",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@ -30,17 +30,16 @@
"moment": "^2.29.4", "moment": "^2.29.4",
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"node-schedule": "^2.1.1", "node-schedule": "^2.1.1",
"node-xlsx": "^0.23.0",
"oicq": "^2.3.1", "oicq": "^2.3.1",
"pm2": "^5.3.0", "pm2": "^5.3.0",
"puppeteer": "^21.5.1", "puppeteer": "^21.6.0",
"redis": "^4.6.10", "redis": "^4.6.11",
"sequelize": "^6.34.0", "sequelize": "^6.35.1",
"sqlite3": "^5.1.6", "sqlite3": "^5.1.6",
"yaml": "^2.3.4" "yaml": "^2.3.4"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.53.0", "eslint": "^8.55.0",
"eslint-config-standard": "^17.1.0", "eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.29.0", "eslint-plugin-import": "^2.29.0",
"eslint-plugin-n": "^16.3.1", "eslint-plugin-n": "^16.3.1",

View File

@ -52,9 +52,7 @@
|#武器统计|统计抽卡数据,按卡池统计| |#武器统计|统计抽卡数据,按卡池统计|
|#常驻统计|统计抽卡数据,按卡池统计| |#常驻统计|统计抽卡数据,按卡池统计|
|#记录帮助|抽卡记录导入说明| |#记录帮助|抽卡记录导入说明|
|#导出记录|抽卡记录xlsx导出| |#导出记录|抽卡记录json导出|
|#导出记录json|抽卡记录json导出|
|xlsx文件导入|xlsx导入统一可交换祈愿记录v2.2|
|json文件导入|json导入统一可交换祈愿记录v2.2| |json文件导入|json导入统一可交换祈愿记录v2.2|
| 其他指令 | 说明| | 其他指令 | 说明|

View File

@ -22,10 +22,6 @@ export class gcLog extends plugin {
reg: '^#txt日志文件导入记录$', reg: '^#txt日志文件导入记录$',
fnc: 'logFile' fnc: 'logFile'
}, },
{
reg: '^#xlsx文件导入记录$',
fnc: 'logXlsx'
},
{ {
reg: '^#json文件导入记录$', reg: '^#json文件导入记录$',
fnc: 'logJson' fnc: 'logJson'
@ -35,7 +31,7 @@ export class gcLog extends plugin {
fnc: 'getLog' fnc: 'getLog'
}, },
{ {
reg: '^#*(原神|星铁)?导出记录(excel|xlsx|json)*$', reg: '^#*(原神|星铁)?导出记录(json)?$',
fnc: 'exportLog' fnc: 'exportLog'
}, },
{ {
@ -72,10 +68,6 @@ export class gcLog extends plugin {
this.e.msg = '#txt日志文件导入记录' this.e.msg = '#txt日志文件导入记录'
if (name.includes('output')) return true 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)) { if (/(.*)[1-9][0-9]{8}(.*).json/ig.test(name)) {
this.e.msg = '#json文件导入记录' this.e.msg = '#json文件导入记录'
return true return true
@ -142,27 +134,7 @@ export class gcLog extends plugin {
} }
let exportLog = new ExportLog(this.e) let exportLog = new ExportLog(this.e)
return await exportLog.exportJson()
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()
} }
async logJson () { async logJson () {

View File

@ -40,7 +40,7 @@
desc: 按卡池统计抽卡数据 desc: 按卡池统计抽卡数据
- icon: excel - icon: excel
title: 导出记录、导入记录 title: 导出记录、导入记录
desc: 导出导入xlsx、json抽卡记录 desc: 导出导入json抽卡记录
- icon: 纠缠之缘 - icon: 纠缠之缘
title: 十连 十连2 定轨 十连武器 title: 十连 十连2 定轨 十连武器
desc: 真实模拟抽卡 desc: 真实模拟抽卡

View File

@ -6,8 +6,6 @@ import moment from 'moment'
import GachaLog from './gachaLog.js' import GachaLog from './gachaLog.js'
import lodash from 'lodash' import lodash from 'lodash'
let xlsx = {}
export default class ExportLog extends base { export default class ExportLog extends base {
constructor(e) { constructor(e) {
super(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() { async exportJson() {
if (!this.e.isSr) { if (!this.e.isSr) {
await common.downFile('https://api.uigf.org/dict/genshin/chs.json', './temp/uigf/genshin.json') 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, () => { }) 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() { async getUid() {
let gachLog = new GachaLog(this.e) let gachLog = new GachaLog(this.e)
let uid = await gachLog.getUid() let uid = await gachLog.getUid()
@ -215,178 +169,6 @@ export default class ExportLog extends base {
return JSON.parse(fs.readFileSync(json, 'utf8')) 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导入抽卡记录 */ /** json导入抽卡记录 */
async logJson() { async logJson() {
let uid = /[1-9][0-9]{8}/g.exec(this.e.file.name)[0] let uid = /[1-9][0-9]{8}/g.exec(this.e.file.name)[0]