2023-03-04 14:30:13 +08:00
|
|
|
|
import base from './base.js'
|
|
|
|
|
import cfg from '../../../lib/config/config.js'
|
|
|
|
|
import common from '../../../lib/common/common.js'
|
|
|
|
|
import fs from 'node:fs'
|
|
|
|
|
import moment from 'moment'
|
|
|
|
|
import GachaLog from './gachaLog.js'
|
|
|
|
|
import lodash from 'lodash'
|
|
|
|
|
|
|
|
|
|
export default class ExportLog extends base {
|
2023-10-13 02:52:05 +08:00
|
|
|
|
constructor(e) {
|
2023-03-04 14:30:13 +08:00
|
|
|
|
super(e)
|
|
|
|
|
this.model = 'gachaLog'
|
|
|
|
|
|
|
|
|
|
this.urlKey = `${this.prefix}url:`
|
|
|
|
|
/** 绑定的uid */
|
|
|
|
|
this.uidKey = `Yz:genshin:mys:qq-uid:${this.userId}`
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
this.path = this.e.isSr ? `./data/srJson/${this.e.user_id}/` : `./data/gachaJson/${this.e.user_id}/`
|
2023-03-04 14:30:13 +08:00
|
|
|
|
|
2023-11-03 20:57:26 +08:00
|
|
|
|
this.game = this.e.game
|
2023-10-25 17:32:57 +08:00
|
|
|
|
|
|
|
|
|
this.pool = (game = 'gs') => {
|
|
|
|
|
let pool = {
|
|
|
|
|
gs: [
|
|
|
|
|
{ type: 301, typeName: '角色活动' },
|
|
|
|
|
{ type: 302, typeName: '武器活动' },
|
|
|
|
|
{ type: 200, typeName: '常驻' }
|
|
|
|
|
],
|
|
|
|
|
sr: [
|
|
|
|
|
{ type: 11, typeName: '角色活动' },
|
|
|
|
|
{ type: 12, typeName: '武器活动' },
|
|
|
|
|
{ type: 2, typeName: '新手活动' },
|
|
|
|
|
{ type: 1, typeName: '常驻' }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
return pool[game]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.typeName = (game = 'gs') => {
|
|
|
|
|
let type = {
|
|
|
|
|
gs: {
|
|
|
|
|
301: '角色',
|
|
|
|
|
302: '武器',
|
|
|
|
|
200: '常驻'
|
|
|
|
|
},
|
|
|
|
|
sr: {
|
|
|
|
|
11: '角色',
|
|
|
|
|
12: '武器',
|
|
|
|
|
2: '新手',
|
|
|
|
|
1: '常驻'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return type[game]
|
|
|
|
|
}
|
2023-03-04 14:30:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
async exportJson() {
|
2023-10-25 17:32:57 +08:00
|
|
|
|
if (!this.e.isSr) {
|
|
|
|
|
await common.downFile('https://api.uigf.org/dict/genshin/chs.json', './temp/uigf/genshin.json')
|
|
|
|
|
}
|
2023-03-04 14:30:13 +08:00
|
|
|
|
await this.getUid()
|
|
|
|
|
|
|
|
|
|
if (!this.uid) return false
|
|
|
|
|
|
|
|
|
|
let list = this.getAllList().list
|
2024-01-25 00:56:49 +08:00
|
|
|
|
let yunzaiName = cfg.package.name
|
|
|
|
|
if (yunzaiName == 'miao-yunzai') {
|
|
|
|
|
yunzaiName = 'Miao-Yunzai'
|
|
|
|
|
} else if (yunzaiName == 'yunzai') {
|
|
|
|
|
yunzaiName = 'Yunzai-Bot'
|
|
|
|
|
} else if (yunzaiName == 'trss-yunzai') {
|
|
|
|
|
yunzaiName = 'TRSS-Yunzai'
|
|
|
|
|
} else {
|
|
|
|
|
yunzaiName = _.capitalize(yunzaiName)
|
|
|
|
|
}
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let data = {
|
|
|
|
|
info: {
|
|
|
|
|
uid: this.uid,
|
|
|
|
|
lang: list[0].lang,
|
|
|
|
|
export_time: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
export_timestamp: moment().format('X'),
|
2024-01-25 00:56:49 +08:00
|
|
|
|
export_app: yunzaiName,
|
2023-03-04 14:30:13 +08:00
|
|
|
|
export_app_version: cfg.package.version,
|
|
|
|
|
},
|
|
|
|
|
list
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 17:32:57 +08:00
|
|
|
|
if (this.e.isSr) {
|
|
|
|
|
data.info.srgf_version = 'v1.0'
|
|
|
|
|
data.info.region_time_zone = moment(list[0].time).utcOffset() / 60
|
|
|
|
|
} else {
|
|
|
|
|
data.info.uigf_version = 'v2.3'
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let saveFile = `${this.path}${this.uid}/${this.uid}.json`
|
|
|
|
|
|
|
|
|
|
fs.writeFileSync(saveFile, JSON.stringify(data, '', '\t'))
|
|
|
|
|
|
|
|
|
|
logger.mark(`${this.e.logFnc} 导出成功${this.uid}.json`)
|
|
|
|
|
|
|
|
|
|
this.e.reply(`导出成功:${this.uid}.json,共${list.length}条 \n请接收文件`)
|
|
|
|
|
|
2024-01-05 14:46:23 +08:00
|
|
|
|
if (this.e.group?.sendFile)
|
|
|
|
|
await this.e.group.sendFile(saveFile)
|
|
|
|
|
else if (this.e.friend?.sendFile)
|
|
|
|
|
await this.e.friend.sendFile(saveFile)
|
|
|
|
|
else this.e.reply('导出失败:暂不支持发送文件')
|
2023-03-04 14:30:13 +08:00
|
|
|
|
|
|
|
|
|
/** 删除文件 */
|
2023-10-13 02:52:05 +08:00
|
|
|
|
fs.unlink(saveFile, () => { })
|
2023-03-04 14:30:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
async getUid() {
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let gachLog = new GachaLog(this.e)
|
|
|
|
|
let uid = await gachLog.getUid()
|
|
|
|
|
|
|
|
|
|
if (!uid) return false
|
|
|
|
|
|
|
|
|
|
this.uid = uid
|
|
|
|
|
return this.uid
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
getAllList() {
|
2023-11-03 20:57:26 +08:00
|
|
|
|
let uigf = './temp/uigf/genshin.json'
|
|
|
|
|
try {
|
|
|
|
|
uigf = JSON.parse(fs.readFileSync(uigf, 'utf8'))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
uigf = false
|
|
|
|
|
}
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let res = {
|
|
|
|
|
list: []
|
|
|
|
|
}
|
|
|
|
|
let tmpId = {}
|
2023-10-25 17:32:57 +08:00
|
|
|
|
for (let v of this.pool(this.game)) {
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let json = `${this.path}${this.uid}/${v.type}.json`
|
|
|
|
|
if (fs.existsSync(json)) {
|
|
|
|
|
json = JSON.parse(fs.readFileSync(json, 'utf8'))
|
|
|
|
|
json = json.reverse()
|
|
|
|
|
} else {
|
|
|
|
|
json = []
|
|
|
|
|
}
|
|
|
|
|
res[v.type] = json
|
|
|
|
|
for (let v of json) {
|
2023-11-03 20:57:26 +08:00
|
|
|
|
if (!v.item_id && uigf) {
|
2023-10-25 17:32:57 +08:00
|
|
|
|
v.item_id = String(uigf[v.name])
|
|
|
|
|
}
|
|
|
|
|
if (!this.e.isSr) {
|
|
|
|
|
if (v.gacha_type == 301 || v.gacha_type == 400) {
|
|
|
|
|
v.uigf_gacha_type = '301'
|
|
|
|
|
} else {
|
|
|
|
|
v.uigf_gacha_type = v.gacha_type
|
|
|
|
|
}
|
2023-03-04 14:30:13 +08:00
|
|
|
|
}
|
|
|
|
|
let id = v.id
|
|
|
|
|
if (!id) {
|
|
|
|
|
id = moment(v.time).format('x') + '000000'
|
|
|
|
|
v.id = id
|
|
|
|
|
} else {
|
|
|
|
|
if (id.length == 13) {
|
|
|
|
|
v.id = `${id}000000`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tmpId[id]) {
|
|
|
|
|
let newId = `${id}00000${tmpId[id].length}`
|
|
|
|
|
tmpId[id].push(newId)
|
|
|
|
|
v.id = newId
|
|
|
|
|
} else {
|
|
|
|
|
tmpId[id] = [id]
|
|
|
|
|
}
|
|
|
|
|
res.list.push(v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res.list = lodash.orderBy(res.list, ['id', 'asc'])
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
loadJson(json) {
|
2023-03-04 14:30:13 +08:00
|
|
|
|
if (!fs.existsSync(json)) return []
|
|
|
|
|
return JSON.parse(fs.readFileSync(json, 'utf8'))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** json导入抽卡记录 */
|
2023-10-13 02:52:05 +08:00
|
|
|
|
async logJson() {
|
2024-02-04 09:02:39 +08:00
|
|
|
|
let uid = /([1-9]|18)[0-9]{8}/g.exec(this.e.file.name)[0]
|
2023-03-04 14:30:13 +08:00
|
|
|
|
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('下载json文件错误')
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
let json = {}
|
|
|
|
|
try {
|
|
|
|
|
json = JSON.parse(fs.readFileSync(textPath, 'utf8'))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.e.reply(`${this.e.file.name},json格式错误`)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lodash.isEmpty(json) || !json.list) {
|
|
|
|
|
this.e.reply('json文件内容错误:非统一祈愿记录标准')
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 17:32:57 +08:00
|
|
|
|
if (json.info.srgf_version) {
|
|
|
|
|
this.e.isSr = true
|
|
|
|
|
this.game = 'sr'
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let data = this.dealJson(json.list)
|
|
|
|
|
if (!data) return false
|
|
|
|
|
|
|
|
|
|
/** 保存json */
|
|
|
|
|
let msg = []
|
|
|
|
|
for (let type in data) {
|
2023-10-25 17:32:57 +08:00
|
|
|
|
let typeName = this.typeName(this.game)
|
|
|
|
|
if (!typeName[type]) continue
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let gachLog = new GachaLog(this.e)
|
|
|
|
|
gachLog.uid = uid
|
|
|
|
|
gachLog.type = type
|
|
|
|
|
gachLog.writeJson(data[type])
|
|
|
|
|
|
2023-10-25 17:32:57 +08:00
|
|
|
|
msg.push(`${typeName[type]}记录:${data[type].length}条`)
|
2023-03-04 14:30:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 删除文件 */
|
2023-10-13 02:52:05 +08:00
|
|
|
|
fs.unlink(textPath, () => { })
|
2023-03-04 14:30:13 +08:00
|
|
|
|
|
2023-10-25 17:32:57 +08:00
|
|
|
|
await this.e.reply(`${this.e.file.name},${this.e.isSr ? '星铁' : '原神'}记录导入成功\n${msg.join('\n')}`)
|
2023-03-04 14:30:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:52:05 +08:00
|
|
|
|
dealJson(list) {
|
2023-03-04 14:30:13 +08:00
|
|
|
|
let data = {}
|
|
|
|
|
|
|
|
|
|
/** 必要字段 */
|
|
|
|
|
let reqField = ['gacha_type', 'item_type', 'name', 'time']
|
|
|
|
|
|
|
|
|
|
for (let v of reqField) {
|
|
|
|
|
if (!list[0][v]) {
|
|
|
|
|
this.e.reply(`json文件内容错误:缺少必要字段${v}`)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 倒序 */
|
|
|
|
|
if (moment(list[0].time).format('x') < moment(list[list.length - 1].time).format('x')) {
|
|
|
|
|
list = list.reverse()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let v of list) {
|
2023-10-25 17:32:57 +08:00
|
|
|
|
if (this.game === 'sr') v.uigf_gacha_type = v.gacha_type
|
2023-03-04 14:30:13 +08:00
|
|
|
|
if (!data[v.uigf_gacha_type]) data[v.uigf_gacha_type] = []
|
|
|
|
|
data[v.uigf_gacha_type].push(v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
}
|