// ==UserScript==
// @name Hpoi Price Statistics
// @namespace niaier Hpoi Price Statistics
// @version 0.2
// @description 统计预定想买的预计价格和相关信息
// @match *://*.hpoi.net/user/*
// @author niaier
// @license MIT
// @match http://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant GM_addStyle
// @grant GM_getResourceText
// @grant GM_xmlhttpRequest
// @grant GM_download
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_setClipboard
// @grant unsafeWindow
// @grant window.close
// @grant window.focus
// @grant window.onurlchange
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
// @require https://cdn.jsdelivr.net/npm/vue@2.6.14
// @require https://unpkg.com/element-ui/lib/index.js
// @connect *
// @resource css https://unpkg.com/element-ui/lib/theme-chalk/index.css
// @downloadURL https://update.greasyfork.icu/scripts/435216/Hpoi%20Price%20Statistics.user.js
// @updateURL https://update.greasyfork.icu/scripts/435216/Hpoi%20Price%20Statistics.meta.js
// ==/UserScript==
(async function () {
GM_addStyle(GM_getResourceText("css"));
const vueApp = `
价格统计
全部
预定
{{syncDataTip}}
清空数据
添加数据
名称
价格
预付
待付
操作
{{unpaidResult[index]&&unpaidResult[index].unpaid}}
删除
总价: {{totalPrice}}
总待付: {{totalUnpaid}}
`
$('.info').eq(0).append(vueApp)
// Your code here...
async function getFigurePrice (url) {
let price = 0
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
"method": "GET",
"url": url,
"headers": {
"user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
},
"onload": function (result) {
// console.log(result);
var list = $.parseHTML(result.response);
list.forEach(function (item) {
const priceText = $(item).find('.hpoi-infoList-item span:contains("定价")').parent().find('p').text()
if (priceText) {
if (priceText.match(/\d+元/g) && priceText.match(/\d+元/g)[0]) {
price = priceText.match(/\d+元/g)[0].replace('元', "")
} else {
price = 0
}
resolve(price)
}
})
}
});
})
}
async function getAllCollection (mode) {
return new Promise(async function (resolve, reject) {
// const content = $('#content')
const itemList = $('#content .item')
// console.log(itemList);
const figureList = []
console.log(itemList.length);
for (const i in itemList) {
// const href = $(this).find('a').attr('href')
let href = ''
if ($(itemList[i]).find('a') && $(itemList[i]).find('a')[0]) {
href = $(itemList[i]).find('a')[0].href
// console.log(full);
const name = $(itemList[i]).find('.name').text().trim().replace(/\s/g, "")
const price = await getFigurePrice(href)
const obj = {
url: href,
name: name,
price: Number(price),
prepay: 0,
unpaid: 0
}
console.log(i);
figureList.push(obj)
}
if (i == itemList.length - 1) {
let itemMode;
if (mode == 'all') itemMode = 'figureList'
if (mode == 'pre') itemMode = 'preList'
const oldList = JSON.parse(window.localStorage.getItem(itemMode))
if (oldList) {
figureList.forEach(item => {
oldList.forEach(el => {
if (el.url == item.url) {
item.prepay = el.prepay
}
})
})
}
window.localStorage.setItem(itemMode, JSON.stringify(figureList))
resolve(figureList)
}
}
})
// console.log(figureList);
}
function getQueryString (name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
new Vue({
el: '#app',
data: {
syncDataTip: '同步数据',
message: 'Hello Vue!',
show: false,
priceDialogVisible: false,
// figureList: []
figureList: JSON.parse(window.localStorage.getItem('figureList')) || [{
url: '',
name: '',
price: 0,
prepay: 0,
unpaid: 0
}],
preList: JSON.parse(window.localStorage.getItem('preList')) || [{
url: '',
name: '',
price: 0,
prepay: 0,
unpaid: 0
}],
mode: 'all',
listData: [{
url: '',
name: '',
price: 0,
prepay: 0,
unpaid: 0
}]
},
computed: {
totalPrice () {
let total = 0
this.listData.forEach(item => {
total += Number(item.price)
})
return total
},
unpaidResult () {
let result = [{}]
if (this.listData) {
this.listData.forEach(item => {
item.unpaid = item.price - item.prepay
})
}
result = this.listData
return result
},
totalUnpaid () {
let total = 0
this.unpaidResult.forEach(item => {
total += Number(item.unpaid)
})
return total
}
},
created () {
// want preorder null
if (getQueryString('favState') == null) this.mode = "all"
if (getQueryString('favState') == 'preorder') this.mode = "pre"
if (getQueryString('favState') == 'want') this.mode = "want"
if (getQueryString('favState') == 'care') this.mode = "care"
if (getQueryString('favState') == 'buy') this.mode = "buy"
if (getQueryString('favState') == 'resell') this.mode = "resell"
this.changeMode()
console.log(this.listData);
},
methods: {
async syncData () {
this.syncDataTip = "同步数据中"
this.listData = await getAllCollection(this.mode)
this.syncDataTip = "同步完成"
},
handleShow () {
this.priceDialogVisible = true
},
handleClose () {
this.priceDialogVisible = false
},
getResult () {
console.log(this.figureList);
},
handleSave () {
let itemMode;
if (this.mode == 'all') itemMode = 'figureList'
if (this.mode == 'pre') itemMode = 'preList'
window.localStorage.setItem(itemMode, JSON.stringify(this.listData))
this.handleClose()
},
changeMode () {
if (this.mode == 'all') this.listData = this.figureList
if (this.mode == 'pre') this.listData = this.preList
},
clearData () {
this.listData = []
},
addData () {
this.listData.push({
name: '',
price: 0,
prepay: 0,
unpaid: 0
})
},
deleteData (index) {
this.listData.splice(index, 1)
}
}
})
})();