每周更新
This commit is contained in:
@@ -81,4 +81,26 @@ export function addAsicMachine(data) {
|
||||
})
|
||||
}
|
||||
|
||||
///添加出售机器的币种获取ASIC
|
||||
export function getSupportCoin() {
|
||||
return request({
|
||||
url: `/lease/v2/product/machine/getSupportCoin`,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
///添加出售机器的对应币种的算法获取ASIC
|
||||
/**
|
||||
* 根据币种获取支持的算法列表
|
||||
* @param {string} coin - 币种名称,例如 'BTC', 'ETH' 等
|
||||
* @returns {Promise} 返回算法列表
|
||||
*/
|
||||
export function getSupportAlgo(coin) {
|
||||
return request({
|
||||
url: `/lease/v2/product/machine/getSupportAlgo`,
|
||||
method: 'get',
|
||||
params: { coin } // 使用 params,request 拦截器会自动将参数拼接到 URL 查询字符串中
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -98,3 +98,15 @@ export function addOrdersV2(data) {
|
||||
|
||||
|
||||
|
||||
|
||||
//已购矿机配置
|
||||
export function getPurchasedItems(data) {
|
||||
return request({
|
||||
url: `/lease/v2/order/info/getPurchasedItems`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<script>
|
||||
import { readCart } from '../utils/cartManager'
|
||||
import { mainNavigation, getBreadcrumb } from '../utils/navigation'
|
||||
import { getGoodsList } from '../api/shoppingCart'
|
||||
import { getGoodsListV2 } from '../api/shoppingCart'
|
||||
|
||||
export default {
|
||||
name: 'Header',
|
||||
@@ -74,47 +74,37 @@ export default {
|
||||
loadCart() {
|
||||
this.cart = readCart()
|
||||
},
|
||||
/**
|
||||
* 加载服务器购物车数量
|
||||
* 根据新接口结构:res.rows[].cartMachineInfoDtoList.length 累加
|
||||
*/
|
||||
async loadServerCartCount() {
|
||||
try {
|
||||
const res = await getGoodsList()
|
||||
// 统一提取 rows/数组
|
||||
const primary = Array.isArray(res && res.rows)
|
||||
? res.rows
|
||||
: Array.isArray(res && res.data && res.data.rows)
|
||||
? res.data.rows
|
||||
: Array.isArray(res && res.data)
|
||||
? res.data
|
||||
: (Array.isArray(res) ? res : [])
|
||||
|
||||
let groups = []
|
||||
if (Array.isArray(primary) && primary.length) {
|
||||
// 情况A:shop -> shoppingCartInfoDtoList -> productMachineDtoList
|
||||
if (Array.isArray(primary[0] && primary[0].shoppingCartInfoDtoList)) {
|
||||
primary.forEach(shop => {
|
||||
if (Array.isArray(shop && shop.shoppingCartInfoDtoList)) {
|
||||
groups.push(...shop.shoppingCartInfoDtoList)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 情况B:直接就是商品分组数组
|
||||
groups = primary
|
||||
}
|
||||
} else if (Array.isArray(res && res.shoppingCartInfoDtoList)) {
|
||||
// 情况C:返回对象直接有 shoppingCartInfoDtoList
|
||||
groups = res.shoppingCartInfoDtoList
|
||||
}
|
||||
|
||||
const res = await getGoodsListV2()
|
||||
let total = 0
|
||||
if (groups.length) {
|
||||
total = groups.reduce((sum, g) => sum + (Array.isArray(g && g.productMachineDtoList) ? g.productMachineDtoList.length : 0), 0)
|
||||
} else if (Array.isArray(res && res.productMachineDtoList)) {
|
||||
// 情况D:根对象直接是机器列表
|
||||
total = res.productMachineDtoList.length
|
||||
|
||||
// 新接口结构:res.rows 是店铺数组,每个店铺有 cartMachineInfoDtoList
|
||||
if (Array.isArray(res && res.rows)) {
|
||||
total = res.rows.reduce((sum, shop) => {
|
||||
const machineList = Array.isArray(shop && shop.cartMachineInfoDtoList)
|
||||
? shop.cartMachineInfoDtoList
|
||||
: []
|
||||
return sum + machineList.length
|
||||
}, 0)
|
||||
} else if (Array.isArray(res && res.data && res.data.rows)) {
|
||||
// 兼容:如果数据在 res.data.rows 中
|
||||
total = res.data.rows.reduce((sum, shop) => {
|
||||
const machineList = Array.isArray(shop && shop.cartMachineInfoDtoList)
|
||||
? shop.cartMachineInfoDtoList
|
||||
: []
|
||||
return sum + machineList.length
|
||||
}, 0)
|
||||
}
|
||||
|
||||
this.cartServerCount = Number.isFinite(total) ? total : 0
|
||||
} catch (e) {
|
||||
// 忽略错误,保持当前显示
|
||||
console.error('加载购物车数量失败:', e)
|
||||
}
|
||||
},
|
||||
handleStorageChange(event) {
|
||||
|
||||
@@ -179,6 +179,16 @@ export const accountRoutes = [
|
||||
allAuthority: ['all']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'purchased-machine-config',
|
||||
name: 'accountPurchasedMachineConfig',
|
||||
component: () => import('../views/account/purchasedMachineConfig.vue'),
|
||||
meta: {
|
||||
title: '已购矿机配置',
|
||||
description: '查看已购买矿机的配置信息',
|
||||
allAuthority: ['all']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'funds-flow',
|
||||
name: 'accountFundsFlow',
|
||||
|
||||
@@ -6,11 +6,16 @@
|
||||
<template #default="outer">
|
||||
<el-table :data="outer.row.orderItemDtoList || []" size="small" border :header-cell-style="{ textAlign: 'left' }" :cell-style="{ textAlign: 'left' }" row-key="productMachineId">
|
||||
<el-table-column prop="productMachineId" label="机器ID" min-width="120" />
|
||||
<el-table-column prop="name" label="名称" min-width="160" />
|
||||
<el-table-column label="矿机类型" min-width="100">
|
||||
<template #default="scope">{{ formatMachineType(scope.row && scope.row.type) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="payCoin" label="币种" min-width="100" />
|
||||
<el-table-column prop="address" label="收款地址" min-width="240" />
|
||||
<el-table-column prop="leaseTime" label="租赁天数" min-width="100" />
|
||||
<el-table-column prop="price" label="售价(USDT)" min-width="240">
|
||||
<el-table-column label="购买数量" min-width="100">
|
||||
<template #default="scope">{{ scope.row && scope.row.numbers != null ? scope.row.numbers : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="单价(USDT)" min-width="240">
|
||||
<template #default="scope">
|
||||
<span class="value strong">
|
||||
<el-tooltip
|
||||
@@ -31,17 +36,20 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="店铺" width="120">
|
||||
<template #default="scope">{{ scope.row && scope.row.shopName || '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单号" min-width="220">
|
||||
<template #default="scope"><span class="value mono">{{ scope.row && scope.row.orderNumber || '—' }}</span></template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="创建时间" min-width="180">
|
||||
<el-table-column label="创建时间" width="160">
|
||||
<template #default="scope">{{ formatDateTime(scope.row && scope.row.createTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数" min-width="100">
|
||||
<el-table-column label="商品数" min-width="70">
|
||||
<template #default="scope">{{ Array.isArray(scope.row && scope.row.orderItemDtoList) ? scope.row.orderItemDtoList.length : 0 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总金额(USDT)" min-width="140">
|
||||
<el-table-column label="总金额(USDT)" width="120">
|
||||
<template #default="scope">
|
||||
<span class="value strong">
|
||||
<el-tooltip
|
||||
@@ -58,7 +66,7 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="180">
|
||||
<el-table-column width="160">
|
||||
<template #header>
|
||||
<el-tooltip placement="top" effect="dark">
|
||||
<div slot="content">
|
||||
@@ -88,24 +96,10 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="待支付金额(USDT)" min-width="140">
|
||||
<template #default="scope">
|
||||
<span class="value strong">
|
||||
<el-tooltip
|
||||
v-if="formatAmount(scope.row && scope.row.noPayAmount, 'USDT').truncated"
|
||||
:content="formatAmount(scope.row && scope.row.noPayAmount, 'USDT').full"
|
||||
placement="top"
|
||||
>
|
||||
<span>
|
||||
{{ formatAmount(scope.row && scope.row.noPayAmount, 'USDT').text }}
|
||||
<i class="el-icon-more amount-more"></i>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<span v-else>{{ formatAmount(scope.row && scope.row.noPayAmount, 'USDT').text }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<el-table-column label="订单完成时间" width="160">
|
||||
<template #default="scope">{{ formatDateTime(scope.row && scope.row.endTime) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="280" fixed="right">
|
||||
<el-table-column label="操作" min-width="60" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button size="mini" @click="handleGoDetail(scope.row)" style="margin-right:8px;">详情</el-button>
|
||||
<template v-if="shouldShowActions(scope.row)">
|
||||
@@ -241,6 +235,18 @@ export default {
|
||||
if (!value) return '—'
|
||||
try { const str = String(value); return str.includes('T') ? str.replace('T', ' ') : str } catch (e) { return String(value) }
|
||||
},
|
||||
/**
|
||||
* 格式化矿机类型
|
||||
* @param {number} type - 矿机类型:0=ASIC, 1=GPU
|
||||
* @returns {string} 类型文本
|
||||
*/
|
||||
formatMachineType(type) {
|
||||
if (type === null || type === undefined) return '—'
|
||||
const typeNum = Number(type)
|
||||
if (typeNum === 0) return 'ASIC'
|
||||
if (typeNum === 1) return 'GPU'
|
||||
return '—'
|
||||
},
|
||||
async handleCheckout(row) {
|
||||
if (!row) return
|
||||
try {
|
||||
|
||||
@@ -64,6 +64,7 @@ export default {
|
||||
buyerLinks: [
|
||||
{ label: '我的钱包', to: '/account/wallet' },
|
||||
{ label: '已购商品', to: '/account/purchased' },
|
||||
{ label: '已购矿机配置', to: '/account/purchased-machine-config' },
|
||||
{ label: '订单列表', to: '/account/orders' },
|
||||
// { label: '充值记录', to: '/account/rechargeRecord' },
|
||||
// { label: '提现记录', to: '/account/withdrawalHistory' },
|
||||
@@ -154,11 +155,12 @@ export default {
|
||||
}
|
||||
return
|
||||
}
|
||||
// 买家前缀优先匹配,确保“已购详情”等页面归属买家侧
|
||||
// 买家前缀优先匹配,确保"已购详情"等页面归属买家侧
|
||||
const buyerPrefixes = [
|
||||
'/account/wallet',
|
||||
'/account/purchased',
|
||||
'/account/purchased-detail',
|
||||
'/account/purchased-machine-config',
|
||||
'/account/orders',
|
||||
'/account/funds-flow'
|
||||
]
|
||||
@@ -206,13 +208,26 @@ export default {
|
||||
const map = {
|
||||
'/account/seller-orders': ['/account/seller-orders'],
|
||||
'/account/products': ['/account/products', '/account/product-detail'],
|
||||
'/account/purchased': ['/account/purchased', '/account/purchased-detail']
|
||||
'/account/purchased': ['/account/purchased', '/account/purchased-detail'],
|
||||
'/account/purchased-machine-config': ['/account/purchased-machine-config']
|
||||
}
|
||||
const prefixes = map[pathLike]
|
||||
if (Array.isArray(prefixes)) {
|
||||
return prefixes.some(p => current.indexOf(p) === 0)
|
||||
return prefixes.some(p => {
|
||||
// 精确匹配
|
||||
if (current === p) return true
|
||||
// 对于详情页路径,使用前缀匹配(支持 /account/purchased-detail/:id)
|
||||
if (p === '/account/purchased-detail' || p === '/account/product-detail') {
|
||||
return current.indexOf(p) === 0
|
||||
}
|
||||
// 列表页已经在上面精确匹配了,这里不需要额外处理
|
||||
return false
|
||||
})
|
||||
}
|
||||
return current.indexOf(pathLike) === 0
|
||||
// 不在 map 中的路径,精确匹配
|
||||
// 特别注意:避免 /account/purchased 匹配到 /account/purchased-machine-config
|
||||
// 使用精确匹配而不是前缀匹配
|
||||
return current === pathLike
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -344,6 +359,7 @@ export default {
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
min-height: 420px;
|
||||
width: 82vw;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
<div class="row"><span class="label">订单ID:</span><span class="value mono">{{ order.id || '—' }}</span></div>
|
||||
<div class="row"><span class="label">订单号:</span><span class="value mono">{{ order.orderNumber || '—' }}</span></div>
|
||||
<div class="row"><span class="label">状态:</span><span class="value">{{ getOrderStatusText(order.status) }}</span></div>
|
||||
<div class="row"><span class="label">店铺:</span><span class="value">{{ order.shopName || '—' }}</span></div>
|
||||
<div class="row"><span class="label">金额(USDT):</span><span class="value strong">{{ order.totalPrice }}</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.endTime) }}</span></div>
|
||||
</el-card>
|
||||
|
||||
<el-card class="section" style="margin-top:12px;">
|
||||
@@ -16,9 +18,14 @@
|
||||
<el-table :data="items" border size="small" style="width:100%"
|
||||
:header-cell-style="{ textAlign: 'left' }" :cell-style="{ textAlign: 'left' }">
|
||||
<el-table-column prop="productMachineId" label="机器ID" min-width="120" />
|
||||
<el-table-column prop="name" label="名称" min-width="160" />
|
||||
<el-table-column label="矿机类型" min-width="100">
|
||||
<template #default="scope">{{ formatMachineType(scope.row && scope.row.type) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="payCoin" label="币种" min-width="100" />
|
||||
<el-table-column prop="leaseTime" label="租赁天数" min-width="100" />
|
||||
<el-table-column label="购买数量" min-width="100">
|
||||
<template #default="scope">{{ scope.row && scope.row.numbers != null ? scope.row.numbers : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="price" label="单价(USDT)" min-width="120" />
|
||||
<el-table-column prop="address" label="收款地址" min-width="240" />
|
||||
</el-table>
|
||||
@@ -91,6 +98,18 @@ export default {
|
||||
} catch (e) {
|
||||
return String(value)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 格式化矿机类型
|
||||
* @param {number} type - 矿机类型:0=ASIC, 1=GPU
|
||||
* @returns {string} 类型文本
|
||||
*/
|
||||
formatMachineType(type) {
|
||||
if (type === null || type === undefined) return '—'
|
||||
const typeNum = Number(type)
|
||||
if (typeNum === 0) return 'ASIC'
|
||||
if (typeNum === 1) return 'GPU'
|
||||
return '—'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
421
power_leasing/src/views/account/purchasedMachineConfig.vue
Normal file
421
power_leasing/src/views/account/purchasedMachineConfig.vue
Normal file
@@ -0,0 +1,421 @@
|
||||
<template>
|
||||
<div class="account-purchased-machine-config">
|
||||
<div class="toolbar">
|
||||
<div class="left-area">
|
||||
<h2 class="page-title">已购矿机配置</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
:data="tableData"
|
||||
v-loading="loading"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
:header-cell-style="{ textAlign: 'left' }"
|
||||
:cell-style="{ textAlign: 'left' }"
|
||||
>
|
||||
<el-table-column type="expand" width="46">
|
||||
<template #default="scope">
|
||||
<div class="expand-content">
|
||||
<div class="expand-row" v-if="scope.row.walletAddress">
|
||||
<div class="expand-label">钱包地址:</div>
|
||||
<div class="expand-value">
|
||||
<span class="mono-ellipsis" style="font-family: monospace;">{{ scope.row.walletAddress }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-document-copy"
|
||||
@click="handleCopy(scope.row.walletAddress, '钱包地址')"
|
||||
class="copy-btn"
|
||||
>
|
||||
复制
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="expand-row" v-if="scope.row.poolUrl">
|
||||
<div class="expand-label">矿池地址:</div>
|
||||
<div class="expand-value">
|
||||
<span class="mono-ellipsis">{{ scope.row.poolUrl }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-document-copy"
|
||||
@click="handleCopy(scope.row.poolUrl, '矿池地址')"
|
||||
class="copy-btn"
|
||||
>
|
||||
复制
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="expand-row" v-if="scope.row.watchUrl">
|
||||
<div class="expand-label">挖矿信息页面地址:</div>
|
||||
<div class="expand-value">
|
||||
<span class="mono-ellipsis">{{ scope.row.watchUrl }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-document-copy"
|
||||
@click="handleCopy(scope.row.watchUrl, '挖矿信息页面地址')"
|
||||
class="copy-btn"
|
||||
>
|
||||
复制
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!scope.row.walletAddress && !scope.row.poolUrl && !scope.row.watchUrl" class="expand-empty">
|
||||
暂无地址信息
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column prop="id" label="ID" width="80" /> -->
|
||||
|
||||
<el-table-column prop="coin" label="币种" width="100">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.coin || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="algorithm" label="算法" min-width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.algorithm || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="pool" label="矿池" min-width="140">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.pool || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="poolUser" label="矿池用户" min-width="140">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.poolUser || '—' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
|
||||
<el-table-column prop="startTime" label="开始时间" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ formatDateTime(scope.row.startTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="endTime" label="结束时间" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ formatDateTime(scope.row.endTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="status" label="状态" width="140">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">
|
||||
{{ getStatusText(scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
background
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
:current-page.sync="pagination.pageNum"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size.sync="pagination.pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPurchasedItems } from '../../api/order'
|
||||
|
||||
/**
|
||||
* 已购矿机配置页面
|
||||
* - 展示已购买矿机的配置信息
|
||||
* - 支持分页查询
|
||||
*/
|
||||
export default {
|
||||
name: 'AccountPurchasedMachineConfig',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
tableData: [],
|
||||
pagination: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
total: 0,
|
||||
totalPage: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchTableData()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取已购矿机配置列表
|
||||
*/
|
||||
async fetchTableData() {
|
||||
this.loading = true
|
||||
try {
|
||||
const params = {
|
||||
pageNum: this.pagination.pageNum,
|
||||
pageSize: this.pagination.pageSize
|
||||
}
|
||||
const res = await getPurchasedItems(params)
|
||||
if (res && (res.code === 0 || res.code === 200)) {
|
||||
this.tableData = Array.isArray(res.rows) ? res.rows : []
|
||||
this.total = Number(res.total || 0)
|
||||
this.totalPage = Number(res.totalPage || 0)
|
||||
} else {
|
||||
this.tableData = []
|
||||
this.total = 0
|
||||
this.totalPage = 0
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取已购矿机配置失败', e)
|
||||
this.$message({
|
||||
message: '获取已购矿机配置失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
this.tableData = []
|
||||
this.total = 0
|
||||
this.totalPage = 0
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 处理分页大小变化
|
||||
* @param {number} size - 新的分页大小
|
||||
*/
|
||||
handleSizeChange(size) {
|
||||
this.pagination.pageSize = size
|
||||
this.pagination.pageNum = 1
|
||||
this.fetchTableData()
|
||||
},
|
||||
/**
|
||||
* 处理当前页变化
|
||||
* @param {number} page - 新的页码
|
||||
*/
|
||||
handleCurrentChange(page) {
|
||||
this.pagination.pageNum = page
|
||||
this.fetchTableData()
|
||||
},
|
||||
/**
|
||||
* 格式化日期时间
|
||||
* @param {string|number} value - 日期时间值
|
||||
* @returns {string} 格式化后的日期时间字符串
|
||||
*/
|
||||
formatDateTime(value) {
|
||||
if (!value) return '—'
|
||||
try {
|
||||
const str = String(value)
|
||||
return str.includes('T') ? str.replace('T', ' ') : str
|
||||
} catch (e) {
|
||||
return String(value)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 复制文本到剪贴板
|
||||
* @param {string} text - 需要复制的内容
|
||||
* @param {string} label - 语义标签,用于提示文案
|
||||
*/
|
||||
async handleCopy(text, label = '内容') {
|
||||
if (!text) {
|
||||
this.$message({
|
||||
message: `${label}为空,无法复制`,
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const value = String(text).trim()
|
||||
if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(value)
|
||||
this.$message({
|
||||
message: `${label}已复制到剪贴板`,
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
} else {
|
||||
// 备用复制方法
|
||||
const textArea = document.createElement('textarea')
|
||||
textArea.value = value
|
||||
textArea.style.position = 'fixed'
|
||||
textArea.style.left = '-9999px'
|
||||
document.body.appendChild(textArea)
|
||||
textArea.focus()
|
||||
textArea.select()
|
||||
try {
|
||||
document.execCommand('copy')
|
||||
this.$message({
|
||||
message: `${label}已复制到剪贴板`,
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
} catch (err) {
|
||||
this.$message({
|
||||
message: '复制失败,请手动复制',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
}
|
||||
document.body.removeChild(textArea)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('复制失败', e)
|
||||
this.$message({
|
||||
message: '复制失败,请手动复制',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取状态文本
|
||||
* @param {number|boolean} status - 状态值
|
||||
* @returns {string} 状态文本
|
||||
*/
|
||||
getStatusText(status) {
|
||||
const statusNum = Number(status)
|
||||
if (statusNum === 0) return '租约已到期'
|
||||
if (statusNum === 1) return '挖矿中'
|
||||
if (statusNum === 2) return '卖家矿机启动中'
|
||||
// 兼容旧数据(boolean类型)
|
||||
if (status === true) return '挖矿中'
|
||||
return '未知状态'
|
||||
},
|
||||
/**
|
||||
* 获取状态标签类型
|
||||
* @param {number|boolean} status - 状态值
|
||||
* @returns {string} el-tag 的类型
|
||||
*/
|
||||
getStatusType(status) {
|
||||
const statusNum = Number(status)
|
||||
if (statusNum === 0) return 'info' // 租约已到期 - 灰色
|
||||
if (statusNum === 1) return 'success' // 挖矿中 - 绿色
|
||||
if (statusNum === 2) return 'warning' // 卖家矿机启动中 - 黄色
|
||||
// 兼容旧数据(boolean类型)
|
||||
if (status === true) return 'success'
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.account-purchased-machine-config {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.left-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* 展开内容样式 */
|
||||
.expand-content {
|
||||
padding: 16px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.expand-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.expand-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.expand-label {
|
||||
min-width: 100px;
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.expand-value {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.expand-value .mono-ellipsis {
|
||||
font-family: monospace;
|
||||
color: #303133;
|
||||
line-height: 1.5;
|
||||
word-break: break-all;
|
||||
flex: 0 1 auto;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
flex-shrink: 0;
|
||||
padding: 0 8px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
.expand-empty {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 钱包地址和URL格式化显示样式 */
|
||||
.mono-ellipsis {
|
||||
font-family: monospace;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="机器ID" width="80" />
|
||||
<el-table-column prop="algorithm" label="算法" />
|
||||
<el-table-column prop="algorithm" label="最大收益算法" />
|
||||
|
||||
|
||||
<!-- <el-table-column prop="powerDissipation" label="功耗(kw/h)">
|
||||
@@ -343,7 +343,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="机器ID" min-width="160" />
|
||||
<el-table-column prop="algorithm" label="算法" min-width="140" />
|
||||
<el-table-column prop="algorithm" label="最大收益算法" min-width="140" />
|
||||
<el-table-column prop="unitPrice" min-width="140">
|
||||
<template #header>单价({{ grp.coinSymbol || 'USDT' }})</template>
|
||||
<template #default="scope">
|
||||
@@ -408,6 +408,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="handleConfirmDialogPrev">上一步</el-button>
|
||||
<el-button @click="confirmDialog.visible=false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmPay">确认结算</el-button>
|
||||
</template>
|
||||
@@ -416,7 +417,7 @@
|
||||
|
||||
|
||||
<!-- 购物须知(测试版) - 必须勾选并等待5秒后才可关闭 -->
|
||||
<el-dialog :visible.sync="noticeDialog.visible" width="680px" title="下单须知" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||
<el-dialog :visible.sync="noticeDialog.visible" width="60vw" title="下单须知" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||
<div class="notice-content">
|
||||
<p class="notice-title">尊敬的客户,感谢您选择我们的服务。在您下单前,请务必仔细阅读并完全理解以下须知条款。一旦您点击" 同意并下单"或完成支付流程,即视为您已充分阅读、理解并同意接受本须知的全部内容约束。</p>
|
||||
<ol class="notice-list">
|
||||
@@ -445,7 +446,7 @@
|
||||
:close-on-click-modal="false" :close-on-press-escape="false">
|
||||
<div>
|
||||
<!-- 未配置的机器配置区域 -->
|
||||
<div v-if="unconfiguredMachinesList.length > 0">
|
||||
<div v-if="configDialog.selectedMachines && configDialog.selectedMachines.length > 0">
|
||||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
|
||||
<div style="font-weight:600;color:#2c3e50;">选择币种/算法</div>
|
||||
<el-cascader
|
||||
@@ -468,65 +469,121 @@
|
||||
style="width: 240px;"
|
||||
size="small"
|
||||
@change="handlePoolValueChange"
|
||||
:disabled="!configDialog.coinAlgoValue || configDialog.coinAlgoValue.length !== 2"
|
||||
/>
|
||||
</div>
|
||||
<el-table
|
||||
:data="unconfiguredMachinesList"
|
||||
max-height="300"
|
||||
border
|
||||
stripe
|
||||
ref="configTable"
|
||||
row-key="id"
|
||||
reserve-selection
|
||||
@selection-change="handleConfigSelectionChange"
|
||||
:header-cell-style="{ textAlign: 'left', fontSize: '14px' }"
|
||||
:cell-style="{ textAlign: 'left', fontSize: '14px' }">
|
||||
<el-table-column type="selection" width="46" />
|
||||
<el-table-column label="矿机种类" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
disable-transitions
|
||||
:class="['type-tag', typeClass(scope.row.type)]"
|
||||
style="font-size: 14px;"
|
||||
>
|
||||
{{ formatMachineType(scope.row.type) }}
|
||||
</el-tag>
|
||||
<!-- 机器列表 -->
|
||||
<div v-if="unconfiguredMachinesList.length > 0">
|
||||
<div style="font-weight:600;color:#2c3e50;margin-bottom:8px;font-size:14px;">
|
||||
<template v-if="!configDialog.coinAlgoValue || configDialog.coinAlgoValue.length !== 2">
|
||||
待配置机器(共 {{ unconfiguredMachinesList.length }} 台)
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="机器ID" width="120" />
|
||||
<el-table-column prop="algorithm" label="算法" min-width="140" />
|
||||
</el-table>
|
||||
<div style="display:flex;align-items:center;gap:12px;margin-top:12px;flex-wrap: nowrap;">
|
||||
<div style="font-weight:600;color:#2c3e50;white-space: nowrap;">钱包地址</div>
|
||||
<el-input
|
||||
v-model="configDialog.walletAddress"
|
||||
placeholder="请输入钱包地址(26-95个字符,仅支持英文、数字)"
|
||||
size="small"
|
||||
style="width: 380px;"
|
||||
clearable
|
||||
maxlength="95"
|
||||
@input="handleWalletAddressInput"
|
||||
/>
|
||||
<div style="font-weight:600;color:#2c3e50;margin-left:8px;white-space: nowrap;">挖矿账户</div>
|
||||
<el-input
|
||||
v-model="configDialog.miningAccount"
|
||||
placeholder="挖矿账户(仅支持英文、数字)"
|
||||
size="small"
|
||||
style="width: 220px;"
|
||||
clearable
|
||||
maxlength="50"
|
||||
@input="handleMiningAccountInput"
|
||||
/>
|
||||
<div style="font-weight:600;color:#2c3e50;margin-left:8px;white-space: nowrap;">矿工号</div>
|
||||
<el-input
|
||||
v-model="configDialog.workerId"
|
||||
placeholder="矿工号(最多24个英文字符)"
|
||||
size="small"
|
||||
style="width: 220px;"
|
||||
clearable
|
||||
maxlength="24"
|
||||
@input="handleWorkerIdInput"
|
||||
/>
|
||||
<template v-else>
|
||||
支持该币种/算法的机器(共 {{ unconfiguredMachinesList.length }} 台)
|
||||
</template>
|
||||
</div>
|
||||
<el-table
|
||||
:data="unconfiguredMachinesList"
|
||||
max-height="300"
|
||||
border
|
||||
stripe
|
||||
ref="configTable"
|
||||
row-key="id"
|
||||
reserve-selection
|
||||
@selection-change="handleConfigSelectionChange"
|
||||
:header-cell-style="{ textAlign: 'left', fontSize: '14px' }"
|
||||
:cell-style="{ textAlign: 'left', fontSize: '14px' }">
|
||||
<el-table-column type="selection" width="46" />
|
||||
<el-table-column label="矿机种类" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
disable-transitions
|
||||
:class="['type-tag', typeClass(scope.row.type)]"
|
||||
style="font-size: 14px;"
|
||||
>
|
||||
{{ formatMachineType(scope.row.type) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="机器ID" width="120" />
|
||||
<el-table-column prop="algorithm" label="最大收益算法" min-width="140" />
|
||||
<!-- 矿工号列始终显示(只要选择了矿池/模型) -->
|
||||
<el-table-column
|
||||
v-if="getCurrentWalletMining() !== null"
|
||||
label="矿工号"
|
||||
min-width="160">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row._workerId"
|
||||
placeholder="矿工号"
|
||||
size="mini"
|
||||
clearable
|
||||
maxlength="40"
|
||||
@input="val => handleMachineWorkerIdInput(scope.row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 统一输入区域:根据 walletMining 显示钱包地址或挖矿账户 -->
|
||||
<div v-if="getCurrentWalletMining() !== null" style="margin-top: 16px;">
|
||||
<!-- 钱包地址输入(当 walletMining 为 true 时显示) -->
|
||||
<div v-if="getCurrentWalletMining() === true" style="display: flex; align-items: center; gap: 12px;">
|
||||
<label style="font-weight: 600; color: #2c3e50; min-width: 100px;">钱包地址:</label>
|
||||
<el-input
|
||||
v-model="configDialog.walletAddress"
|
||||
placeholder="请输入钱包地址"
|
||||
clearable
|
||||
maxlength="95"
|
||||
style="flex: 1; max-width: 500px;"
|
||||
@input="handleWalletAddressInput"
|
||||
/>
|
||||
</div>
|
||||
<!-- 挖矿账户输入(当 walletMining 为 false 时显示) -->
|
||||
<div v-if="getCurrentWalletMining() === false" style="display: flex; align-items: center; gap: 12px;">
|
||||
<label style="font-weight: 600; color: #2c3e50; min-width: 100px;">挖矿账户:</label>
|
||||
<el-input
|
||||
v-model="configDialog.miningAccount"
|
||||
placeholder="请输入挖矿账户"
|
||||
clearable
|
||||
maxlength="40"
|
||||
style="flex: 1; max-width: 500px;"
|
||||
@input="handleMiningAccountInput"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="configDialog.coinAlgoValue && configDialog.coinAlgoValue.length === 2 && getCurrentWalletMining() === null" style="margin-top: 16px; color: #909399; font-size: 14px;">
|
||||
请先选择矿池/模型
|
||||
</div>
|
||||
<div v-else-if="configDialog.coinAlgoValue && configDialog.coinAlgoValue.length === 2 && unconfiguredMachinesList.length === 0" style="margin-bottom:12px;color:#909399;font-size:14px;">
|
||||
当前选择的币种/算法下没有可配置的机器
|
||||
</div>
|
||||
<!-- 不支持的机器列表 -->
|
||||
<div v-if="unsupportedMachinesList.length > 0" style="margin-top: 16px;">
|
||||
<div style="font-weight:600;color:#f56c6c;margin-bottom:8px;font-size:14px;">
|
||||
不支持该币种/算法的机器(共 {{ unsupportedMachinesList.length }} 台)
|
||||
</div>
|
||||
<el-table
|
||||
:data="unsupportedMachinesList"
|
||||
max-height="200"
|
||||
border
|
||||
stripe
|
||||
:header-cell-style="{ textAlign: 'left', fontSize: '14px' }"
|
||||
:cell-style="{ textAlign: 'left', fontSize: '14px' }">
|
||||
<el-table-column label="矿机种类" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
disable-transitions
|
||||
:class="['type-tag', typeClass(scope.row.type)]"
|
||||
style="font-size: 14px;"
|
||||
>
|
||||
{{ formatMachineType(scope.row.type) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="机器ID" width="120" />
|
||||
<el-table-column prop="algorithm" label="最大收益算法" min-width="140" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -560,12 +617,21 @@
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="miningAccount" label="挖矿账户" min-width="140" />
|
||||
<el-table-column prop="workerId" label="矿工号" min-width="140" />
|
||||
<el-table-column
|
||||
v-if="hasConfiguredMiningAccount"
|
||||
prop="miningAccount"
|
||||
label="挖矿账户"
|
||||
min-width="140" />
|
||||
<el-table-column
|
||||
v-if="hasConfiguredWorkerId"
|
||||
prop="workerId"
|
||||
label="矿工号"
|
||||
min-width="140" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="handleConfigPrev">上一步</el-button>
|
||||
<el-button @click="handleConfigCancel">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@@ -609,6 +675,7 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleGoogleCodePrev">上一步</el-button>
|
||||
<el-button @click="handleGoogleCodeCancel">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@@ -781,11 +848,67 @@ export default {
|
||||
payCoinSymbol() {
|
||||
return (this.selectedCoin || '').toUpperCase()
|
||||
},
|
||||
// 未配置的机器列表(计算属性,避免每次渲染都重新计算导致选择状态丢失)
|
||||
// 未配置的机器列表(计算属性,根据选择的币种/算法和machineIds过滤)
|
||||
unconfiguredMachinesList() {
|
||||
const allMachines = this.configDialog.selectedMachines || []
|
||||
const configuredIds = new Set((this.configDialog.configuredMachines || []).map(m => m.id))
|
||||
return allMachines.filter(m => !configuredIds.has(m.id))
|
||||
const unconfigured = allMachines.filter(m => !configuredIds.has(m.id))
|
||||
|
||||
// 如果未选择币种/算法,返回所有未配置的机器
|
||||
const coinAlgo = Array.isArray(this.configDialog.coinAlgoValue) ? this.configDialog.coinAlgoValue : []
|
||||
if (coinAlgo.length !== 2) {
|
||||
return unconfigured
|
||||
}
|
||||
|
||||
const coin = coinAlgo[0]
|
||||
const algorithm = coinAlgo[1]
|
||||
|
||||
// 从machineSupportData中查找对应的machineIds
|
||||
const coinData = (this.machineSupportData || []).find(it => String(it && it.coin) === String(coin))
|
||||
if (!coinData) {
|
||||
return []
|
||||
}
|
||||
|
||||
const algoData = (coinData.algorithmList || []).find(a => String(a && a.algorithm) === String(algorithm))
|
||||
if (!algoData) {
|
||||
return []
|
||||
}
|
||||
|
||||
const supportedMachineIds = new Set((algoData.machineIds || []).map(id => Number(id)))
|
||||
|
||||
// 只返回在machineIds中的机器
|
||||
return unconfigured.filter(m => supportedMachineIds.has(Number(m.id)))
|
||||
},
|
||||
// 不支持的机器列表(不在当前选择的币种/算法的machineIds中)
|
||||
unsupportedMachinesList() {
|
||||
const allMachines = this.configDialog.selectedMachines || []
|
||||
const configuredIds = new Set((this.configDialog.configuredMachines || []).map(m => m.id))
|
||||
const unconfigured = allMachines.filter(m => !configuredIds.has(m.id))
|
||||
|
||||
// 如果未选择币种/算法,返回空列表
|
||||
const coinAlgo = Array.isArray(this.configDialog.coinAlgoValue) ? this.configDialog.coinAlgoValue : []
|
||||
if (coinAlgo.length !== 2) {
|
||||
return []
|
||||
}
|
||||
|
||||
const coin = coinAlgo[0]
|
||||
const algorithm = coinAlgo[1]
|
||||
|
||||
// 从machineSupportData中查找对应的machineIds
|
||||
const coinData = (this.machineSupportData || []).find(it => String(it && it.coin) === String(coin))
|
||||
if (!coinData) {
|
||||
return []
|
||||
}
|
||||
|
||||
const algoData = (coinData.algorithmList || []).find(a => String(a && a.algorithm) === String(algorithm))
|
||||
if (!algoData) {
|
||||
return []
|
||||
}
|
||||
|
||||
const supportedMachineIds = new Set((algoData.machineIds || []).map(id => Number(id)))
|
||||
|
||||
// 返回不在machineIds中的机器
|
||||
return unconfigured.filter(m => !supportedMachineIds.has(Number(m.id)))
|
||||
},
|
||||
/**
|
||||
* 检查是否可以点击按钮(计算属性,确保响应式更新)
|
||||
@@ -844,6 +967,16 @@ export default {
|
||||
const allConfigured = Array.from(allMachineIds).every(id => configuredIds.has(id))
|
||||
|
||||
return allConfigured
|
||||
},
|
||||
// 判断已配置机器中是否有挖矿账户数据
|
||||
hasConfiguredMiningAccount() {
|
||||
const configured = this.configDialog.configuredMachines || []
|
||||
return configured.some(m => m.miningAccount && String(m.miningAccount).trim().length > 0)
|
||||
},
|
||||
// 判断已配置机器中是否有矿工号数据
|
||||
hasConfiguredWorkerId() {
|
||||
const configured = this.configDialog.configuredMachines || []
|
||||
return configured.some(m => m.workerId && String(m.workerId).trim().length > 0)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -1573,8 +1706,8 @@ export default {
|
||||
|
||||
// 构建订单信息列表 orderInfoVoList
|
||||
const orderInfoVoList = []
|
||||
// 构建挖矿配置列表 orderMiningInfoDtoList(按 coinConfigId 分组)
|
||||
const miningConfigMap = new Map() // key: coinConfigId, value: { coinConfigId, poolName, poolUser, walletAddress, walletMining, workerId, machineIds: [] }
|
||||
// 构建挖矿配置列表 orderMiningInfoDtoList(每台机器一个配置项,使用 machineId 字符串)
|
||||
const orderMiningInfoDtoList = []
|
||||
|
||||
// 处理单店铺或多店铺的机器
|
||||
const allMachines = []
|
||||
@@ -1595,7 +1728,7 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
// 构建订单信息列表和挖矿配置映射
|
||||
// 构建订单信息列表和挖矿配置列表
|
||||
allMachines.forEach(({ shop, machine }) => {
|
||||
const sel = this.paySelectionMap[shop.id] || ''
|
||||
const [chain, coin] = String(sel).split('|')
|
||||
@@ -1618,32 +1751,29 @@ export default {
|
||||
shopId: shop.id
|
||||
})
|
||||
|
||||
// 按 coinConfigId 分组构建挖矿配置
|
||||
// 为每台机器单独创建挖矿配置项,使用 machineId(string)而不是 machineIds(array)
|
||||
const coinConfigId = config.coinConfigId
|
||||
if (!coinConfigId) {
|
||||
console.warn(`机器 ${machine.id} 的 coinConfigId 为空`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!miningConfigMap.has(coinConfigId)) {
|
||||
miningConfigMap.set(coinConfigId, {
|
||||
coinConfigId: coinConfigId,
|
||||
poolName: config.poolName || '',
|
||||
poolUser: config.miningAccount || '',
|
||||
walletAddress: config.walletAddress || '',
|
||||
walletMining: config.walletMining || '',
|
||||
workerId: config.workerId || '',
|
||||
machineIds: []
|
||||
})
|
||||
}
|
||||
const walletAddress = String(config.walletAddress || '').trim()
|
||||
const poolUser = String(config.miningAccount || '').trim()
|
||||
const workerId = String(config.workerId || '').trim()
|
||||
|
||||
const miningConfig = miningConfigMap.get(coinConfigId)
|
||||
miningConfig.machineIds.push(machine.id)
|
||||
// 为每台机器创建独立的配置项
|
||||
orderMiningInfoDtoList.push({
|
||||
coinConfigId: coinConfigId,
|
||||
poolName: config.poolName || '',
|
||||
poolUser: poolUser,
|
||||
walletAddress: walletAddress,
|
||||
walletMining: config.walletMining || false,
|
||||
workerId: workerId,
|
||||
machineId: String(machine.id) // 使用 machineId(string)而不是 machineIds(array)
|
||||
})
|
||||
})
|
||||
|
||||
// 转换为数组
|
||||
const orderMiningInfoDtoList = Array.from(miningConfigMap.values())
|
||||
|
||||
this.creatingOrder = true
|
||||
try {
|
||||
const res = await this.fetchAddOrdersV2(orderInfoVoList, orderMiningInfoDtoList, googleCode)
|
||||
@@ -1710,7 +1840,7 @@ export default {
|
||||
this.$message({ message: '未找到可结算的上架机器', type: 'warning', showClose: true })
|
||||
return
|
||||
}
|
||||
// 在点击“结算选中机器”时请求币种/算法支持数据
|
||||
// 在点击"结算选中机器"时请求币种/算法支持数据
|
||||
try {
|
||||
const ids = []
|
||||
picked.forEach(({ items }) => {
|
||||
@@ -1720,8 +1850,24 @@ export default {
|
||||
})
|
||||
if (ids.length) {
|
||||
await this.fetchGetMachineSupportCoinAndAlgorithm(ids)
|
||||
// 检查是否获取到数据
|
||||
if (!this.machineSupportData || this.machineSupportData.length === 0) {
|
||||
this.$message({
|
||||
message: '加载配置信息失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e) { /* noop */ }
|
||||
} catch (e) {
|
||||
this.$message({
|
||||
message: '加载配置信息失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
this.pendingCheckoutAll = picked
|
||||
// 打开须知弹窗
|
||||
this.noticeDialog.visible = true
|
||||
@@ -1774,6 +1920,12 @@ export default {
|
||||
this.confirmDialog.visible = false
|
||||
this.showGoogleCodeDialog()
|
||||
},
|
||||
// 确认结算弹窗的上一步:返回到配置弹窗
|
||||
handleConfirmDialogPrev() {
|
||||
this.confirmDialog.visible = false
|
||||
// 重新打开配置弹窗
|
||||
this.configDialog.visible = true
|
||||
},
|
||||
// 关闭成功弹窗:跳转到订单列表的订单进行中状态
|
||||
handleCloseSuccessDialog() {
|
||||
try { this.settlementSuccessfulVisible = false } catch (e) { /* noop */ }
|
||||
@@ -1813,6 +1965,15 @@ export default {
|
||||
},
|
||||
// 打开配置弹窗并初始化选项与机器列表
|
||||
openConfigDialog() {
|
||||
// 检查是否获取到配置数据
|
||||
if (!this.machineSupportData || this.machineSupportData.length === 0) {
|
||||
this.$message({
|
||||
message: '加载配置信息失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
// 重置已配置列表
|
||||
this.configDialog.configuredMachines = []
|
||||
// 初始化币种选项
|
||||
@@ -1831,21 +1992,10 @@ export default {
|
||||
value: a && a.algorithm ? String(a.algorithm) : ''
|
||||
})) : []
|
||||
}))
|
||||
// 默认选中第一个币种
|
||||
if (!this.configDialog.coin && coinOptions.length) {
|
||||
this.configDialog.coin = coinOptions[0].value
|
||||
}
|
||||
// 默认算法为该币种下第一个
|
||||
try {
|
||||
const firstCoin = (coins && coins.length) ? coins[0] : null
|
||||
const firstAlgo = firstCoin && Array.isArray(firstCoin.algorithmList) && firstCoin.algorithmList.length
|
||||
? (firstCoin.algorithmList[0].algorithm || '')
|
||||
: ''
|
||||
if (!this.configDialog.algorithm) this.configDialog.algorithm = firstAlgo
|
||||
this.configDialog.coinAlgoValue = [this.configDialog.coin, this.configDialog.algorithm].filter(Boolean)
|
||||
} catch (e) { /* noop */ }
|
||||
// 根据币种初始化算法选项
|
||||
this.refreshAlgorithmOptions()
|
||||
// 不默认选择币种和算法,等用户自己选择
|
||||
this.$set(this.configDialog, 'coin', '')
|
||||
this.$set(this.configDialog, 'algorithm', '')
|
||||
this.$set(this.configDialog, 'coinAlgoValue', [])
|
||||
// 构建展示用机器列表
|
||||
this.configDialog.selectedMachines = this.buildSelectedMachinesForConfig()
|
||||
// 重置选择状态
|
||||
@@ -1855,12 +2005,9 @@ export default {
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
this.$set(this.configDialog, 'workerId', '')
|
||||
this.$set(this.configDialog, 'poolValue', [])
|
||||
// 同步加载矿池/模型下拉
|
||||
try {
|
||||
if (this.configDialog.coin && this.configDialog.algorithm) {
|
||||
this.fetchGetMachineSupportPool(this.configDialog.coin, this.configDialog.algorithm)
|
||||
}
|
||||
} catch (e) { /* noop */ }
|
||||
// 重置矿池选项
|
||||
this.$set(this.configDialog, 'poolOptions', [])
|
||||
this.$set(this.configDialog, 'poolRawData', [])
|
||||
// 打开弹窗
|
||||
this.configDialog.visible = true
|
||||
},
|
||||
@@ -1915,10 +2062,20 @@ export default {
|
||||
this.$set(this.configDialog, 'coin', coin)
|
||||
this.$set(this.configDialog, 'algorithm', algo)
|
||||
this.$set(this.configDialog, 'coinAlgoValue', arr)
|
||||
// 强制触发视图更新
|
||||
// 清空表格选择状态
|
||||
this.$set(this.configDialog, 'selectedMachineIds', [])
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
const tb = this.$refs.configTable
|
||||
if (tb && typeof tb.clearSelection === 'function') {
|
||||
tb.clearSelection()
|
||||
}
|
||||
} catch (e) { /* noop */ }
|
||||
this.$forceUpdate()
|
||||
})
|
||||
// 清空统一输入框和矿池/模型选择
|
||||
this.$set(this.configDialog, 'walletAddress', '')
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
if (coin && algo) {
|
||||
this.fetchGetMachineSupportPool(coin, algo)
|
||||
} else {
|
||||
@@ -1930,11 +2087,95 @@ export default {
|
||||
// 矿池/模型选择变化
|
||||
handlePoolValueChange(val) {
|
||||
this.$set(this.configDialog, 'poolValue', val || [])
|
||||
// 获取当前选择的矿池/模型的 walletMining 值
|
||||
const poolValue = Array.isArray(val) ? val : []
|
||||
if (poolValue.length === 2) {
|
||||
const poolId = poolValue[0]
|
||||
const coinConfigId = poolValue[1]
|
||||
const poolOption = (this.configDialog.poolOptions || []).find(p => p.value === poolId)
|
||||
if (poolOption) {
|
||||
const modelOption = (poolOption.children || []).find(m => m.value === coinConfigId)
|
||||
if (modelOption && modelOption.raw) {
|
||||
const walletMining = modelOption.raw.walletMining || false
|
||||
// 清空统一输入框
|
||||
this.$set(this.configDialog, 'walletAddress', '')
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
// 清空所有未配置机器的矿工号
|
||||
const unconfigured = this.unconfiguredMachinesList
|
||||
unconfigured.forEach(machine => {
|
||||
this.$set(machine, '_walletMining', walletMining)
|
||||
this.$set(machine, '_workerId', '')
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果未选择矿池/模型,清空统一输入框
|
||||
this.$set(this.configDialog, 'walletAddress', '')
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
}
|
||||
// 强制触发视图更新
|
||||
this.$nextTick(() => {
|
||||
this.$forceUpdate()
|
||||
})
|
||||
},
|
||||
// 获取当前选择的矿池/模型的 walletMining 值
|
||||
getCurrentWalletMining() {
|
||||
const poolValue = Array.isArray(this.configDialog.poolValue) ? this.configDialog.poolValue : []
|
||||
if (poolValue.length !== 2) {
|
||||
return null
|
||||
}
|
||||
const poolId = poolValue[0]
|
||||
const coinConfigId = poolValue[1]
|
||||
const poolOption = (this.configDialog.poolOptions || []).find(p => p.value === poolId)
|
||||
if (poolOption) {
|
||||
const modelOption = (poolOption.children || []).find(m => m.value === coinConfigId)
|
||||
if (modelOption && modelOption.raw) {
|
||||
return modelOption.raw.walletMining || false
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
// 处理机器钱包地址输入
|
||||
handleMachineWalletAddressInput(machine, val) {
|
||||
if (!val) {
|
||||
this.$set(machine, '_walletAddress', '')
|
||||
return
|
||||
}
|
||||
// 只过滤中文字符,其他字符都可以输入
|
||||
// 匹配中文字符范围:\u4e00-\u9fa5 (基本汉字), \u3400-\u4dbf (扩展A), \u3000-\u303f (CJK符号和标点), \uff00-\uffef (全角字符)
|
||||
let filtered = val.replace(/[\u4e00-\u9fa5\u3400-\u4dbf\u3000-\u303f\uff00-\uffef]/g, '')
|
||||
// 限制最大长度95
|
||||
if (filtered.length > 95) {
|
||||
filtered = filtered.substring(0, 95)
|
||||
}
|
||||
this.$set(machine, '_walletAddress', filtered)
|
||||
},
|
||||
// 处理机器挖矿账户输入
|
||||
handleMachineMiningAccountInput(machine, val) {
|
||||
if (!val) {
|
||||
this.$set(machine, '_miningAccount', '')
|
||||
return
|
||||
}
|
||||
// 只限制最大长度40,不限制其他输入
|
||||
let filtered = String(val)
|
||||
if (filtered.length > 40) {
|
||||
filtered = filtered.substring(0, 40)
|
||||
}
|
||||
this.$set(machine, '_miningAccount', filtered)
|
||||
},
|
||||
// 处理机器矿工号输入
|
||||
handleMachineWorkerIdInput(machine, val) {
|
||||
if (!val) {
|
||||
this.$set(machine, '_workerId', '')
|
||||
return
|
||||
}
|
||||
// 只限制最大长度40,不限制其他输入
|
||||
let filtered = String(val)
|
||||
if (filtered.length > 40) {
|
||||
filtered = filtered.substring(0, 40)
|
||||
}
|
||||
this.$set(machine, '_workerId', filtered)
|
||||
},
|
||||
// 钱包地址输入(过滤中文,限制长度26-95)
|
||||
handleWalletAddressInput(val) {
|
||||
if (!val) {
|
||||
@@ -2095,8 +2336,6 @@ export default {
|
||||
// 验证表单完整性
|
||||
const coinAlgo = Array.isArray(this.configDialog.coinAlgoValue) ? this.configDialog.coinAlgoValue : []
|
||||
const pool = Array.isArray(this.configDialog.poolValue) ? this.configDialog.poolValue : []
|
||||
const wallet = String(this.configDialog.walletAddress || '').trim()
|
||||
const account = String(this.configDialog.miningAccount || '').trim()
|
||||
|
||||
if (coinAlgo.length !== 2) {
|
||||
this.$message.warning('请选择币种和算法')
|
||||
@@ -2108,22 +2347,6 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
if (!wallet || wallet.length === 0) {
|
||||
this.$message.warning('请输入钱包地址')
|
||||
return
|
||||
}
|
||||
|
||||
// 验证钱包地址长度(26-95个字符)
|
||||
if (wallet.length < 26 || wallet.length > 95) {
|
||||
this.$message.warning('钱包地址长度应在26-95个字符之间')
|
||||
return
|
||||
}
|
||||
|
||||
if (!account || account.length === 0) {
|
||||
this.$message.warning('请输入挖矿账户')
|
||||
return
|
||||
}
|
||||
|
||||
// 获取选中的机器(使用上面验证时获取的 selectedIds)
|
||||
const selectedMachines = unconfigured.filter(m =>
|
||||
selectedIds.includes(m.id)
|
||||
@@ -2134,7 +2357,7 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取矿池和模型名称
|
||||
// 获取矿池和模型名称以及 walletMining
|
||||
const poolValue = this.configDialog.poolValue || []
|
||||
const poolId = poolValue[0]
|
||||
const coinConfigId = poolValue[1]
|
||||
@@ -2142,7 +2365,7 @@ export default {
|
||||
// 从 poolOptions 中查找名称和原始数据
|
||||
let poolName = ''
|
||||
let modelName = ''
|
||||
let walletMining = ''
|
||||
let walletMining = false
|
||||
const poolOption = (this.configDialog.poolOptions || []).find(p => p.value === poolId)
|
||||
if (poolOption) {
|
||||
poolName = poolOption.label || ''
|
||||
@@ -2150,13 +2373,47 @@ export default {
|
||||
if (modelOption && modelOption.raw) {
|
||||
modelName = modelOption.label || ''
|
||||
// 从原始数据中获取 walletMining
|
||||
walletMining = modelOption.raw.walletMining || ''
|
||||
walletMining = modelOption.raw.walletMining || false
|
||||
}
|
||||
}
|
||||
|
||||
// 验证统一输入字段
|
||||
if (walletMining) {
|
||||
// 支持钱包地址挖矿,需要验证钱包地址
|
||||
const wallet = String(this.configDialog.walletAddress || '').trim()
|
||||
if (!wallet || wallet.length === 0) {
|
||||
this.$message.warning('请输入钱包地址')
|
||||
return
|
||||
}
|
||||
// 验证钱包地址长度(26-95个字符)
|
||||
if (wallet.length < 26 || wallet.length > 95) {
|
||||
this.$message.warning('钱包地址长度应在26-95个字符之间')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// 不支持钱包地址挖矿,需要验证挖矿账户
|
||||
const account = String(this.configDialog.miningAccount || '').trim()
|
||||
if (!account || account.length === 0) {
|
||||
this.$message.warning('请输入挖矿账户')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 验证每台机器的矿工号
|
||||
for (const machine of selectedMachines) {
|
||||
const workerId = String(machine._workerId || '').trim()
|
||||
if (!workerId || workerId.length === 0) {
|
||||
this.$message.warning(`机器ID ${machine.id} 请输入矿工号`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 保存配置(使用上面已经验证过的 coinAlgo)
|
||||
const coin = this.toUpperText(coinAlgo[0] || '')
|
||||
const algorithm = String(coinAlgo[1] || '')
|
||||
// 统一输入框的值
|
||||
const walletAddress = walletMining ? String(this.configDialog.walletAddress || '').trim() : ''
|
||||
const miningAccount = walletMining ? '' : String(this.configDialog.miningAccount || '').trim()
|
||||
|
||||
selectedMachines.forEach(machine => {
|
||||
this.configDialog.configuredMachines.push({
|
||||
@@ -2165,9 +2422,9 @@ export default {
|
||||
algorithm: algorithm,
|
||||
poolName: poolName,
|
||||
modelName: modelName,
|
||||
walletAddress: String(this.configDialog.walletAddress || '').trim(),
|
||||
miningAccount: String(this.configDialog.miningAccount || '').trim(),
|
||||
workerId: String(this.configDialog.workerId || '').trim(),
|
||||
walletAddress: walletAddress,
|
||||
miningAccount: miningAccount,
|
||||
workerId: String(machine._workerId || '').trim(), // 矿工号从每行获取
|
||||
walletMining: walletMining,
|
||||
type: machine.type,
|
||||
// 保存原始数据用于后续提交
|
||||
@@ -2179,15 +2436,66 @@ export default {
|
||||
})
|
||||
})
|
||||
|
||||
// 计算剩下待配置的机器ID
|
||||
const allMachineIds = new Set((this.configDialog.selectedMachines || []).map(m => m.id))
|
||||
const configuredIds = new Set((this.configDialog.configuredMachines || []).map(m => m.id))
|
||||
const remainingMachineIds = Array.from(allMachineIds).filter(id => !configuredIds.has(id))
|
||||
|
||||
// 如果有待配置的机器,重新请求币种/算法支持数据
|
||||
if (remainingMachineIds.length > 0) {
|
||||
this.fetchGetMachineSupportCoinAndAlgorithm(remainingMachineIds).then(() => {
|
||||
// 检查是否获取到数据
|
||||
if (!this.machineSupportData || this.machineSupportData.length === 0) {
|
||||
this.$message({
|
||||
message: '加载配置信息失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
// 更新币种/算法选项
|
||||
const coins = Array.isArray(this.machineSupportData) ? this.machineSupportData : []
|
||||
this.configDialog.coinAlgoOptions = (coins || []).map(c => ({
|
||||
label: this.toUpperText(c && c.coin),
|
||||
value: c && c.coin,
|
||||
children: Array.isArray(c && c.algorithmList) ? c.algorithmList.map(a => ({
|
||||
label: a && a.algorithm ? String(a.algorithm) : '',
|
||||
value: a && a.algorithm ? String(a.algorithm) : ''
|
||||
})) : []
|
||||
}))
|
||||
// 如果更新后没有选项,清空选项
|
||||
if (this.configDialog.coinAlgoOptions.length === 0) {
|
||||
this.configDialog.coinAlgoOptions = []
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error('重新获取币种/算法支持数据失败:', e)
|
||||
this.$message({
|
||||
message: '加载配置信息失败,请重试',
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// 如果没有待配置的机器,清空币种/算法选项
|
||||
this.configDialog.coinAlgoOptions = []
|
||||
}
|
||||
|
||||
// 清空当前输入,准备下一批配置
|
||||
this.$set(this.configDialog, 'selectedMachineIds', [])
|
||||
this.$set(this.configDialog, 'walletAddress', '')
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
this.$set(this.configDialog, 'workerId', '')
|
||||
this.$set(this.configDialog, 'poolValue', [])
|
||||
this.$set(this.configDialog, 'coinAlgoValue', [])
|
||||
this.$set(this.configDialog, 'coin', '')
|
||||
this.$set(this.configDialog, 'algorithm', '')
|
||||
// 清空统一输入框
|
||||
this.$set(this.configDialog, 'walletAddress', '')
|
||||
this.$set(this.configDialog, 'miningAccount', '')
|
||||
|
||||
// 清空所有未配置机器的矿工号
|
||||
const remainingUnconfigured = this.unconfiguredMachinesList
|
||||
remainingUnconfigured.forEach(machine => {
|
||||
this.$set(machine, '_workerId', '')
|
||||
this.$set(machine, '_walletMining', null)
|
||||
})
|
||||
|
||||
// 清空表格选择
|
||||
this.$nextTick(() => {
|
||||
@@ -2254,6 +2562,14 @@ export default {
|
||||
// 恢复勾选状态
|
||||
this.reapplySelectionsForPendingShop()
|
||||
},
|
||||
// 配置弹窗的上一步:返回到下单须知弹窗
|
||||
handleConfigPrev() {
|
||||
this.configDialog.visible = false
|
||||
// 重新打开下单须知弹窗
|
||||
this.noticeDialog.visible = true
|
||||
this.noticeDialog.checked = false
|
||||
this.startNoticeCountdown()
|
||||
},
|
||||
openPaySelectDialog() {
|
||||
// 已取消支付方式选择步骤,此函数保留空实现以兼容旧调用
|
||||
return
|
||||
@@ -2466,6 +2782,19 @@ export default {
|
||||
this.reapplySelectionsForPendingShop()
|
||||
this.pendingCheckoutShop = null
|
||||
},
|
||||
// 谷歌验证码弹窗的上一步:返回到确认结算弹窗
|
||||
handleGoogleCodePrev() {
|
||||
this.googleCodeDialog.visible = false
|
||||
this.googleCodeDialog.code = ''
|
||||
this.googleCodeDialog.error = ''
|
||||
this.googleCodeDialog.loading = false
|
||||
// 重新打开确认结算弹窗
|
||||
if (this.pendingCheckoutAll && this.pendingCheckoutAll.length) {
|
||||
this.showConfirmDialogAll()
|
||||
} else {
|
||||
this.showConfirmDialog()
|
||||
}
|
||||
},
|
||||
// 处理租赁天数输入变化
|
||||
handleLeaseTimeChange(machine) {
|
||||
// 确保租赁天数是大于等于1的整数
|
||||
|
||||
@@ -435,23 +435,54 @@ export default {
|
||||
*/
|
||||
hasAnyPrice(row) {
|
||||
try {
|
||||
if (!row) return false
|
||||
if (!row) {
|
||||
console.log('[hasAnyPrice] 行数据为空')
|
||||
return false
|
||||
}
|
||||
if (Array.isArray(row.priceList) && row.priceList.length) {
|
||||
return row.priceList.some(it => it && it.price !== null && it.price !== undefined)
|
||||
const hasValidPrice = row.priceList.some(it => it && it.price !== null && it.price !== undefined)
|
||||
if (!hasValidPrice) {
|
||||
console.log(`[hasAnyPrice] 机器ID ${row.id || 'unknown'} priceList 中无有效价格:`, row.priceList)
|
||||
}
|
||||
return hasValidPrice
|
||||
}
|
||||
const v = row.price
|
||||
return v !== null && v !== undefined && v !== ''
|
||||
} catch (e) { return false }
|
||||
const hasPrice = v !== null && v !== undefined && v !== ''
|
||||
if (!hasPrice) {
|
||||
console.log(`[hasAnyPrice] 机器ID ${row.id || 'unknown'} row.price 无效:`, v)
|
||||
}
|
||||
return hasPrice
|
||||
} catch (e) {
|
||||
console.error('[hasAnyPrice] 异常:', e, row)
|
||||
return false
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 该行是否应禁用选择:已售出/售出中 或 无价格
|
||||
*/
|
||||
isRowDisabled(row) {
|
||||
try {
|
||||
if (!row) return true
|
||||
if (row.saleState === 1 || row.saleState === 2) return true
|
||||
return !this.hasAnyPrice(row)
|
||||
} catch (e) { return true }
|
||||
if (!row) {
|
||||
console.log('[isRowDisabled] 行数据为空')
|
||||
return true
|
||||
}
|
||||
if (row.saleState === 1 || row.saleState === 2) {
|
||||
console.log(`[isRowDisabled] 机器ID ${row.id || 'unknown'} 已售出或售出中, saleState:`, row.saleState)
|
||||
return true
|
||||
}
|
||||
const hasPrice = this.hasAnyPrice(row)
|
||||
if (!hasPrice) {
|
||||
console.log(`[isRowDisabled] 机器ID ${row.id || 'unknown'} 无价格:`, {
|
||||
priceList: row.priceList,
|
||||
price: row.price,
|
||||
hasPriceList: Array.isArray(row.priceList) && row.priceList.length > 0
|
||||
})
|
||||
}
|
||||
return !hasPrice
|
||||
} catch (e) {
|
||||
console.error('[isRowDisabled] 异常:', e, row)
|
||||
return true
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取行的最大可租赁天数
|
||||
|
||||
Reference in New Issue
Block a user