更新
This commit is contained in:
parent
8146b165f9
commit
e7effb0881
@ -5,6 +5,14 @@
|
|||||||
|
|
||||||
# CHANGE
|
# CHANGE
|
||||||
|
|
||||||
|
## 1.0.6
|
||||||
|
|
||||||
|
2023年06月26日
|
||||||
|
|
||||||
|
### 添加
|
||||||
|
|
||||||
|
- 物品功能标签
|
||||||
|
|
||||||
## 1.0.5
|
## 1.0.5
|
||||||
|
|
||||||
2023年06月19日
|
2023年06月19日
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wuhu-torn-helper",
|
"name": "wuhu-torn-helper",
|
||||||
"version": "1.0.5",
|
"version": "1.0.6",
|
||||||
"description": "芜湖助手",
|
"description": "芜湖助手",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release": "cross-env NODE_ENV=production rollup -c && node build.mjs",
|
"release": "cross-env NODE_ENV=production rollup -c && node build.mjs",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -13,6 +13,7 @@ import TravelItem, { TravelItemKey } from "./action/TravelItem";
|
|||||||
import QuickGymTrain, { QuickGymTrainKey } from "./action/QuickGymTrain";
|
import QuickGymTrain, { QuickGymTrainKey } from "./action/QuickGymTrain";
|
||||||
import QuickFlyBtnHandler, { QuickFlyBtnHandlerKey } from "./handler/QuickFlyBtnHandler";
|
import QuickFlyBtnHandler, { QuickFlyBtnHandlerKey } from "./handler/QuickFlyBtnHandler";
|
||||||
import ItemHelper, { ItemHelperKey } from "./utils/ItemHelper";
|
import ItemHelper, { ItemHelperKey } from "./utils/ItemHelper";
|
||||||
|
import MathUtils, { MathUtilsKey } from "./utils/MathUtils";
|
||||||
|
|
||||||
@ClassName("IconHelper")
|
@ClassName("IconHelper")
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -31,6 +32,7 @@ export default class IconHelper {
|
|||||||
private readonly quickGymTrain: QuickGymTrain,
|
private readonly quickGymTrain: QuickGymTrain,
|
||||||
private readonly quickFlyBtnHandler: QuickFlyBtnHandler,
|
private readonly quickFlyBtnHandler: QuickFlyBtnHandler,
|
||||||
private readonly itemHelper: ItemHelper,
|
private readonly itemHelper: ItemHelper,
|
||||||
|
private readonly mathUtils: MathUtils,
|
||||||
) {
|
) {
|
||||||
this._element = document.createElement('div');
|
this._element = document.createElement('div');
|
||||||
}
|
}
|
||||||
@ -47,6 +49,7 @@ export default class IconHelper {
|
|||||||
app.config.warnHandler = (err) => this.logger.warn('[VUE警告]', err);
|
app.config.warnHandler = (err) => this.logger.warn('[VUE警告]', err);
|
||||||
app.provide(LoggerKey, this.logger);
|
app.provide(LoggerKey, this.logger);
|
||||||
app.provide(CommonUtilsKey, this.commonUtils);
|
app.provide(CommonUtilsKey, this.commonUtils);
|
||||||
|
app.provide(MathUtilsKey, this.mathUtils);
|
||||||
app.provide(TravelItemKey, this.travelItem);
|
app.provide(TravelItemKey, this.travelItem);
|
||||||
app.provide(PopupWrapperKey, this.popupWrapper);
|
app.provide(PopupWrapperKey, this.popupWrapper);
|
||||||
app.provide(LocalConfigWrapperKey, this.localConfigWrapper);
|
app.provide(LocalConfigWrapperKey, this.localConfigWrapper);
|
||||||
|
|||||||
@ -374,8 +374,7 @@ export default class TranslateNew extends Provider implements ResponseInject {
|
|||||||
name.innerText = `${ name.innerText } ${ nameZh }`;
|
name.innerText = `${ name.innerText } ${ nameZh }`;
|
||||||
}
|
}
|
||||||
// 操作按钮
|
// 操作按钮
|
||||||
let actions = elem.querySelectorAll('.icon-h');
|
elem.querySelectorAll('.icon-h').forEach(action => {
|
||||||
actions.forEach(action => {
|
|
||||||
let attrTitle = action.getAttribute('title');
|
let attrTitle = action.getAttribute('title');
|
||||||
// TODO
|
// TODO
|
||||||
let zh = itemPageDict[attrTitle];
|
let zh = itemPageDict[attrTitle];
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import ClassName from "../../container/ClassName";
|
import ClassName from "../../container/ClassName";
|
||||||
import { Injectable } from "../../container/Injectable";
|
import { Injectable } from "../../container/Injectable";
|
||||||
|
import { InjectionKey } from "vue";
|
||||||
|
|
||||||
@ClassName('MathUtils')
|
@ClassName('MathUtils')
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -14,3 +15,5 @@ export default class MathUtils {
|
|||||||
return Math.floor(Math.random() * (max - min)) + min;
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MathUtilsKey = Symbol('MathUtilsKey') as InjectionKey<MathUtils>
|
||||||
|
|||||||
5
src/ts/func/utils/Sleep.ts
Normal file
5
src/ts/func/utils/Sleep.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const Sleep = (ms: number = 0) => {
|
||||||
|
return new Promise(resolve => window.setTimeout(resolve, ms))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Sleep
|
||||||
21
src/ts/func/utils/equipItem.ts
Normal file
21
src/ts/func/utils/equipItem.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const equipItem = (itemId: string, armoryId: string, type: number) => {
|
||||||
|
return fetch(window.addRFC("https://www.torn.com/item.php"), {
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/item.php",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": `step=actionForm&item_id=${ itemId }&armour-from-set=&type=${ type }&action=equip&item=${ itemId }&id=${ armoryId }&confirm=1`,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default equipItem
|
||||||
@ -15,9 +15,9 @@
|
|||||||
</el-badge>
|
</el-badge>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
<el-dialog v-model="drawer" :destroy-on-close="false" :fullscreen="isMobilePhone" :lock-scroll="true"
|
<el-dialog v-model="drawer" :fullscreen="isMobilePhone" :lock-scroll="true"
|
||||||
:title="editableTabsValue" width="65%">
|
width="65%">
|
||||||
<el-tabs v-model="editableTabsValue" closable type="card" @tab-remove="removeTab">
|
<el-tabs v-model="editableTabsValue" closable style="margin-top: -1em" type="border-card" @tab-remove="removeTab">
|
||||||
<el-tab-pane v-for="item in editableTabs" :key="item.name" :label="item.title" :name="item.name">
|
<el-tab-pane v-for="item in editableTabs" :key="item.name" :label="item.title" :name="item.name">
|
||||||
<component :is="item.content"/>
|
<component :is="item.content"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -82,20 +82,20 @@
|
|||||||
<el-menu-item @click="quickGymTrain.doTrain(BATTLE_STAT.DEX)">闪避
|
<el-menu-item @click="quickGymTrain.doTrain(BATTLE_STAT.DEX)">闪避
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
<el-menu-item v-for="(item, i) in menuItemList" :index="(3 + i).toString()" @click="menuClick(item)">
|
<el-sub-menu index="3">
|
||||||
<el-icon>{{ item.title.slice(0, 2) }}</el-icon>
|
|
||||||
<span>{{ item.title.slice(2, item.title.length) }}</span>
|
|
||||||
</el-menu-item>
|
|
||||||
<el-sub-menu :index="2 + menuItemList.length + 1 + ''">
|
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon>🪓</el-icon>
|
<el-icon>🪓</el-icon>
|
||||||
<span>老功能</span>
|
<span>老功能</span>
|
||||||
</template>
|
</template>
|
||||||
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 1" @click="_adHelper">📜️ 传单助手</el-menu-item>
|
<el-menu-item index="3-1" @click="_adHelper">📜️ 传单助手</el-menu-item>
|
||||||
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 2" @click="_safeKeeper">🛡️ 守望者</el-menu-item>
|
<el-menu-item index="3-2" @click="_safeKeeper">🛡️ 守望者</el-menu-item>
|
||||||
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 3" @click="MUZHUANG">🌲 寻找木桩</el-menu-item>
|
<el-menu-item index="3-3" @click="MUZHUANG">🌲 寻找木桩</el-menu-item>
|
||||||
<el-menu-item :index="(2 + menuItemList.length + 1) + '-' + 4" @click="_setting">⚙️ 助手设置</el-menu-item>
|
<el-menu-item index="3-4" @click="_setting">⚙️ 助手设置</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
<el-menu-item v-for="(item, i) in menuItemList" :index="(4 + i).toString()" @click="menuClick(item)">
|
||||||
|
<el-icon>{{ item.title.slice(0, 2) }}</el-icon>
|
||||||
|
<span>{{ item.title.slice(2, item.title.length) }}</span>
|
||||||
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</el-config-provider>
|
</el-config-provider>
|
||||||
@ -127,6 +127,7 @@ import PTMarketView from "./PTMarketView.vue";
|
|||||||
import QuickCrime from "./QuickCrime.vue";
|
import QuickCrime from "./QuickCrime.vue";
|
||||||
import UpdateDate from "./UpdateScript.vue";
|
import UpdateDate from "./UpdateScript.vue";
|
||||||
import VirusProgramming from "./VirusProgramming.vue";
|
import VirusProgramming from "./VirusProgramming.vue";
|
||||||
|
import InventoryView from "./InventoryView.vue";
|
||||||
|
|
||||||
const logger = inject(LoggerKey);
|
const logger = inject(LoggerKey);
|
||||||
const quickGymTrain = inject(QuickGymTrainKey);
|
const quickGymTrain = inject(QuickGymTrainKey);
|
||||||
@ -208,6 +209,10 @@ const menuItemList: MenuItem[] = [
|
|||||||
title: '🫵 关闭店铺(双击开启)',
|
title: '🫵 关闭店铺(双击开启)',
|
||||||
handler: () => bazaarControl.method(),
|
handler: () => bazaarControl.method(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '📦 物品',
|
||||||
|
template: InventoryView,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '🚀 更新历史',
|
title: '🚀 更新历史',
|
||||||
handler: () => {
|
handler: () => {
|
||||||
|
|||||||
300
src/vue/InventoryView.vue
Normal file
300
src/vue/InventoryView.vue
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
import { Check, Delete, Promotion } from "@element-plus/icons-vue"
|
||||||
|
import { ElMessage } from "element-plus"
|
||||||
|
import { inject, onMounted, ref } from "vue"
|
||||||
|
import { LoggerKey } from "../ts/class/Logger"
|
||||||
|
import { itemNameDict } from "../ts/dictionary/translation"
|
||||||
|
import Sleep from "../ts/func/utils/Sleep"
|
||||||
|
import equipItem from "../ts/func/utils/equipItem"
|
||||||
|
import useItem from "../ts/func/utils/useItem"
|
||||||
|
|
||||||
|
const logger = inject(LoggerKey)
|
||||||
|
|
||||||
|
type Item = {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
nameZh: string
|
||||||
|
amount: number
|
||||||
|
isEquipped: boolean
|
||||||
|
details: ItemDetails
|
||||||
|
isDetailsLoading: boolean
|
||||||
|
armoryId: number
|
||||||
|
damage: number
|
||||||
|
accuracy: number
|
||||||
|
defence: number
|
||||||
|
type: number
|
||||||
|
}
|
||||||
|
|
||||||
|
type ItemDetails = {
|
||||||
|
itemType: string
|
||||||
|
itemCost: string
|
||||||
|
itemValue: string
|
||||||
|
itemRareTitle: string
|
||||||
|
extras: { icon: string; cl: string; type: string; title: string; value: string }[]
|
||||||
|
itemInfo: string
|
||||||
|
itemSell: string
|
||||||
|
itemID: number
|
||||||
|
itemName: string
|
||||||
|
itemInfoContent: string
|
||||||
|
itemCirculation: string
|
||||||
|
armoryID: boolean
|
||||||
|
itemRareIcon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemList = ref<Item[]>([])
|
||||||
|
const disabledInfiniteLoading = ref(false)
|
||||||
|
const categorySelected = ref('Drug')
|
||||||
|
const categories = [
|
||||||
|
{ label: '📦 ', value: '' },
|
||||||
|
{ label: '主', value: 'Primary' },
|
||||||
|
{ label: '副', value: 'Secondary' },
|
||||||
|
{ label: '🔪 ', value: 'Melee' },
|
||||||
|
{ label: '💣 ', value: 'Temporary' },
|
||||||
|
{ label: '🛡 ', value: 'Defensive' },
|
||||||
|
{ label: '👔 ', value: 'Clothing' },
|
||||||
|
{ label: '🏥 ', value: 'Medical' },
|
||||||
|
{ label: '💊 ', value: 'Drug' },
|
||||||
|
{ label: '🥤 ', value: 'Energy+Drink' },
|
||||||
|
{ label: '🍺 ', value: 'Alcohol' },
|
||||||
|
{ label: '🍬 ', value: 'Candy' },
|
||||||
|
{ label: '⬆️ ', value: 'Booster' },
|
||||||
|
{ label: '🪄 ', value: 'Enhancer' },
|
||||||
|
{ label: '📦 ', value: 'Supply+Pack' },
|
||||||
|
{ label: '🔌 ', value: 'Electronic' },
|
||||||
|
{ label: '💎 ', value: 'Jewelry' },
|
||||||
|
{ label: '🌹 ', value: 'Flower' },
|
||||||
|
{ label: '🧸 ', value: 'Plushie' },
|
||||||
|
{ label: '🚗 ', value: 'Car' },
|
||||||
|
{ label: '🦠 ', value: 'Virus' },
|
||||||
|
{ label: '📖 ', value: 'Book' },
|
||||||
|
{ label: '🌟', value: 'Special' },
|
||||||
|
{ label: '🛍 ', value: 'Other' },
|
||||||
|
// TODO
|
||||||
|
{ label: '🗼 ', value: '' },
|
||||||
|
{ label: '🏆 ', value: '' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const fetchList = async (start: number = 0): Promise<string> => {
|
||||||
|
let json: { html?: string, error?: string, text?: string }
|
||||||
|
try {
|
||||||
|
json = await (await fetch(window.addRFC("https://www.torn.com/item.php"), {
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/item.php",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": categorySelected.value ? `step=getCategoryList&itemName=${ categorySelected.value }&start=${ start }&test=true&prevtotal=0` : `step=getNotAllItemsListWithoutGroups&start=${ start }&queue=All`,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
})).json()
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(e.stack)
|
||||||
|
ElMessage.error('物品获取失败 ' + e.message)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
if (json.html) return json.html
|
||||||
|
else {
|
||||||
|
const err = json.error || json.text || '获取物品列表时没有内容'
|
||||||
|
logger.error(err)
|
||||||
|
ElMessage.error('获取物品失败 ' + err)
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchItemDetails = async (id: number): Promise<ItemDetails> => {
|
||||||
|
let ret: ItemDetails = null
|
||||||
|
try {
|
||||||
|
ret = await (await fetch(window.addRFC("https://www.torn.com/page.php?sid=inventory"), {
|
||||||
|
"headers": {
|
||||||
|
"accept": "*/*",
|
||||||
|
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
"sec-ch-ua-mobile": "?0",
|
||||||
|
"sec-fetch-dest": "empty",
|
||||||
|
"sec-fetch-mode": "cors",
|
||||||
|
"sec-fetch-site": "same-origin",
|
||||||
|
"x-requested-with": "XMLHttpRequest"
|
||||||
|
},
|
||||||
|
"referrer": "https://www.torn.com/item.php",
|
||||||
|
"referrerPolicy": "strict-origin-when-cross-origin",
|
||||||
|
"body": "itemID=" + id,
|
||||||
|
"method": "POST",
|
||||||
|
"mode": "cors",
|
||||||
|
"credentials": "include"
|
||||||
|
})).json()
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(e.stack)
|
||||||
|
ElMessage.error('物品详情获取失败 ' + e.message)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseListHtml = (html: string) => {
|
||||||
|
const ret: Item[] = []
|
||||||
|
let tmp = document.createElement('div')
|
||||||
|
tmp.innerHTML = html
|
||||||
|
tmp.childNodes.forEach(li => {
|
||||||
|
if (li.nodeType === 1) {
|
||||||
|
const item: Item = {
|
||||||
|
type: 0,
|
||||||
|
defence: 0,
|
||||||
|
accuracy: 0, damage: 0,
|
||||||
|
armoryId: 0,
|
||||||
|
details: undefined,
|
||||||
|
isDetailsLoading: false,
|
||||||
|
amount: -1, isEquipped: false, id: -1, name: "", nameZh: ""
|
||||||
|
}
|
||||||
|
let elem = li as HTMLElement
|
||||||
|
// 物品名
|
||||||
|
let name: HTMLElement = elem.querySelector('.name-wrap .name')
|
||||||
|
item.name = name.innerText.trim()
|
||||||
|
item.nameZh = itemNameDict[item.name]
|
||||||
|
// 堆叠数量
|
||||||
|
item.amount = Number(elem.getAttribute('data-qty'))
|
||||||
|
// id
|
||||||
|
item.id = Number(elem.getAttribute('data-item'))
|
||||||
|
// 装备
|
||||||
|
item.isEquipped = elem.getAttribute('data-equipped').trim() === 'true'
|
||||||
|
// 装备id
|
||||||
|
item.armoryId = Number(elem.getAttribute('data-armoryid'))
|
||||||
|
// 武器攻击
|
||||||
|
item.damage = Number(elem.querySelector('.bonus-attachment-item-damage-bonus')?.nextElementSibling.innerText?.trim())
|
||||||
|
// 武器命中
|
||||||
|
item.accuracy = Number(elem.querySelector('.bonus-attachment-item-accuracy-bonus')?.nextElementSibling.innerText?.trim())
|
||||||
|
// 武器命中
|
||||||
|
item.defence = Number(elem.querySelector('.bonus-attachment-item-defence-bonus')?.nextElementSibling.innerText?.trim())
|
||||||
|
// 装备类型
|
||||||
|
item.type = Number(elem.querySelector('ul.actions-wrap li[data-type]')?.getAttribute('data-type').trim())
|
||||||
|
|
||||||
|
ret.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
let mouseOverItemId: number
|
||||||
|
const itemHover = async (item: Item) => {
|
||||||
|
const thisId = item.id
|
||||||
|
mouseOverItemId = item.id
|
||||||
|
await Sleep(300)
|
||||||
|
if (thisId === mouseOverItemId && !item.isDetailsLoading && !item.details) {
|
||||||
|
item.isDetailsLoading = true
|
||||||
|
try {
|
||||||
|
item.details = await fetchItemDetails(item.id)
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
item.isDetailsLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadMore = async () => {
|
||||||
|
if (disabledInfiniteLoading.value) return
|
||||||
|
disabledInfiniteLoading.value = true
|
||||||
|
let newItems: Item[]
|
||||||
|
try {
|
||||||
|
newItems = parseListHtml(await fetchList(itemList.value.length))
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message !== '获取物品列表时没有内容') {
|
||||||
|
ElMessage.error(e.message)
|
||||||
|
logger.error(e.stack)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newItems.forEach(item => itemList.value.push(item))
|
||||||
|
window.setTimeout(() => disabledInfiniteLoading.value = newItems.length < 1, 500)
|
||||||
|
}
|
||||||
|
const loadCategory = async (type: string) => {
|
||||||
|
disabledInfiniteLoading.value = true
|
||||||
|
categorySelected.value = type
|
||||||
|
itemList.value = []
|
||||||
|
itemList.value = parseListHtml(await fetchList(itemList.value.length))
|
||||||
|
window.setTimeout(() => disabledInfiniteLoading.value = false, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _equipItem = async (item: Item) => {
|
||||||
|
await equipItem(String(item.id), String(item.armoryId), item.type)
|
||||||
|
item.isEquipped = !item.isEquipped
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
itemList.value = parseListHtml(await fetchList())
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-button-group>
|
||||||
|
<el-button v-for="item in categories" :disabled="item.value === categorySelected" @click="loadCategory(item.value)">
|
||||||
|
{{ item.label }}
|
||||||
|
</el-button>
|
||||||
|
</el-button-group>
|
||||||
|
<el-space size="default" wrap>
|
||||||
|
<div v-for="item in itemList" v-infinite-scroll="loadMore" :infinite-scroll-delay="500"
|
||||||
|
:infinite-scroll-disabled="disabledInfiniteLoading">
|
||||||
|
<el-badge :hidden="item.amount < 2" :value="item.amount">
|
||||||
|
<el-popover :show-after="300" :width="240" trigger="hover">
|
||||||
|
<template #reference>
|
||||||
|
<el-card :body-style="{ padding: '0px' }" :style="item.isEquipped ? { borderColor: '#32CD32' } : null"
|
||||||
|
shadow="hover">
|
||||||
|
<el-image :alt="item.id.toString()" :mouseover="itemHover(item)"
|
||||||
|
:src="`/images/items/${item.id}/medium.png`" style="width: 60px;height: 30px"/>
|
||||||
|
<el-row v-if="item.damage > 0 && item.accuracy > 0">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-tag>{{ item.damage }}</el-tag>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-tag>{{ item.accuracy }}</el-tag>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row v-if="item.defence > 0">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-tag>{{ item.defence }}</el-tag>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<el-row>
|
||||||
|
<el-text v-if="item.nameZh" size="large">{{ item.nameZh }}</el-text>
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-text>{{ item.name }}<span v-if="item.armoryId"> - {{ item.armoryId }}</span></el-text>
|
||||||
|
</el-row>
|
||||||
|
<el-row v-if="item.damage">
|
||||||
|
<el-text>攻击: {{ item.damage }}</el-text>
|
||||||
|
</el-row>
|
||||||
|
<el-row v-if="item.accuracy">
|
||||||
|
<el-text>命中: {{ item.accuracy }}</el-text>
|
||||||
|
</el-row>
|
||||||
|
<el-row v-if="item.defence">
|
||||||
|
<el-text>防御: {{ item.defence }}</el-text>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="4">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-button :icon="Check" @click="item.armoryId ? _equipItem(item) : useItem(item.id.toString())"/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-button :icon="Delete" disabled/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-button :icon="Promotion" disabled/>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div v-if="item.details || item.isDetailsLoading" v-loading="item.isDetailsLoading"
|
||||||
|
v-html="item.details?.itemInfoContent || ''"></div>
|
||||||
|
<el-row v-if="item.details">
|
||||||
|
<el-text>估值: {{ item.details.itemValue }}</el-text>
|
||||||
|
</el-row>
|
||||||
|
</el-popover>
|
||||||
|
</el-badge>
|
||||||
|
</div>
|
||||||
|
</el-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@ -65,9 +65,12 @@ import { LoggerKey } from "../ts/class/Logger";
|
|||||||
import { ItemHelperKey } from "../ts/class/utils/ItemHelper";
|
import { ItemHelperKey } from "../ts/class/utils/ItemHelper";
|
||||||
import { itemNameDict } from "../ts/dictionary/translation";
|
import { itemNameDict } from "../ts/dictionary/translation";
|
||||||
import toThousands from "../ts/func/utils/toThousands";
|
import toThousands from "../ts/func/utils/toThousands";
|
||||||
|
import Sleep from "../ts/func/utils/Sleep";
|
||||||
|
import { MathUtilsKey } from "../ts/class/utils/MathUtils";
|
||||||
|
|
||||||
const logger = inject(LoggerKey);
|
const logger = inject(LoggerKey);
|
||||||
const itemHelper = inject(ItemHelperKey);
|
const itemHelper = inject(ItemHelperKey);
|
||||||
|
const mathUtils = inject(MathUtilsKey)
|
||||||
|
|
||||||
let itemName2IdMap: { [p: string]: number } = null;
|
let itemName2IdMap: { [p: string]: number } = null;
|
||||||
const itemName = ref<string>('');
|
const itemName = ref<string>('');
|
||||||
@ -205,7 +208,7 @@ const buy = async (itemInfo: ItemInfo) => {
|
|||||||
throw new Error('bazaarId为空')
|
throw new Error('bazaarId为空')
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
await Sleep(mathUtils.getRandomInt(100, 110))
|
||||||
// 从baz买货
|
// 从baz买货
|
||||||
let buyResponse = await (await fetch("https://www.torn.com/bazaar.php?sid=bazaarData&step=buyItem", {
|
let buyResponse = await (await fetch("https://www.torn.com/bazaar.php?sid=bazaarData&step=buyItem", {
|
||||||
"headers": {
|
"headers": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user