Miao-Yunzai/model/ledger.ts

556 lines
14 KiB
TypeScript
Raw Normal View History

2024-06-14 10:44:18 +08:00
import base from './base.js'
import { MysInfo, MysApi } from 'yunzai/mys'
import lodash from 'lodash'
import moment from 'moment'
import fs from 'node:fs'
import { sleep } from 'yunzai/utils'
export default class Ledger extends base {
constructor(e) {
super(e)
this.e = e
this.model = 'ledger'
2024-06-17 23:04:18 +08:00
if (this.e.msg?.includes('星琼')) this.e.isSr = true
this.color = [
'#73a9c6',
'#d56565',
'#70b2b4',
'#bd9a5a',
'#739970',
'#7a6da7',
'#597ea0'
]
2024-06-14 10:44:18 +08:00
this.action = {
2024-06-17 23:04:18 +08:00
other: 0,
adventure_reward: 1,
space_reward: 2,
daily_reward: 3,
abyss_reward: 4,
mail_reward: 5,
event_reward: 6
2024-06-14 10:44:18 +08:00
}
}
async get() {
this.getMonth()
if (!this.month) return
let res = await MysInfo.get(this.e, 'ys_ledger', { month: this.month })
if (!res || res.retcode !== 0) return false
this.e.nowData = res.data
let data = this.dealData(res.data)
this.saveLedger(this.e.uid)
return data
}
getMonth() {
let month = this.e.msg.replace(/#|原石|月|札记|星铁|星琼/g, '')
let NowMonth = Number(moment().month()) + 1
2024-06-17 23:04:18 +08:00
let monthData = [
'一',
'二',
'三',
'四',
'五',
'六',
'七',
'八',
'九',
'十',
'十一',
'十二'
]
2024-06-14 10:44:18 +08:00
if (month) {
if (isNaN(month)) {
for (let i in monthData) {
if (month == monthData[i]) {
month = Number(i) + 1
break
}
}
if (isNaN(month)) {
month = NowMonth
}
}
} else {
month = NowMonth
}
if (month < 1 || month > 12) {
month = NowMonth
}
// 获取前三个月
2024-06-17 23:04:18 +08:00
let monthArr = [11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].splice(
NowMonth - 1,
3
)
2024-06-14 10:44:18 +08:00
if (!monthArr.includes(Number(month))) {
this.e.reply('札记仅支持查询最近三个月的数据')
return false
}
2024-06-17 23:04:18 +08:00
if (
(NowMonth >= 3 && month > NowMonth) ||
(NowMonth < 3 && month > NowMonth && month <= 9 + month)
) {
2024-06-14 10:44:18 +08:00
month = NowMonth
}
if (this.e.isSr) {
2024-06-17 23:04:18 +08:00
this.NowMonth =
moment().year().toString() +
(NowMonth < 10 ? '0' : '') +
NowMonth.toString()
this.month =
moment().year().toString() + (month < 10 ? '0' : '') + month.toString()
2024-06-14 10:44:18 +08:00
this.srmonth = month
} else {
this.NowMonth = NowMonth
this.month = month
}
}
dealData(ledgerInfo) {
let day
if (this.month == this.NowMonth) {
day = `${this[this.e.isSr ? 'srmonth' : 'month']}${moment().date()}`
} else {
day = `${this[this.e.isSr ? 'srmonth' : 'month']}`
}
let gacha = this.e.isSr ? 'current_hcoin' : 'current_primogems'
let last_gacha = this.e.isSr ? 'last_hcoin' : 'last_primogems'
let mora = this.e.isSr ? 'current_rails_pass' : 'current_mora'
let last_mora = this.e.isSr ? 'last_rails_pass' : 'last_mora'
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data.gacha = (ledgerInfo.month_data[gacha] / 160).toFixed(
0
)
ledgerInfo.month_data.last_gacha = (
ledgerInfo.month_data[last_gacha] / 160
).toFixed(0)
2024-06-14 10:44:18 +08:00
if (ledgerInfo.month_data[gacha] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data[gacha] =
(ledgerInfo.month_data[gacha] / 10000).toFixed(2) + ' w'
2024-06-14 10:44:18 +08:00
}
if (ledgerInfo.month_data[last_gacha] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data[last_gacha] =
(ledgerInfo.month_data[last_gacha] / 10000).toFixed(2) + ' w'
2024-06-14 10:44:18 +08:00
}
if (ledgerInfo.month_data[mora] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data[mora] =
(ledgerInfo.month_data[mora] / 10000).toFixed(1) + ' w'
2024-06-14 10:44:18 +08:00
}
if (ledgerInfo.month_data[last_mora] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data[last_mora] =
(ledgerInfo.month_data[last_mora] / 10000).toFixed(1) + ' w'
2024-06-14 10:44:18 +08:00
}
if (ledgerInfo.day_data[gacha] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.day_data[gacha] =
(ledgerInfo.day_data[gacha] / 10000).toFixed(1) + ' w'
2024-06-14 10:44:18 +08:00
}
if (ledgerInfo.day_data[mora] > 10000) {
2024-06-17 23:04:18 +08:00
ledgerInfo.day_data[mora] =
(ledgerInfo.day_data[mora] / 10000).toFixed(1) + ' w'
2024-06-14 10:44:18 +08:00
}
ledgerInfo.color = []
2024-06-17 23:04:18 +08:00
ledgerInfo.month_data.group_by.forEach(item => {
2024-06-14 10:44:18 +08:00
if (this.e.isSr) {
item.color = this.color[this.action[item.action]]
item.action_name = item.action_name.slice(0, 4)
} else {
item.color = this.color[item.action_id]
}
ledgerInfo.color.push(item.color)
})
ledgerInfo.group_by = JSON.stringify(ledgerInfo.month_data.group_by)
ledgerInfo.color = JSON.stringify(ledgerInfo.color)
let icon = ''
if (this.e.isSr)
2024-06-17 23:04:18 +08:00
icon = lodash.sample(
fs
.readdirSync(
`${this._path}/plugins/genshin/resources/StarRail/img/role`
)
.filter(file => file.endsWith('.webp'))
)
2024-06-14 10:44:18 +08:00
let week = [
'星期日',
'星期一',
'星期二',
'星期三',
'星期四',
'星期五',
'星期六'
]
return {
saveId: this.e.uid,
uid: this.e.uid,
2024-06-17 23:04:18 +08:00
day,
icon,
2024-06-14 10:44:18 +08:00
srday: `${week[moment().day()]}`,
nowDay: moment(new Date()).format('YYYY年MM月DD日'),
...ledgerInfo,
...this.screenData
}
}
// 保存上两个原石数据
async saveLedger(uid, ck = '', isTask = false) {
if (ck) {
uid = ck.uid
} else {
/** 获取个人ck */
ck = await MysInfo.checkUidBing(uid, this.e.isSr ? 'sr' : 'gs')
}
if (!ck || lodash.isEmpty(ck)) {
return false
}
let dataPath = `./data/${this.e?.isSr ? 'SR_NoteData' : 'NoteData'}/${uid}.json`
let NoteData = {}
if (fs.existsSync(dataPath)) {
NoteData = JSON.parse(fs.readFileSync(dataPath, 'utf8'))
}
// 当前年
let NowYear = Number(moment().year())
let NowMonth = Number(moment().month()) + 1
// 获取前三个月
2024-06-17 23:04:18 +08:00
let monthArr = [11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].splice(
NowMonth - 1,
3
)
2024-06-14 10:44:18 +08:00
for (let month of monthArr) {
let year = NowYear
// 上一年
if (NowMonth <= 2 && month >= 11) {
year--
}
if (!NoteData[year]) NoteData[year] = {}
2024-06-17 23:04:18 +08:00
if (
NoteData[year][month] &&
NowMonth != month &&
NoteData[year][month].isUpdate
)
continue
2024-06-14 10:44:18 +08:00
let ledgerInfo
2024-06-17 23:04:18 +08:00
if (
NowMonth == month &&
this.e.nowData &&
this.e.nowData?.data?.data_month == NowMonth
) {
2024-06-14 10:44:18 +08:00
ledgerInfo = this.e.nowData
} else {
let months = month
2024-06-17 23:04:18 +08:00
if (this.e.isSr)
months = String(year) + (month < 10 ? '0' : '') + String(month)
2024-06-14 10:44:18 +08:00
ledgerInfo = await this.ysLedger(ck, months, isTask)
if (!ledgerInfo) continue
}
if (NowMonth != month) {
ledgerInfo.isUpdate = true
}
NoteData[year][month] = ledgerInfo
sleep(100)
}
logger.mark(`[札记查询][自动保存] uid:${uid} 数据已保存`)
fs.writeFileSync(dataPath, JSON.stringify(NoteData, '', '\t'))
return NoteData
}
async ysLedger(ck, month, isTask) {
let ledgerInfo = {}
if (isTask) {
let mysApi = new MysApi(ck.uid, ck.ck, { log: false }, this.e?.isSr)
ledgerInfo = await mysApi.getData('ys_ledger', { month })
2024-06-17 23:04:18 +08:00
ledgerInfo = await new MysInfo(this.e).checkCode(
ledgerInfo,
'ys_ledger',
mysApi,
{ month },
isTask
)
2024-06-14 10:44:18 +08:00
} else {
ledgerInfo = await MysInfo.get(this.e, 'ys_ledger', { month })
}
if (!ledgerInfo || ledgerInfo.retcode != 0) return false
return ledgerInfo.data
}
async ledgerTask(manual) {
let cks = (await GsCfg.getBingCk(this.e?.isSr ? 'sr' : 'gs')).ck
let uids = lodash.map(cks, 'uid')
2024-06-17 23:04:18 +08:00
let finishTime = moment()
.add(uids.length * 0.7, 's')
.format('MM-DD HH:mm:ss')
logger.mark(
`${this.e?.isSr ? '开拓月历' : '札记'}ck:${uids.length}个,预计需要${this.countTime(uids.length)} ${finishTime} 完成`
)
2024-06-14 10:44:18 +08:00
if (manual) {
2024-06-17 23:04:18 +08:00
await this.e.reply(
`开始任务:保存${this.e?.isSr ? '星琼' : '原石'}数据,完成前请勿重复执行`
)
await this.e.reply(
`${this.e?.isSr ? '开拓月历' : '札记'}ck${uids.length}\n预计需要${this.countTime(uids.length)}\n完成时间${finishTime}`
)
2024-06-14 10:44:18 +08:00
}
for (const uid of uids) {
const ck = cks[uid]
await this.saveLedger(uid, ck, true)
await sleep(500)
}
if (manual) {
this.e.reply(`${this.e?.isSr ? '星琼' : '原石'}任务完成`)
}
}
countTime(num) {
let time = num * 0.7
let hour = Math.floor((time / 3600) % 24)
let min = Math.floor((time / 60) % 60)
let sec = Math.floor(time % 60)
let msg = ''
if (hour > 0) msg += `${hour}小时`
if (min > 0) msg += `${min}分钟`
if (sec > 0) msg += `${sec}`
return msg
}
async ledgerCount() {
this.model = 'ledgerCount'
let mysInfo = await MysInfo.init(this.e, 'ys_ledger')
let uid = mysInfo?.uid
if (!uid) return false
/** 保存札记数据 */
let NoteData = await this.saveLedger(uid)
/** 处理数据 */
return this.ledgerCountData(NoteData)
}
async ledgerCountHistory() {
let nowYear
if (this.e.msg.includes('去年')) {
nowYear = moment().year() - 1
} else if (this.e.msg.includes('今年')) {
nowYear = moment().year()
} else {
// 获取年份
nowYear = this.e.msg.match(/(\d{4})/)
}
if (nowYear) {
nowYear = parseInt(nowYear)
}
if (!nowYear) {
nowYear = moment().year()
}
this.model = 'ledgerCount'
let mysInfo = await MysInfo.init(this.e, 'ys_ledger')
let uid = mysInfo?.uid
if (!uid) return false
let dataPath = `./data/${this.e?.isSr ? 'SR_NoteData' : 'NoteData'}/${uid}.json`
let NoteData = {}
if (fs.existsSync(dataPath)) {
NoteData = JSON.parse(fs.readFileSync(dataPath, 'utf8'))
}
// console.log(NoteData)
if (!NoteData || lodash.isEmpty(NoteData)) {
2024-06-17 23:04:18 +08:00
this.e.reply(
this.e?.isSr
? [
'暂无星琼数据,请先发送 *星琼',
segment.button([{ text: '星琼', input: '*星琼' }])
]
: [
'暂无原石数据,请先发送 #原石',
segment.button([{ text: '原石', input: '#原石' }])
],
false,
{ at: true }
)
2024-06-14 10:44:18 +08:00
return false
}
NoteData = NoteData[nowYear]
if (!NoteData) {
2024-06-17 23:04:18 +08:00
this.e.reply(
`uid${uid} ${nowYear}年无${this.e?.isSr ? '星琼' : '原石'}统计数据!`,
false,
{ at: true }
)
2024-06-14 10:44:18 +08:00
return false
}
2024-06-17 23:04:18 +08:00
lodash.forEach(NoteData, val => {
2024-06-14 10:44:18 +08:00
val.year = nowYear
})
/** 处理数据 */
return this.ledgerCountData(NoteData, String(nowYear))
}
ledgerCountData(NoteData, nowYear) {
let hasMore = false
let yearText
if (!nowYear) {
// 获取总长度
2024-06-17 23:04:18 +08:00
if (
NoteData &&
Object.keys(NoteData) &&
Object.keys(NoteData).length > 0
) {
2024-06-14 10:44:18 +08:00
let len = 0
2024-06-17 23:04:18 +08:00
Object.keys(NoteData).forEach(year => {
2024-06-14 10:44:18 +08:00
let yearData = NoteData[year]
len += Object.keys(yearData).length
})
hasMore = len >= 12
}
// 获取最近12个月的数据
const newNoteData = []
for (let i = 0; i < 12; i++) {
let month = Number(moment().month()) + 1 - i
let year = Number(moment().year())
if (month <= 0) {
month = 12 + month
year--
}
if (NoteData[year] && NoteData[year][month]) {
NoteData[year][month].year = year
newNoteData.push(NoteData[year][month])
}
}
NoteData = newNoteData
} else {
yearText = `${nowYear}年-`
}
if (!NoteData || lodash.isEmpty(NoteData)) return
let data = {
allPrimogems: 0,
allMora: 0,
primogemsMonth: [],
moraMonth: [],
yearText
}
let Primogems = this.e.isSr ? 'current_hcoin' : 'current_primogems'
let Mora = this.e.isSr ? 'current_rails_pass' : 'current_mora'
2024-06-17 23:04:18 +08:00
lodash.forEach(NoteData, val => {
2024-06-14 10:44:18 +08:00
data.allPrimogems += val.month_data[Primogems]
data.allMora += val.month_data[Mora]
// 柱状图数据
if (this.e.isSr)
2024-06-17 23:04:18 +08:00
val.data_month =
val.data_month.slice(-2, -1) == '0'
? val.data_month.slice(-1)
: val.data_month.slice(-2)
2024-06-14 10:44:18 +08:00
data.primogemsMonth.push({
value: val.month_data[Primogems],
month: String(val.data_month),
year: String(val.year),
name: this.e.isSr ? '星琼' : '原石'
})
data.moraMonth.push({
value: (val.month_data[Mora] / 1000).toFixed(0),
month: String(val.data_month),
year: String(val.year),
name: this.e.isSr ? '专&通票' : '摩拉'
})
})
// 单位处理
data.allPrimogemsShow = (data.allPrimogems / 10000).toFixed(2) + 'w'
data.allGacha = (data.allPrimogems / 160).toFixed(0)
if (this.e.isSr) {
data.allGacha = (data.allPrimogems / 160 + data.allMora).toFixed(0)
data.allMora = data.allMora.toFixed(0) + '张'
} else {
data.allMora = (data.allMora / 10000).toFixed(0) + 'w'
}
// 原石最多
data.maxPrimogems = lodash.maxBy(data.primogemsMonth, 'value')
data.maxMora = lodash.maxBy(data.moraMonth, 'value')
// 按年份月份排序
data.primogemsMonth = lodash.sortBy(data.primogemsMonth, item => {
return Number(item.year) * 100 + Number(item.month)
})
2024-06-17 23:04:18 +08:00
let groupBy = lodash(NoteData)
.map('month_data')
.map('group_by')
.flatMap()
.value()
2024-06-14 10:44:18 +08:00
if (this.e.isSr)
2024-06-17 23:04:18 +08:00
groupBy.forEach(item => {
2024-06-14 10:44:18 +08:00
item.action_id = this.action[item.action]
item.action = item.action_name.slice(0, 4)
})
let pieData = {}
for (let val of groupBy) {
if (!pieData[val.action]) {
pieData[val.action] = {
num: val.num,
action: val.action,
action_id: val.action_id
}
} else {
pieData[val.action].num += val.num
}
}
2024-06-17 23:04:18 +08:00
pieData = lodash.flatMap(pieData, item => {
2024-06-14 10:44:18 +08:00
return item
})
pieData = lodash.orderBy(pieData, ['num'], ['desc'])
data.color = []
2024-06-17 23:04:18 +08:00
pieData.forEach(item => {
2024-06-14 10:44:18 +08:00
data.color.push(this.color[item.action_id])
})
data.group_by = pieData
data.color = JSON.stringify(data.color)
data.pieData = JSON.stringify(pieData)
data.primogemsMonth = JSON.stringify(data.primogemsMonth)
data.hasMore = hasMore
return {
saveId: this.e.uid,
uid: this.e.uid,
...data,
...this.screenData
}
}
}