chatapp-h5/h5/recharge/index.html
2026-06-01 17:36:04 +08:00

225 lines
9.3 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<meta name="format-detection" content="telephone=no" />
<title>Recharge Center</title>
<link rel="stylesheet" href="./style.css?v=20260601-0400" />
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
</head>
<body>
<div id="app" v-cloak>
<div class="page" :dir="isRtl ? 'rtl' : 'ltr'">
<header class="topbar">
<button class="icon-button" type="button" :aria-label="text.back" @click="closePage">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M15 5 8 12l7 7" />
</svg>
</button>
<h1>{{ text.title }}</h1>
<div class="language-switcher" @click.stop>
<button
class="language-button"
type="button"
:aria-label="text.languageButtonAria"
:aria-expanded="languageMenuOpen ? 'true' : 'false'"
@click="toggleLanguageMenu"
>
{{ languageLabel }}
</button>
<div class="language-menu" v-show="languageMenuOpen">
<button
v-for="language in languages"
:key="language.type"
type="button"
:class="{ 'is-active': language.type === lang }"
:aria-pressed="language.type === lang ? 'true' : 'false'"
@click="applyLanguage(language.type)"
>
{{ language.label }}
</button>
</div>
</div>
</header>
<main class="content" @click="closeLanguageMenu">
<section v-if="paymentReturn" class="notice" :class="paymentReturn.type">
<strong>{{ paymentReturn.title }}</strong>
<span>{{ paymentReturn.message }}</span>
</section>
<section v-if="!authenticated && !isMock" class="notice warning">
<strong>{{ text.authMissingTitle }}</strong>
<span>{{ text.authMissingDesc }}</span>
</section>
<section v-if="selfMode && !targetProfile" class="panel">
<div class="empty-state">{{ searching ? text.loadingAccount : (statusText || text.loadingAccount) }}</div>
</section>
<section v-if="!selfMode" class="panel search-panel">
<div class="section-head">
<h3>{{ text.searchTitle }}</h3>
</div>
<form class="search-form" @submit.prevent="searchAccount">
<input
v-model.trim="account"
type="text"
inputmode="text"
autocomplete="off"
:placeholder="text.accountPlaceholder"
/>
<button type="submit" :disabled="searching || !account">
{{ searching ? text.searching : text.search }}
</button>
</form>
<p class="guide-text">{{ text.searchGuide }}</p>
<p v-if="statusText" class="status" :class="statusType">{{ statusText }}</p>
</section>
<section v-if="targetProfile" class="panel account-panel">
<div class="avatar-wrap">
<img v-if="avatarUrl(targetProfile)" :src="avatarUrl(targetProfile)" alt="" @error="hideBrokenImage" />
<span v-else>{{ fallbackInitial(targetProfile) }}</span>
</div>
<div class="account-copy">
<div class="role-row">
<span class="role-pill" :class="{ dealer: isDealer }">{{ roleLabel }}</span>
<span v-if="isDealer" class="role-pill fee">{{ text.lowFee }}</span>
</div>
<h3>{{ profileName(targetProfile) }}</h3>
<p>{{ text.userId }} {{ profileAccount(targetProfile) }}</p>
<p v-if="selectedCountry">{{ text.country }} {{ countryName(selectedCountry) }}</p>
</div>
<button v-if="!selfMode" class="mini-button" type="button" @click="resetTarget">{{ text.change }}</button>
</section>
<section v-if="targetProfile" class="panel methods-panel">
<div class="section-head">
<h3>{{ text.packageTitle }}</h3>
</div>
<div v-if="loadingOptions" class="empty-state">{{ text.loading }}</div>
<template v-else>
<div v-if="commodity.length" class="package-grid">
<button
v-for="goods in commodity"
:key="goods.id"
class="package-button"
:class="{ active: selectedGoodsId === String(goods.id) }"
type="button"
:disabled="ordering"
@click="selectGoods(goods)"
>
<span class="coin-mark"></span>
<strong>{{ goods.content || goods.name || '-' }}</strong>
<span>{{ formatPrice(goods) }}</span>
<small v-if="goods.awardContent">{{ goods.awardContent }}</small>
</button>
</div>
<div v-else class="empty-state">{{ text.noPackage }}</div>
<div class="section-head payment-head">
<h3>{{ text.methodTitle }}</h3>
</div>
<div v-if="visibleChannels.length" class="channel-list">
<button
v-for="channel in visibleChannels"
:key="channelKey(channel)"
class="channel-button"
:class="{ usdt: isUsdtTrc20Channel(channel), active: selectedChannelKey === channelKey(channel) }"
type="button"
:disabled="ordering"
@click="selectChannel(channel)"
>
<div class="method-icon">
<img v-if="channelIcon(channel)" :src="channelIcon(channel)" alt="" />
<span v-else>{{ channelName(channel).slice(0, 1) }}</span>
</div>
<div class="channel-copy">
<h4>{{ channelName(channel) }}</h4>
</div>
<span v-if="isUsdtTrc20Channel(channel)" class="method-badge">USDT TRC20</span>
</button>
</div>
<div v-else class="empty-state">{{ text.noOptions }}</div>
<button
class="create-order-button"
type="button"
:disabled="ordering || !selectedChannel || !selectedGoods"
@click="createOrder"
>
{{ ordering ? text.creatingOrder : text.createOrder }}
</button>
</template>
</section>
</main>
<div v-if="orderResult" class="sheet-mask" @click="orderResult = null">
<section class="result-sheet" @click.stop>
<button class="sheet-close" type="button" @click="orderResult = null">&times;</button>
<div class="result-icon" :class="orderResult.type"></div>
<h3>{{ orderResult.title }}</h3>
<p>{{ orderResult.message }}</p>
<dl v-if="orderResult.orderNo">
<dt>{{ text.orderNo }}</dt>
<dd>{{ orderResult.orderNo }}</dd>
</dl>
<button class="primary-wide" type="button" @click="orderResult = null">{{ text.done }}</button>
</section>
</div>
<div v-if="usdtModalOpen" class="sheet-mask usdt-mask">
<section class="usdt-dialog" @click.stop>
<button class="sheet-close" type="button" :aria-label="text.done" @click="closeUsdtModal">&times;</button>
<h3>{{ text.usdtOrderTitle }}</h3>
<div class="field-block">
<label>{{ text.trc20Address }}</label>
<div class="copy-row">
<button class="address-value" type="button" @click="copyUsdtAddress">{{ usdtAddressText }}</button>
<button class="copy-button" type="button" @click="copyUsdtAddress">{{ text.copy }}</button>
</div>
</div>
<div class="field-block">
<label>{{ text.amount }}</label>
<div class="readonly-amount">{{ formatPrice(selectedGoods) }}</div>
</div>
<form class="usdt-form" @submit.prevent="queryUsdtPaymentStatus">
<div class="field-block">
<label for="usdtOrderInput">{{ text.orderInputLabel }}</label>
<input
id="usdtOrderInput"
v-model.trim="usdtOrderInput"
class="usdt-input"
type="text"
inputmode="text"
autocomplete="off"
:placeholder="text.orderInputPlaceholder"
/>
</div>
<p v-if="usdtOrderError" class="status error">{{ usdtOrderError }}</p>
<button class="primary-wide" type="submit" :disabled="queryingPayment || !usdtOrderInput">
{{ queryingPayment ? text.queryingStatus : text.queryPaymentStatus }}
</button>
</form>
</section>
</div>
<div v-if="toastText" class="toast">{{ toastText }}</div>
</div>
</div>
<script src="./script.js?v=20260601-0400"></script>
</body>
</html>