Greasy Fork

Hpoi Price Statistics

统计预定想买的预计价格和相关信息

// ==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/[email protected]
// @require      https://unpkg.com/element-ui/lib/index.js
// @connect      *
// @resource css https://unpkg.com/element-ui/lib/theme-chalk/index.css
// ==/UserScript==

(async function () {
  GM_addStyle(GM_getResourceText("css"));
  const vueApp = ` <div id="app">
  <el-button @click="handleShow()" type="primary">价格统计</el-button>
  <div>
    <el-dialog title="提示" :visible="priceDialogVisible" :show-close="false" :close-on-click-modal="false" width="80%">


      <el-radio-group v-model="mode" :disabled="true" change="changeMode">
        <el-radio-button label="all" v-if="mode=='all'">全部</el-radio-button>
        <el-radio-button label="pre" v-if="mode=='pre'">预定</el-radio-button>
      </el-radio-group>
      <!-- 数据部分 s -->
      <div style="margin-top:20px;" v-if="(mode=='all'||mode=='pre')">
        <el-row :gutter=16>
          <el-col :span="4">
            <el-button type="primary" @click="syncData">{{syncDataTip}}</el-button>
          </el-col>
          <el-col :span="4">
            <el-button type="danger" @click="clearData">清空数据</el-button>
          </el-col>
          <el-col :span="4">
            <el-button type="success" @click="addData">添加数据</el-button>
          </el-col>
        </el-row>
        <el-row style="text-align: center;margin-top:20px">
          <el-col :span="8">名称</el-col>
          <el-col :span="3" style="margin-left:20px">价格</el-col>
          <el-col :span="3" style="margin-left:20px">预付</el-col>
          <el-col :span="3" style="margin-left:20px">待付</el-col>
          <el-col :span="3" style="margin-left:20px">操作</el-col>
        </el-row>
        <el-row v-for="(item,index) in listData" style="margin-top: 20px;" :key="index">
          <el-col :span="8">
            <el-input v-model="item.name"></el-input>
          </el-col>
          <el-col :span="3" style="margin-left:20px">
            <el-input v-model="item.price"></el-input>
          </el-col>
          <el-col :span="3" style="margin-left:20px">
            <el-input v-model="item.prepay"></el-input>
          </el-col>
          <el-col :span="3"
            style="margin-left:20px;display:flex;align-items:center;justify-content:center;height:40px;">
            <div>
              <span>{{unpaidResult[index]&&unpaidResult[index].unpaid}}</span>
            </div>
          </el-col>
          <el-col :span="3" style="margin-left:20px;text-align:center">
            <el-button @click="deleteData(index)">删除</el-button>
          </el-col>
        </el-row>
        <el-row style="margin-top: 20px;" type="flex" justify="end">
          <el-col :span="4"><span>总价: {{totalPrice}}</span></el-col>
        </el-row>
        <el-row style="margin-top: 20px;" type="flex" justify="end">
          <el-col :span="4">
            <span>总待付: {{totalUnpaid}}</span>
          </el-col>
        </el-row>
      </div>
      <!-- 数据部分 e -->


      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </span>
    </el-dialog>
  </div>
</div>`
  $('.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)
      }
    }
  })

})();