每周更新
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
<div class="desc">{{ shop.description || '这家店还没有描述~' }}</div>
|
<div class="desc">{{ shop.description || '这家店还没有描述~' }}</div>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<span>手续费率:{{ formatFeeRate(shop.feeRate) }}</span>
|
<span>手续费率:{{ formatFeeRate(shop.feeRate) }}</span>
|
||||||
|
<span>网络手续费:{{ shopNetworkFeeText }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<el-button size="small" type="primary" @click="handleOpenEdit">修改店铺</el-button>
|
<el-button size="small" type="primary" @click="handleOpenEdit">修改店铺</el-button>
|
||||||
@@ -218,9 +219,27 @@
|
|||||||
<label class="label">手续费比例</label>
|
<label class="label">手续费比例</label>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="editForm.feeRate"
|
v-model="editForm.feeRate"
|
||||||
placeholder="比例区间 0.01 - 0.1 之间,最多6位小数"
|
class="fee-rate-input"
|
||||||
|
placeholder="1 - 10"
|
||||||
@input="handleEditFeeRateInput"
|
@input="handleEditFeeRateInput"
|
||||||
/>
|
>
|
||||||
|
<template slot="append">%</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label class="label">专用网络</label>
|
||||||
|
<div class="edit-network">
|
||||||
|
<div class="edit-network-line">
|
||||||
|
<span class="edit-network-label">是否开启</span>
|
||||||
|
<el-switch v-model="editForm.isOpen" />
|
||||||
|
<span class="edit-network-fee">
|
||||||
|
网络手续费
|
||||||
|
<span class="edit-fee-value" :class="{ on: editForm.isOpen }">{{ editNetworkFeeText }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="edit-network-hint">专用网络会增加2%的手续费,建议无法直连矿池的用户开启</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="label">谷歌验证码</label>
|
<label class="label">谷歌验证码</label>
|
||||||
@@ -286,11 +305,13 @@ export default {
|
|||||||
image: '',
|
image: '',
|
||||||
description: '',
|
description: '',
|
||||||
feeRate: '',
|
feeRate: '',
|
||||||
|
networkFee: 0,
|
||||||
|
isOpen: false,
|
||||||
del: true,
|
del: true,
|
||||||
state: 0
|
state: 0
|
||||||
},
|
},
|
||||||
visibleEdit: false,
|
visibleEdit: false,
|
||||||
editForm: { id: '', name: '', image: '', description: '', feeRate: '', gCode: '' },
|
editForm: { id: '', name: '', image: '', description: '', feeRate: '', gCode: '', isOpen: false, networkFee: 0 },
|
||||||
// 店铺配置列表
|
// 店铺配置列表
|
||||||
shopConfigs: [],
|
shopConfigs: [],
|
||||||
visibleConfigEdit: false,
|
visibleConfigEdit: false,
|
||||||
@@ -335,6 +356,17 @@ export default {
|
|||||||
if (this.shop.state === 2) return 'info'
|
if (this.shop.state === 2) return 'info'
|
||||||
return 'info'
|
return 'info'
|
||||||
},
|
},
|
||||||
|
shopNetworkFeeText() {
|
||||||
|
const fee = Number(this.shop.networkFee)
|
||||||
|
const feeValid = Number.isFinite(fee) && fee > 0
|
||||||
|
const isOpen = this.normalizeIsOpen(this.shop.isOpen)
|
||||||
|
if (!isOpen) return '0'
|
||||||
|
const rate = feeValid ? fee : 0
|
||||||
|
if (!rate) return '0'
|
||||||
|
const percent = rate * 100
|
||||||
|
const fixed = percent.toFixed(6)
|
||||||
|
return `${fixed.replace(/\.?0+$/, '')}%`
|
||||||
|
},
|
||||||
hasShop() {
|
hasShop() {
|
||||||
return !!(this.shop && Number(this.shop.id) > 0)
|
return !!(this.shop && Number(this.shop.id) > 0)
|
||||||
},
|
},
|
||||||
@@ -352,6 +384,9 @@ export default {
|
|||||||
const map = new Map((this.editCoinOptions || []).map(o => [String(o.value), String(o.label).toUpperCase()]))
|
const map = new Map((this.editCoinOptions || []).map(o => [String(o.value), String(o.label).toUpperCase()]))
|
||||||
return (this.configForm.payCoins || []).map(v => map.get(String(v)) || String(v).toUpperCase())
|
return (this.configForm.payCoins || []).map(v => map.get(String(v)) || String(v).toUpperCase())
|
||||||
},
|
},
|
||||||
|
editNetworkFeeText() {
|
||||||
|
return this.editForm.isOpen ? '2%' : '0'
|
||||||
|
},
|
||||||
/* 提现弹窗标题:如 USDT提现 */
|
/* 提现弹窗标题:如 USDT提现 */
|
||||||
withdrawDialogTitle() {
|
withdrawDialogTitle() {
|
||||||
const sym = String((this.currentWithdrawRow && this.currentWithdrawRow.payCoin) || '').toUpperCase() || ''
|
const sym = String((this.currentWithdrawRow && this.currentWithdrawRow.payCoin) || '').toUpperCase() || ''
|
||||||
@@ -379,6 +414,34 @@ export default {
|
|||||||
this.fetchMyShop()
|
this.fetchMyShop()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* 专用网络状态解析(兼容 boolean/number/string)
|
||||||
|
*/
|
||||||
|
normalizeIsOpen(value) {
|
||||||
|
if (value === true || value === 1) return true
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const v = value.trim().toLowerCase()
|
||||||
|
return v === 'true' || v === '1'
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 统一解析店铺数据结构(兼容 data/data.list/array/string)
|
||||||
|
*/
|
||||||
|
normalizeShopData(raw) {
|
||||||
|
let data = raw && raw.data != null ? raw.data : raw
|
||||||
|
if (Array.isArray(data)) return data[0] || {}
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(data)
|
||||||
|
if (Array.isArray(parsed)) return parsed[0] || {}
|
||||||
|
return parsed || {}
|
||||||
|
} catch (e) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data || {}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 修改店铺:谷歌验证码输入(仅数字,最多6位)
|
* 修改店铺:谷歌验证码输入(仅数字,最多6位)
|
||||||
*/
|
*/
|
||||||
@@ -669,8 +732,9 @@ export default {
|
|||||||
if (value === null || value === undefined || value === '') return '-'
|
if (value === null || value === undefined || value === '') return '-'
|
||||||
const num = Number(value)
|
const num = Number(value)
|
||||||
if (!Number.isFinite(num)) return '-'
|
if (!Number.isFinite(num)) return '-'
|
||||||
const fixed = num.toFixed(6)
|
const percent = num * 100
|
||||||
return fixed.replace(/\.?0+$/, '')
|
const fixed = percent.toFixed(6)
|
||||||
|
return `${fixed.replace(/\.?0+$/, '')}%`
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 修改弹窗 - 手续费输入:允许一个小数点,最多6位小数;允许尾随点
|
* 修改弹窗 - 手续费输入:允许一个小数点,最多6位小数;允许尾随点
|
||||||
@@ -709,6 +773,9 @@ export default {
|
|||||||
name: '',
|
name: '',
|
||||||
image: '',
|
image: '',
|
||||||
description: '',
|
description: '',
|
||||||
|
feeRate: '',
|
||||||
|
networkFee: 0,
|
||||||
|
isOpen: false,
|
||||||
del: true,
|
del: true,
|
||||||
state: 0
|
state: 0
|
||||||
}
|
}
|
||||||
@@ -721,17 +788,23 @@ export default {
|
|||||||
const res = await getMyShop()
|
const res = await getMyShop()
|
||||||
// 预期格式:{"code":0,"data":{"del":true,"description":"","id":0,"image":"","name":"","state":0},"msg":""}
|
// 预期格式:{"code":0,"data":{"del":true,"description":"","id":0,"image":"","name":"","state":0},"msg":""}
|
||||||
if (res && (res.code === 0 || res.code === 200) && res.data) {
|
if (res && (res.code === 0 || res.code === 200) && res.data) {
|
||||||
|
const shopData = this.normalizeShopData(res.data)
|
||||||
|
const feeRaw = Number(shopData.networkFee)
|
||||||
|
const feeValid = Number.isFinite(feeRaw) && feeRaw > 0
|
||||||
|
const isOpen = this.normalizeIsOpen(shopData.isOpen) || feeValid
|
||||||
this.shop = {
|
this.shop = {
|
||||||
id: res.data.id,
|
id: shopData.id,
|
||||||
name: res.data.name,
|
name: shopData.name,
|
||||||
image: res.data.image,
|
image: shopData.image,
|
||||||
description: res.data.description,
|
description: shopData.description,
|
||||||
feeRate: res.data.feeRate,
|
feeRate: shopData.feeRate,
|
||||||
del: !!res.data.del,
|
networkFee: feeValid ? feeRaw : 0,
|
||||||
state: Number(res.data.state || 0)
|
isOpen,
|
||||||
|
del: !!shopData.del,
|
||||||
|
state: Number(shopData.state || 0)
|
||||||
}
|
}
|
||||||
// 同步加载钱包绑定
|
// 同步加载钱包绑定
|
||||||
this.fetchShopConfigs(res.data.id)
|
this.fetchShopConfigs(shopData.id)
|
||||||
} else {
|
} else {
|
||||||
// 当接口返回错误或没有数据时,重置店铺状态
|
// 当接口返回错误或没有数据时,重置店铺状态
|
||||||
this.resetShopState()
|
this.resetShopState()
|
||||||
@@ -940,38 +1013,54 @@ export default {
|
|||||||
this.visibleEdit = true
|
this.visibleEdit = true
|
||||||
// 查询最新店铺详情
|
// 查询最新店铺详情
|
||||||
const res = await queryShop({ id: this.shop.id })
|
const res = await queryShop({ id: this.shop.id })
|
||||||
if (res && (res.code === 0 || res.code === 200) && res.data) {
|
if (res && (res.code === 0 || res.code === 200)) {
|
||||||
|
const shopData = this.normalizeShopData(res.data)
|
||||||
|
const feeRaw = Number(shopData.networkFee)
|
||||||
|
const feeValid = Number.isFinite(feeRaw) && feeRaw > 0
|
||||||
|
const isOpen = this.normalizeIsOpen(shopData.isOpen) || feeValid
|
||||||
|
const feeRateNum = Number(shopData.feeRate)
|
||||||
|
const feeRatePercent = Number.isFinite(feeRateNum) ? (feeRateNum * 100) : ''
|
||||||
this.editForm = {
|
this.editForm = {
|
||||||
id: res.data.id,
|
id: shopData.id,
|
||||||
name: res.data.name,
|
name: shopData.name,
|
||||||
image: res.data.image,
|
image: shopData.image,
|
||||||
description: res.data.description,
|
description: shopData.description,
|
||||||
feeRate: res.data.feeRate,
|
feeRate: feeRatePercent === '' ? '' : String(feeRatePercent),
|
||||||
gCode: ''
|
gCode: '',
|
||||||
|
isOpen,
|
||||||
|
networkFee: feeValid ? feeRaw : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 回退到当前展示的数据
|
// 回退到当前展示的数据
|
||||||
|
const fallbackRateNum = Number(this.shop.feeRate)
|
||||||
|
const fallbackRatePercent = Number.isFinite(fallbackRateNum) ? (fallbackRateNum * 100) : ''
|
||||||
this.editForm = {
|
this.editForm = {
|
||||||
id: this.shop.id,
|
id: this.shop.id,
|
||||||
name: this.shop.name,
|
name: this.shop.name,
|
||||||
image: this.shop.image,
|
image: this.shop.image,
|
||||||
description: this.shop.description,
|
description: this.shop.description,
|
||||||
feeRate: this.shop.feeRate,
|
feeRate: fallbackRatePercent === '' ? '' : String(fallbackRatePercent),
|
||||||
gCode: ''
|
gCode: '',
|
||||||
|
isOpen: false,
|
||||||
|
networkFee: 0
|
||||||
}
|
}
|
||||||
this.$message.warning(res && res.msg ? res.msg : '未获取到店铺详情')
|
this.$message.warning(res && res.msg ? res.msg : '未获取到店铺详情')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 出错时回退到当前展示的数据
|
// 出错时回退到当前展示的数据
|
||||||
|
const fallbackRateNum = Number(this.shop.feeRate)
|
||||||
|
const fallbackRatePercent = Number.isFinite(fallbackRateNum) ? (fallbackRateNum * 100) : ''
|
||||||
this.editForm = {
|
this.editForm = {
|
||||||
id: this.shop.id,
|
id: this.shop.id,
|
||||||
name: this.shop.name,
|
name: this.shop.name,
|
||||||
image: this.shop.image,
|
image: this.shop.image,
|
||||||
description: this.shop.description,
|
description: this.shop.description,
|
||||||
feeRate: this.shop.feeRate,
|
feeRate: fallbackRatePercent === '' ? '' : String(fallbackRatePercent),
|
||||||
gCode: ''
|
gCode: '',
|
||||||
|
isOpen: false,
|
||||||
|
networkFee: 0
|
||||||
}
|
}
|
||||||
console.error('查询店铺详情失败:', error)
|
console.error('查询店铺详情失败:', error)
|
||||||
|
|
||||||
@@ -1014,19 +1103,19 @@ export default {
|
|||||||
this.$message.warning('店铺描述不能超过300个字符')
|
this.$message.warning('店铺描述不能超过300个字符')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 手续费比例:必填、0.01-0.1、最多6位小数
|
// 手续费比例:必填、1-10(百分比)且最多6位小数
|
||||||
const rateRaw = String(this.editForm.feeRate || '').trim()
|
const rateRaw = String(this.editForm.feeRate || '').trim()
|
||||||
if (!rateRaw) {
|
if (!rateRaw) {
|
||||||
this.$message.warning('请填写店铺手续费比例(0.01 - 0.1,最多6位小数)')
|
this.$message.warning('请填写店铺手续费比例(1 - 10,最多6位小数)')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const rateNum = Number(rateRaw)
|
const rateNum = Number(rateRaw)
|
||||||
const decOk = rateRaw.includes('.') ? ((rateRaw.split('.')[1] || '').length <= 6) : true
|
const decOk = rateRaw.includes('.') ? ((rateRaw.split('.')[1] || '').length <= 6) : true
|
||||||
if (!Number.isFinite(rateNum) || rateNum < 0.01 || rateNum > 0.1 || !decOk) {
|
if (!Number.isFinite(rateNum) || rateNum < 1 || rateNum > 10 || !decOk) {
|
||||||
this.$message.warning('手续费比例需在 0.01 - 0.1 之间,且小数位不超过6位')
|
this.$message.warning('手续费比例需在 1 - 10 之间,且小数位不超过6位')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.editForm.feeRate = rateNum.toString()
|
this.editForm.feeRate = (rateNum / 100).toString()
|
||||||
|
|
||||||
// 谷歌验证码:必填 6 位数字
|
// 谷歌验证码:必填 6 位数字
|
||||||
const gCode = String(this.editForm.gCode || '').trim()
|
const gCode = String(this.editForm.gCode || '').trim()
|
||||||
@@ -1035,6 +1124,8 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const feeRaw = Number(this.editForm.networkFee)
|
||||||
|
this.editForm.networkFee = this.editForm.isOpen ? (Number.isFinite(feeRaw) && feeRaw > 0 ? feeRaw : 0.02) : 0
|
||||||
const payload = { ...this.editForm, gCode }
|
const payload = { ...this.editForm, gCode }
|
||||||
const res = await updateShop(payload)
|
const res = await updateShop(payload)
|
||||||
if (res && (res.code === 0 || res.code === 200)) {
|
if (res && (res.code === 0 || res.code === 200)) {
|
||||||
@@ -1203,6 +1294,57 @@ export default {
|
|||||||
/* 余额数字红色显示 */
|
/* 余额数字红色显示 */
|
||||||
.balance-num { color: #ff4d4f; font-weight: 600; }
|
.balance-num { color: #ff4d4f; font-weight: 600; }
|
||||||
.balance-unit { color: #606266; }
|
.balance-unit { color: #606266; }
|
||||||
|
.fee-rate-input {
|
||||||
|
max-width: 220px;
|
||||||
|
}
|
||||||
|
.edit-network {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f7f9fc;
|
||||||
|
border: 1px solid #eef2f7;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.edit-network-line {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.edit-network-label {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.edit-network-fee {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.edit-fee-value {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #eef2f7;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.edit-fee-value.on {
|
||||||
|
background: #fff7ed;
|
||||||
|
color: #c2410c;
|
||||||
|
border: 1px solid #fed7aa;
|
||||||
|
}
|
||||||
|
.edit-network-hint {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -10,9 +10,18 @@
|
|||||||
<div class="row"><span class="label">店铺:</span><span class="value">{{ order.shopName || '—' }}</span></div>
|
<div class="row"><span class="label">店铺:</span><span class="value">{{ order.shopName || '—' }}</span></div>
|
||||||
<div class="row"><span class="label">订单总价<span v-if="order.payCoin">({{ order.payCoin }})</span>:</span><span class="value strong">{{ order.totalPrice }}</span></div>
|
<div class="row"><span class="label">订单总价<span v-if="order.payCoin">({{ order.payCoin }})</span>:</span><span class="value strong">{{ order.totalPrice }}</span></div>
|
||||||
<div class="row"><span class="label">实际支付总金额<span v-if="order.payCoin">({{ order.payCoin }})</span>:</span><span class="value strong">{{ order.totalPayAmount !== null && order.totalPayAmount !== undefined ? order.totalPayAmount : '' }}</span></div>
|
<div class="row"><span class="label">实际支付总金额<span v-if="order.payCoin">({{ order.payCoin }})</span>:</span><span class="value strong">{{ order.totalPayAmount !== null && order.totalPayAmount !== undefined ? order.totalPayAmount : '' }}</span></div>
|
||||||
<div class="row"><span class="label">实际算力:</span><span class="value">{{ order.totalPracticalPower !== null && order.totalPracticalPower !== undefined ? order.totalPracticalPower : '' }}</span></div>
|
<div class="row">
|
||||||
<div class="row"><span class="label">理论总算力:</span><span class="value">{{ order.totalTheoryPower !== null && order.totalTheoryPower !== undefined ? order.totalTheoryPower : '' }}</span></div>
|
<span class="label">
|
||||||
<div class="row"><span class="label">实际/理论算力比值:</span><span class="value">{{ order.powerRatio !== null && order.powerRatio !== undefined ? order.powerRatio : '' }}</span></div>
|
<el-tooltip content="当前为平均算力值,实际算力值以最终结算为准。" placement="top">
|
||||||
|
<i class="el-icon-question tip-icon" />
|
||||||
|
</el-tooltip>
|
||||||
|
平均算力
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
<span class="value">{{ formatPowerWithUnit(order.totalPracticalPower, order.unit) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="row"><span class="label">理论总算力:</span><span class="value">{{ formatPowerWithUnit(order.totalTheoryPower, order.unit) }}</span></div>
|
||||||
|
<div class="row"><span class="label">实际/理论算力比值:</span><span class="value">{{ formatPowerRatio(order.powerRatio) }}</span></div>
|
||||||
<div class="row"><span class="label">创建时间:</span><span class="value">{{ formatDateTime(order.createTime) }}</span></div>
|
<div class="row"><span class="label">创建时间:</span><span class="value">{{ formatDateTime(order.createTime) }}</span></div>
|
||||||
<div v-if="Number(order.status) === 8" class="row"><span class="label">订单完成时间:</span><span class="value">{{ formatDateTime(order.endTime) }}</span></div>
|
<div v-if="Number(order.status) === 8" class="row"><span class="label">订单完成时间:</span><span class="value">{{ formatDateTime(order.endTime) }}</span></div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -25,9 +34,23 @@
|
|||||||
<el-table-column label="矿机类型" min-width="100">
|
<el-table-column label="矿机类型" min-width="100">
|
||||||
<template #default="scope">{{ formatMachineType(scope.row && scope.row.type) }}</template>
|
<template #default="scope">{{ formatMachineType(scope.row && scope.row.type) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="practicalPower" label="实际算力" min-width="120" />
|
<el-table-column min-width="120">
|
||||||
<el-table-column prop="theoryPower" label="理论算力" min-width="120" />
|
<template #header>
|
||||||
<el-table-column prop="powerRatio" label="实际/理论算力比值" min-width="160" />
|
<span>
|
||||||
|
<el-tooltip content="当前为平均算力值,实际算力值以最终结算为准。" placement="top">
|
||||||
|
<i class="el-icon-question tip-icon" />
|
||||||
|
</el-tooltip>
|
||||||
|
平均算力
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #default="scope">{{ formatPowerWithUnit(scope.row && scope.row.practicalPower, scope.row && scope.row.unit) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="理论算力" min-width="120">
|
||||||
|
<template #default="scope">{{ formatPowerWithUnit(scope.row && scope.row.theoryPower, scope.row && scope.row.unit) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="实际/理论算力比值" min-width="160">
|
||||||
|
<template #default="scope">{{ formatPowerRatio(scope.row && scope.row.powerRatio) }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="leaseTime" label="租赁天数" min-width="100" />
|
<el-table-column prop="leaseTime" label="租赁天数" min-width="100" />
|
||||||
<el-table-column label="购买数量" min-width="100">
|
<el-table-column label="购买数量" min-width="100">
|
||||||
<template #default="scope">{{ scope.row && scope.row.numbers != null ? scope.row.numbers : '—' }}</template>
|
<template #default="scope">{{ scope.row && scope.row.numbers != null ? scope.row.numbers : '—' }}</template>
|
||||||
@@ -125,6 +148,25 @@ export default {
|
|||||||
if (typeNum === 0) return 'ASIC'
|
if (typeNum === 0) return 'ASIC'
|
||||||
if (typeNum === 1) return 'GPU'
|
if (typeNum === 1) return 'GPU'
|
||||||
return '—'
|
return '—'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 实际/理论算力比值显示为百分比
|
||||||
|
*/
|
||||||
|
formatPowerRatio(value) {
|
||||||
|
if (value === null || value === undefined || value === '') return '—'
|
||||||
|
const num = Number(value)
|
||||||
|
if (!Number.isFinite(num)) return '—'
|
||||||
|
const percent = num * 100
|
||||||
|
const fixed = percent.toFixed(2)
|
||||||
|
return `${fixed.replace(/\.?0+$/, '')}%`
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 实际/理论算力展示:拼接单位(unit 有则显示)
|
||||||
|
*/
|
||||||
|
formatPowerWithUnit(power, unit) {
|
||||||
|
if (power === null || power === undefined || power === '') return '—'
|
||||||
|
const u = unit != null ? String(unit).trim() : ''
|
||||||
|
return u ? `${power} ${u}` : String(power)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,6 +183,7 @@ export default {
|
|||||||
.value.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; word-break: break-all; }
|
.value.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; word-break: break-all; }
|
||||||
.value.strong { font-weight: 700; color: #e74c3c; }
|
.value.strong { font-weight: 700; color: #e74c3c; }
|
||||||
.actions { margin-top: 12px; }
|
.actions { margin-top: 12px; }
|
||||||
|
.tip-icon { margin: 0 4px; color: #6b7280; cursor: pointer; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,6 @@
|
|||||||
<h2 class="page-title">商品列表</h2>
|
<h2 class="page-title">商品列表</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-area">
|
<div class="right-area">
|
||||||
<el-select
|
|
||||||
v-model="listParams.type"
|
|
||||||
placeholder="矿机种类"
|
|
||||||
size="small"
|
|
||||||
class="mr-12"
|
|
||||||
style="width: 140px"
|
|
||||||
@change="handleTypeChange"
|
|
||||||
>
|
|
||||||
<el-option :label="'ASIC'" :value="0" />
|
|
||||||
<el-option :label="'GPU'" :value="1" />
|
|
||||||
</el-select>
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchKeyword"
|
v-model="searchKeyword"
|
||||||
:placeholder="searchPlaceholder"
|
:placeholder="searchPlaceholder"
|
||||||
@@ -49,13 +38,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 售价展示币种选择(影响 ASIC 表格“售价”列展示) -->
|
<!-- 矿机类型切换按钮(表格左上方) -->
|
||||||
|
<div class="list-actions-row">
|
||||||
|
<div class="machine-type-switch">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
:type="listParams.type === 0 ? 'primary' : 'default'"
|
||||||
|
:class="{ active: listParams.type === 0 }"
|
||||||
|
@click="handleTypeChange(0)"
|
||||||
|
>
|
||||||
|
ASIC
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
:type="listParams.type === 1 ? 'primary' : 'default'"
|
||||||
|
:class="{ active: listParams.type === 1 }"
|
||||||
|
@click="handleTypeChange(1)"
|
||||||
|
>
|
||||||
|
GPU
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="listParams.type === 0 && payTypes && payTypes.length"
|
v-if="listParams.type === 0 && payTypes && payTypes.length"
|
||||||
class="price-select-bar"
|
class="price-select-bar inline"
|
||||||
style="margin:8px 0 4px; display:flex; justify-content:flex-end; align-items:center;"
|
|
||||||
>
|
>
|
||||||
<span style="margin-right:8px;color:#606266;font-size: 14px;">筛选售价:</span>
|
<span class="price-label">筛选售价:</span>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="selectedPayKey"
|
v-model="selectedPayKey"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -84,6 +91,7 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 表格列表(ASIC) -->
|
<!-- 表格列表(ASIC) -->
|
||||||
<el-table
|
<el-table
|
||||||
@@ -158,7 +166,12 @@
|
|||||||
<!-- 操作:去掉详情与添加出售机器 -->
|
<!-- 操作:去掉详情与添加出售机器 -->
|
||||||
<el-table-column label="操作" fixed="right" width="140">
|
<el-table-column label="操作" fixed="right" width="140">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="text" size="small" @click="handleEdit(scope.row)">修改</el-button>
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
:disabled="Number(scope.row.saleState) === 1"
|
||||||
|
@click="handleEdit(scope.row)"
|
||||||
|
>修改</el-button>
|
||||||
<el-button type="text" size="small" style="color:#f56c6c" @click="handleDelete(scope.row)">删除</el-button>
|
<el-button type="text" size="small" style="color:#f56c6c" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -197,6 +210,7 @@
|
|||||||
:active-value="0"
|
:active-value="0"
|
||||||
:inactive-value="1"
|
:inactive-value="1"
|
||||||
:value="(updateMap[getRowId(scope.row)] && updateMap[getRowId(scope.row)].state) != null ? updateMap[getRowId(scope.row)].state : 1"
|
:value="(updateMap[getRowId(scope.row)] && updateMap[getRowId(scope.row)].state) != null ? updateMap[getRowId(scope.row)].state : 1"
|
||||||
|
:disabled="Number(scope.row.saleState) === 1"
|
||||||
@change="handleToggleState(scope.row, $event)"
|
@change="handleToggleState(scope.row, $event)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -222,6 +236,7 @@
|
|||||||
class="gpu-price-input"
|
class="gpu-price-input"
|
||||||
:value="getPriceValue(getRowId(scope.row), pt)"
|
:value="getPriceValue(getRowId(scope.row), pt)"
|
||||||
placeholder="价格"
|
placeholder="价格"
|
||||||
|
:disabled="Number(scope.row.saleState) === 1"
|
||||||
@input="handlePriceInput(scope.row, pt, $event)"
|
@input="handlePriceInput(scope.row, pt, $event)"
|
||||||
@blur="handlePriceBlur(scope.row, pt)"
|
@blur="handlePriceBlur(scope.row, pt)"
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
@@ -236,7 +251,7 @@
|
|||||||
size="small"
|
size="small"
|
||||||
:value="String((updateMap[getRowId(scope.row)] && updateMap[getRowId(scope.row)].maxLeaseDays) || '')"
|
:value="String((updateMap[getRowId(scope.row)] && updateMap[getRowId(scope.row)].maxLeaseDays) || '')"
|
||||||
placeholder="1-365"
|
placeholder="1-365"
|
||||||
|
:disabled="Number(scope.row.saleState) === 1"
|
||||||
@input="handleMaxLeaseDaysInput(scope.row, $event)"
|
@input="handleMaxLeaseDaysInput(scope.row, $event)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -244,7 +259,13 @@
|
|||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<el-table-column label="操作" fixed="right" width="120">
|
<el-table-column label="操作" fixed="right" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="text" size="small" style="color:#f56c6c" @click="handleDelete(scope.row)">删除</el-button>
|
<el-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
style="color:#f56c6c"
|
||||||
|
:disabled="Number(scope.row.saleState) === 1"
|
||||||
|
@click="handleDelete(scope.row)"
|
||||||
|
>删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -1589,6 +1610,16 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
.price-select-bar.inline {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
.price-select-bar.inline .price-label {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
.paytypes-bar {
|
.paytypes-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1623,6 +1654,39 @@ export default {
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-actions-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
margin: 6px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.machine-type-switch {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.machine-type-switch .el-button {
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 6px 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6b7280;
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
.machine-type-switch .el-button.active {
|
||||||
|
color: #fff;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: 0 6px 12px rgba(118, 75, 162, 0.2);
|
||||||
|
}
|
||||||
|
.machine-type-switch .el-button:not(.active):hover {
|
||||||
|
color: #374151;
|
||||||
|
background: #e5e7eb;
|
||||||
|
border-color: #d1d5db;
|
||||||
|
}
|
||||||
|
|
||||||
/* 编辑弹窗内:让下拉/单选与输入框左边缘对齐 */
|
/* 编辑弹窗内:让下拉/单选与输入框左边缘对齐 */
|
||||||
.edit-form .align-like-input .el-form-item__content {
|
.edit-form .align-like-input .el-form-item__content {
|
||||||
padding-left: 12px; /* 对齐到上方 el-input 的内边距视觉效果 */
|
padding-left: 12px; /* 对齐到上方 el-input 的内边距视觉效果 */
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="power" label="实时算力" min-width="140">
|
<el-table-column prop="power" label="实时算力" min-width="140">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ scope.row.power || '—' }}</span>
|
<span>{{ formatPowerWithUnit(scope.row && scope.row.power, scope.row && scope.row.unit) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="recordTime" label="最近实时算力记录时间" min-width="180">
|
<el-table-column prop="recordTime" label="最近实时算力记录时间" min-width="180">
|
||||||
@@ -218,6 +218,14 @@ export default {
|
|||||||
return String(value)
|
return String(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 实时算力展示:拼接单位(unit 有则显示)
|
||||||
|
*/
|
||||||
|
formatPowerWithUnit(power, unit) {
|
||||||
|
if (power === null || power === undefined || power === '') return '—'
|
||||||
|
const u = unit != null ? String(unit).trim() : ''
|
||||||
|
return u ? `${power} ${u}` : String(power)
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 复制文本到剪贴板
|
* 复制文本到剪贴板
|
||||||
* @param {string} text - 需要复制的内容
|
* @param {string} text - 需要复制的内容
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
border
|
border
|
||||||
stripe
|
stripe
|
||||||
size="small"
|
size="small"
|
||||||
style="width: 100%; table-layout: auto;"
|
style="width: 100%; table-layout: fixed;"
|
||||||
:row-key="getRowKey"
|
:row-key="getRowKey"
|
||||||
:expand-row-keys="expandedRowKeys"
|
:expand-row-keys="expandedRowKeys"
|
||||||
:row-class-name="getRowClassName"
|
:row-class-name="getRowClassName"
|
||||||
@@ -51,24 +51,33 @@
|
|||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="detail-panel">
|
<div class="detail-panel">
|
||||||
<div class="detail-grid">
|
<div class="detail-grid">
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">付款网络/币种</span>
|
||||||
|
<span class="detail-value">
|
||||||
|
<span class="badge">{{ formatChain(scope.row.fromChain) || '-' }}</span>
|
||||||
|
<span class="badge badge-blue">{{ String((scope.row.fromSymbol || scope.row.coin) || '') .toUpperCase() }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<span class="detail-label">订单号</span>
|
<span class="detail-label">订单号</span>
|
||||||
<span class="detail-value mono">{{ scope.row.orderId || '-' }}</span>
|
<span class="detail-value mono">{{ scope.row.orderId || '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<span class="detail-label">付款链</span>
|
<span class="detail-label">实收金额</span>
|
||||||
<span class="detail-value"><span class="badge">{{ formatChain(scope.row.fromChain) || '-' }}</span></span>
|
<span class="detail-value">{{ formatAmount(scope.row.receivedAmount, scope.row.toSymbol || scope.row.coin || '').text }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<span class="detail-label">付款币种</span>
|
<span class="detail-label">应收金额</span>
|
||||||
<span class="detail-value"><span class="badge badge-blue">{{ String((scope.row.fromSymbol || scope.row.coin) || '') .toUpperCase() }}</span></span>
|
<span class="detail-value">{{ formatAmount(scope.row.realAmount, scope.row.toSymbol || scope.row.coin || '').text }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item detail-item-full">
|
<div class="detail-item">
|
||||||
<span class="detail-label">付款地址</span>
|
<span class="detail-label">手续费</span>
|
||||||
<span class="detail-value address">
|
<span class="detail-value">{{ formatAmount(scope.row.fee, scope.row.toSymbol || scope.row.coin || '').text }}</span>
|
||||||
<span class="mono-ellipsis" :title="scope.row.fromAddress">{{ scope.row.fromAddress || '-' }}</span>
|
</div>
|
||||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.fromAddress)" v-if="scope.row.fromAddress">复制</el-button>
|
<div class="detail-item">
|
||||||
</span>
|
|
||||||
|
<span class="detail-label">手续费比例</span>
|
||||||
|
<span class="detail-value">{{ formatFeeRate(scope.row.feeRate) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,45 +86,33 @@
|
|||||||
<el-table-column label="支付时间" width="160">
|
<el-table-column label="支付时间" width="160">
|
||||||
<template #default="scope">{{ formatFullTime(scope.row.createTime) }}</template>
|
<template #default="scope">{{ formatFullTime(scope.row.createTime) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="收款金额" width="140" align="right">
|
<el-table-column label="实收金额" width="140" align="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span class="amount-green">
|
<span class="amount-green">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
v-if="formatAmount(scope.row.realAmount, scope.row.toSymbol || scope.row.coin || '').truncated"
|
v-if="formatAmount(scope.row.receivedAmount, scope.row.toSymbol || scope.row.coin || '').truncated"
|
||||||
:content="`+${formatAmount(scope.row.realAmount, scope.row.toSymbol || scope.row.coin || '').full} ${(scope.row.toSymbol || scope.row.coin || '').toUpperCase()}`"
|
:content="`+${formatAmount(scope.row.receivedAmount, scope.row.toSymbol || scope.row.coin || '').full} ${(scope.row.toSymbol || scope.row.coin || '').toUpperCase()}`"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
+{{ formatAmount(scope.row.realAmount, scope.row.toSymbol || scope.row.coin || '').text }}
|
+{{ formatAmount(scope.row.receivedAmount, scope.row.toSymbol || scope.row.coin || '').text }}
|
||||||
{{ (scope.row.toSymbol || scope.row.coin || '').toUpperCase() }}
|
{{ (scope.row.toSymbol || scope.row.coin || '').toUpperCase() }}
|
||||||
<i class="el-icon-more amount-more"></i>
|
<i class="el-icon-more amount-more"></i>
|
||||||
</span>
|
</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
+{{ formatAmount(scope.row.realAmount, scope.row.toSymbol || scope.row.coin || '').text }}
|
+{{ formatAmount(scope.row.receivedAmount, scope.row.toSymbol || scope.row.coin || '').text }}
|
||||||
{{ (scope.row.toSymbol || scope.row.coin || '').toUpperCase() }}
|
{{ (scope.row.toSymbol || scope.row.coin || '').toUpperCase() }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="收款链" width="140">
|
<el-table-column label="收款网络" width="140">
|
||||||
<template #default="scope">{{ formatChain(scope.row.toChain) }}</template>
|
<template #default="scope">{{ formatChain(scope.row.toChain) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="收款币种" width="100">
|
<el-table-column label="收款币种" width="100">
|
||||||
<template #default="scope">{{ String(scope.row.coin || '').toUpperCase() }}</template>
|
<template #default="scope">{{ String(scope.row.coin || '').toUpperCase() }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="收款地址" min-width="200">
|
|
||||||
<template #default="scope">
|
|
||||||
<span class="mono-ellipsis" :title="scope.row.toAddress">{{ scope.row.toAddress }}</span>
|
|
||||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.toAddress)">复制</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="交易HASH" min-width="200">
|
|
||||||
<template #default="scope">
|
|
||||||
<span class="mono-ellipsis" :title="scope.row.txHash">{{ scope.row.txHash }}</span>
|
|
||||||
<el-button type="text" size="mini" @click.stop="copy(scope.row.txHash)" v-if="scope.row.txHash">复制</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="支付状态" width="120">
|
<el-table-column label="支付状态" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getStatusType(scope.row.status)" size="small">{{ getStatusText(scope.row.status) }}</el-tag>
|
<el-tag :type="getStatusType(scope.row.status)" size="small">{{ getStatusText(scope.row.status) }}</el-tag>
|
||||||
@@ -155,33 +152,53 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
useMock: true,
|
||||||
rows: [
|
rows: [
|
||||||
// {
|
{
|
||||||
// orderId: '1234567890',
|
orderId: '202401150001',
|
||||||
// fromChain: 'tron',
|
fromChain: 'tron',
|
||||||
// fromSymbol: 'USDT',
|
fromSymbol: 'USDT',
|
||||||
// fromAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
toChain: 'tron',
|
||||||
// toChain: 'tron',
|
toSymbol: 'USDT',
|
||||||
// coin: 'USDT',
|
coin: 'USDT',
|
||||||
// toAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
status: 1,
|
||||||
// txHash: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
createTime: '2024-01-15 12:10:25',
|
||||||
// status: 2,
|
updateTime: '2024-01-15 12:12:08',
|
||||||
// updateTime: '2024-01-15 14:30:25',
|
realAmount: 100,
|
||||||
// realAmount: 100,
|
receivedAmount: 98,
|
||||||
// },
|
feeRate: 0.02,
|
||||||
// {
|
fee: 2
|
||||||
// orderId: '1234567890',
|
},
|
||||||
// fromChain: 'tron',
|
{
|
||||||
// fromSymbol: 'USDT',
|
orderId: '202401150002',
|
||||||
// fromAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
fromChain: 'ethereum',
|
||||||
// toChain: 'tron',
|
fromSymbol: 'ETH',
|
||||||
// coin: 'USDT',
|
toChain: 'ethereum',
|
||||||
// toAddress: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
toSymbol: 'ETH',
|
||||||
// txHash: 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE',
|
coin: 'ETH',
|
||||||
// status: 1,
|
status: 2,
|
||||||
// updateTime: '2024-01-15 14:30:25',
|
createTime: '2024-01-15 13:22:40',
|
||||||
// realAmount: 106,
|
updateTime: '2024-01-15 13:25:55',
|
||||||
// }
|
realAmount: 0.5,
|
||||||
|
receivedAmount: 0.49,
|
||||||
|
feeRate: 0.02,
|
||||||
|
fee: 0.01
|
||||||
|
},
|
||||||
|
{
|
||||||
|
orderId: '202401150003',
|
||||||
|
fromChain: 'bsc',
|
||||||
|
fromSymbol: 'USDT',
|
||||||
|
toChain: 'bsc',
|
||||||
|
toSymbol: 'USDT',
|
||||||
|
coin: 'USDT',
|
||||||
|
status: 0,
|
||||||
|
createTime: '2024-01-15 14:05:12',
|
||||||
|
updateTime: '2024-01-15 14:06:09',
|
||||||
|
realAmount: 200,
|
||||||
|
receivedAmount: 0,
|
||||||
|
feeRate: 0.01,
|
||||||
|
fee: 0
|
||||||
|
}
|
||||||
],
|
],
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -253,6 +270,14 @@ export default {
|
|||||||
const map = { tron: 'Tron (TRC20)', ethereum: 'Ethereum (ERC20)', bsc: 'BSC (BEP20)', polygon: 'Polygon' }
|
const map = { tron: 'Tron (TRC20)', ethereum: 'Ethereum (ERC20)', bsc: 'BSC (BEP20)', polygon: 'Polygon' }
|
||||||
return map[chain] || chain || '-'
|
return map[chain] || chain || '-'
|
||||||
},
|
},
|
||||||
|
formatFeeRate(value) {
|
||||||
|
if (value === null || value === undefined || value === '') return '-'
|
||||||
|
const num = Number(value)
|
||||||
|
if (!Number.isFinite(num)) return '-'
|
||||||
|
const percent = num * 100
|
||||||
|
const fixed = percent.toFixed(6)
|
||||||
|
return `${fixed.replace(/\.?0+$/, '')}%`
|
||||||
|
},
|
||||||
getStatusType(status) {
|
getStatusType(status) {
|
||||||
const map = { 0: 'danger', 1: 'success', 2: 'warning', 3: 'danger' }
|
const map = { 0: 'danger', 1: 'success', 2: 'warning', 3: 'danger' }
|
||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
@@ -281,6 +306,11 @@ export default {
|
|||||||
this.page = 1
|
this.page = 1
|
||||||
},
|
},
|
||||||
async fetchList() {
|
async fetchList() {
|
||||||
|
if (this.useMock) {
|
||||||
|
this.rows = this.withKeys(this.rows)
|
||||||
|
this.total = this.rows.length
|
||||||
|
return
|
||||||
|
}
|
||||||
this.loading = true
|
this.loading = true
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
@@ -329,16 +359,21 @@ export default {
|
|||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.receipt-page :deep(.el-table__header),
|
||||||
|
.receipt-page :deep(.el-table__body) {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.receipt-page :deep(.el-table__body-wrapper) {
|
.receipt-page :deep(.el-table__body-wrapper) {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 展开详情样式 */
|
/* 展开详情样式 */
|
||||||
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; padding: 8px 4px; }
|
.detail-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 24px; padding: 8px 4px; }
|
||||||
.detail-item { display: grid; grid-template-columns: 90px 1fr; align-items: center; gap: 8px; }
|
.detail-item { display: grid; grid-template-columns: 96px 1fr; align-items: center; gap: 8px; }
|
||||||
.detail-item-full { grid-column: 1 / -1; }
|
.detail-item-full { grid-column: 1 / -1; }
|
||||||
.detail-label { color: #666; font-size: 13px; text-align: left; }
|
.detail-label { color: #666; font-size: 13px; text-align: left; }
|
||||||
.detail-value { color: #333; font-size: 13px; text-align: left; }
|
.detail-value { color: #333; font-size: 13px; text-align: left; display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||||
.detail-value.address { font-family: "Monaco", "Menlo", monospace; word-break: break-all; }
|
.detail-value.address { font-family: "Monaco", "Menlo", monospace; word-break: break-all; }
|
||||||
|
|
||||||
/* 单行等宽省略 */
|
/* 单行等宽省略 */
|
||||||
|
|||||||
@@ -31,14 +31,31 @@
|
|||||||
<label class="label required">手续费比例</label>
|
<label class="label required">手续费比例</label>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.feeRate"
|
v-model="form.feeRate"
|
||||||
placeholder="比例区间 0.01 - 0.1 之间,最多6位小数"
|
class="fee-rate-input"
|
||||||
|
placeholder="1 - 10"
|
||||||
@input="handleFeeRateInput"
|
@input="handleFeeRateInput"
|
||||||
/>
|
>
|
||||||
|
<template slot="append">%</template>
|
||||||
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin-top:-6px;">
|
<div class="row" style="margin-top:-6px;">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div style="color:#909399; font-size:12px; text-align:left;">
|
<div style="color:#909399; font-size:12px; text-align:left;">
|
||||||
为提升您的店铺曝光,您可为平台交易设置手续费比例,该手续费为商家向平台支付的交易佣金,手续费比例将作为影响店铺排名的关键因素,该比例越高,您的店铺排名就越靠前。
|
该手续费为商家向平台支付的交易佣金,比例越高店铺排名越靠前。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-top:16px;">
|
||||||
|
<label class="label">专用网络</label>
|
||||||
|
<div class="network-card">
|
||||||
|
<div class="network-line">
|
||||||
|
<span class="network-label">是否开启</span>
|
||||||
|
<el-switch v-model="form.isOpen" />
|
||||||
|
<span class="network-fee">
|
||||||
|
网络手续费
|
||||||
|
<span class="fee-value" :class="{ on: form.isOpen }">{{ networkFeeText }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="network-hint">专用网络会增加2%的手续费,建议无法直连矿池的用户开启</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin-top:50px;">
|
<div class="row" style="margin-top:50px;">
|
||||||
@@ -55,9 +72,14 @@ import { getAddShop } from "@/api/shops";
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: { name: "", description: "", image: "", feeRate: "" },
|
form: { name: "", description: "", image: "", feeRate: "", isOpen: false, networkFee: 0 },
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
networkFeeText() {
|
||||||
|
return this.form.isOpen ? '2%' : '0'
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
// 简单的emoji检测:覆盖常见表情平面与符号范围
|
// 简单的emoji检测:覆盖常见表情平面与符号范围
|
||||||
@@ -175,11 +197,11 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 手续费比例校验:必填、0.01-0.1 且最多6位小数
|
// 手续费比例校验:必填、1-10(百分比)且最多6位小数
|
||||||
const rateRaw = String(this.form.feeRate || '').trim()
|
const rateRaw = String(this.form.feeRate || '').trim()
|
||||||
if (!rateRaw) {
|
if (!rateRaw) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '请填写店铺手续费比例(0.01 - 0.1,最多6位小数)',
|
message: '请填写店铺手续费比例(1 - 10,最多6位小数)',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
showClose: true
|
showClose: true
|
||||||
})
|
})
|
||||||
@@ -187,15 +209,16 @@ export default {
|
|||||||
}
|
}
|
||||||
const rateNum = Number(rateRaw)
|
const rateNum = Number(rateRaw)
|
||||||
const decOk = rateRaw.includes('.') ? ((rateRaw.split('.')[1] || '').length <= 6) : true
|
const decOk = rateRaw.includes('.') ? ((rateRaw.split('.')[1] || '').length <= 6) : true
|
||||||
if (!Number.isFinite(rateNum) || rateNum < 0.01 || rateNum > 0.1 || !decOk) {
|
if (!Number.isFinite(rateNum) || rateNum < 1 || rateNum > 10 || !decOk) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '手续费比例需在 0.01 - 0.1 之间,且小数位不超过6位',
|
message: '手续费比例需在 1 - 10 之间,且小数位不超过6位',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
showClose: true
|
showClose: true
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.form.feeRate = rateNum.toString()
|
this.form.feeRate = (rateNum / 100).toString()
|
||||||
|
this.form.networkFee = this.form.isOpen ? 0.02 : 0
|
||||||
|
|
||||||
this.fetchAddShop(this.form)
|
this.fetchAddShop(this.form)
|
||||||
},
|
},
|
||||||
@@ -211,10 +234,10 @@ export default {
|
|||||||
}
|
}
|
||||||
.row {
|
.row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 140px 1fr;
|
grid-template-columns: 120px 1fr;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
.label {
|
.label {
|
||||||
color: #666;
|
color: #666;
|
||||||
@@ -222,6 +245,59 @@ export default {
|
|||||||
white-space: nowrap; /* 左侧文字不换行 */
|
white-space: nowrap; /* 左侧文字不换行 */
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
.fee-rate-input {
|
||||||
|
max-width: 220px;
|
||||||
|
}
|
||||||
|
.network-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #f7f9fc;
|
||||||
|
border: 1px solid #eef2f7;
|
||||||
|
width: 100%;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.network-line {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.network-label {
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.network-fee {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.fee-value {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #eef2f7;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.fee-value.on {
|
||||||
|
background: #fff7ed;
|
||||||
|
color: #c2410c;
|
||||||
|
border: 1px solid #fed7aa;
|
||||||
|
}
|
||||||
|
.network-hint {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
.actions-center {
|
.actions-center {
|
||||||
grid-column: 1 / -1; /* 跨两列,居中显示 */
|
grid-column: 1 / -1; /* 跨两列,居中显示 */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1955,6 +1955,7 @@ export default {
|
|||||||
orderMiningInfoDtoList.push({
|
orderMiningInfoDtoList.push({
|
||||||
coinConfigId: coinConfigId,
|
coinConfigId: coinConfigId,
|
||||||
coin: config.coin || '', // 用户选择的币种/算法框里的币种
|
coin: config.coin || '', // 用户选择的币种/算法框里的币种
|
||||||
|
algorithm: config.algorithm || config.originalAlgorithm || '', // 算法传参
|
||||||
poolName: config.poolName || '',
|
poolName: config.poolName || '',
|
||||||
poolUser: poolUser,
|
poolUser: poolUser,
|
||||||
walletAddress: walletAddress,
|
walletAddress: walletAddress,
|
||||||
|
|||||||
@@ -864,6 +864,8 @@ export default {
|
|||||||
duration: 3000,
|
duration: 3000,
|
||||||
showClose: true
|
showClose: true
|
||||||
})
|
})
|
||||||
|
// 重新拉取店铺机器列表,刷新 inCart 状态
|
||||||
|
try { await this.fetchGetMachineInfo(this.buildQueryParams()) } catch (e) { /* noop */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
this.confirmAddDialog.visible = false
|
this.confirmAddDialog.visible = false
|
||||||
|
|||||||
@@ -126,7 +126,7 @@
|
|||||||
:cell-style="{ textAlign: 'left' }"
|
:cell-style="{ textAlign: 'left' }"
|
||||||
>
|
>
|
||||||
<!-- 勾选框列(首列) -->
|
<!-- 勾选框列(首列) -->
|
||||||
<el-table-column width="46" fixed="left">
|
<el-table-column width="46" fixed="left" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-model="row._selected"
|
v-model="row._selected"
|
||||||
@@ -136,6 +136,12 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="购物车" width="68" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row && row.inCart" class="cart-flag" size="mini">已添加</el-tag>
|
||||||
|
<el-tag v-else size="mini" type="info">未添加</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="(col, colIdx) in getRenderedColumns()"
|
v-for="(col, colIdx) in getRenderedColumns()"
|
||||||
:key="col.key || colIdx"
|
:key="col.key || colIdx"
|
||||||
@@ -1208,6 +1214,12 @@ export default {
|
|||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cart-flag {
|
||||||
|
background: #fef3c7;
|
||||||
|
border-color: #f59e0b;
|
||||||
|
color: #b45309;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
::v-deep .el-input__prefix, .el-input__suffix{
|
::v-deep .el-input__prefix, .el-input__suffix{
|
||||||
top:24%;
|
top:24%;
|
||||||
|
|||||||
Binary file not shown.
1
power_leasing/test/css/app.4bdb375c.css
Normal file
1
power_leasing/test/css/app.4bdb375c.css
Normal file
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>power_leasing</title><script defer="defer" src="/js/chunk-vendors.92ffcf12.js"></script><script defer="defer" src="/js/app.d58df3d3.js"></script><link href="/css/chunk-vendors.10dd4e95.css" rel="stylesheet"><link href="/css/app.954338a1.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but power_leasing doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>power_leasing</title><script defer="defer" src="/js/chunk-vendors.92ffcf12.js"></script><script defer="defer" src="/js/app.bf293dd7.js"></script><link href="/css/chunk-vendors.10dd4e95.css" rel="stylesheet"><link href="/css/app.4bdb375c.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but power_leasing doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||||
2
power_leasing/test/js/app.bf293dd7.js
Normal file
2
power_leasing/test/js/app.bf293dd7.js
Normal file
File diff suppressed because one or more lines are too long
1
power_leasing/test/js/app.bf293dd7.js.map
Normal file
1
power_leasing/test/js/app.bf293dd7.js.map
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user