添加了起付额判定

This commit is contained in:
2025-11-18 14:36:43 +08:00
parent 50e5ce8d08
commit c7cee78798
4 changed files with 66 additions and 17 deletions

View File

@@ -326,7 +326,7 @@ export default {
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; padding: 8px 4px; }
.detail-item { display: grid; grid-template-columns: 90px 1fr; align-items: center; gap: 8px; }
.detail-item-full { grid-column: 1 / -1; }
.detail-label { color: #666; font-size: 13px; text-align: right; }
.detail-label { color: #666; font-size: 13px; text-align: left; }
.detail-value { color: #333; font-size: 13px; text-align: left; }
.detail-value.address { font-family: "Monaco", "Menlo", monospace; word-break: break-all; }

View File

@@ -216,6 +216,22 @@
店铺:{{ grp.shopName || grp.shopId }}
<span style="margin-left:12px;color:#666;font-weight:400;">支付方式:{{ grp.payLabel }}</span>
</div>
<div>
<template v-if="grp.coinSymbol">
<span v-if="grp.enough"
style="color:#16a34a;font-weight:600;">
已满足起付额
{{ formatAmount(grp.deductibleAmount || 0, grp.coinSymbol).text }}
</span>
<span v-else
style="color:#ef4444;font-weight:600;">
金额不足最低起付额
{{ formatAmount(grp.deductibleAmount || 0, grp.coinSymbol).text }}
,收取手续费
{{ formatAmount(grp.fee || 0, grp.coinSymbol).text }}
</span>
</template>
</div>
</div>
<el-table :data="grp.items" max-height="260" border stripe
:header-cell-style="{ textAlign: 'left' }" :cell-style="{ textAlign: 'left' }">
@@ -609,22 +625,16 @@ export default {
getAllGroups() { return [] },
// 生成店铺的支付方式选项,基于 totalPriceList
getShopPayOptions(shop) {
const list = Array.isArray(shop && shop.totalPriceList) ? shop.totalPriceList : []
// 优先使用 payConfigList 提供的 icon以链+币种去匹配
const icons = new Map()
// 下拉渲染严格以 payConfigList 为准(接口定义的可选支付方式)
const cfg = Array.isArray(shop && shop.payConfigList) ? shop.payConfigList : []
cfg.forEach(c => {
const key = `${c.payChain || ''}|${c.payCoin || ''}`
icons.set(key, c.payCoinImage || '')
})
return list.map(it => {
const chain = (it && it.chain) || ''
const coin = (it && it.coin) || ''
return cfg.map(c => {
const chain = c && c.payChain ? String(c.payChain) : ''
const coin = c && c.payCoin ? String(c.payCoin) : ''
const key = `${chain}|${coin}`
return {
label: `${chain} - ${this.toUpperText(coin)}`,
value: key,
icon: icons.get(key) || ''
icon: c && c.payCoinImage ? c.payCoinImage : ''
}
})
},
@@ -1317,12 +1327,24 @@ export default {
const [chain, coin] = String(key).split('|')
const coinSymbol = this.toUpperText(coin || '')
const payLabel = `${chain} - ${coinSymbol}`
// 当前支付方式配置(起付额/手续费)
const cfgList = Array.isArray(shop && shop.payConfigList) ? shop.payConfigList : []
const cfgHit = cfgList.find(c => String(c && c.payChain).toUpperCase() === String(chain).toUpperCase()
&& String(c && c.payCoin).toUpperCase() === String(coin).toUpperCase())
const deductibleAmount = Number((cfgHit && cfgHit.deductibleAmount) || 0)
const fee = Number((cfgHit && cfgHit.fee) || 0)
const groupSubtotal = items.reduce((sum, it) => sum + Number(it.subtotal || 0), 0)
const enough = groupSubtotal >= deductibleAmount || deductibleAmount <= 0
const grp = {
shopId: shop.id,
shopName: shop.name || '',
coinSymbol,
payLabel,
items
items,
deductibleAmount,
fee,
enough,
groupSubtotal
}
this.confirmDialog.shops = [grp]
this.confirmDialog.count = items.length
@@ -1330,7 +1352,9 @@ export default {
const totals = {}
const centsAdd = (acc, v) => (acc + this.toCents(v))
if (coinSymbol) {
const tCents = items.reduce((acc, it) => centsAdd(acc, it.subtotal || 0), 0)
let tCents = items.reduce((acc, it) => centsAdd(acc, it.subtotal || 0), 0)
// 若未满足起付额,合计中加入手续费
if (!enough && fee > 0) tCents = tCents + this.toCents(fee)
totals[coinSymbol] = Number(this.centsToText(tCents))
}
this.confirmDialog.totalsByCoin = totals
@@ -1350,8 +1374,14 @@ export default {
const [chain, coin] = String(key).split('|')
const coinSymbol = this.toUpperText(coin || '')
const payLabel = `${chain} - ${coinSymbol}`
const cfgList = Array.isArray(shop && shop.payConfigList) ? shop.payConfigList : []
const cfgHit = cfgList.find(c => String(c && c.payChain).toUpperCase() === String(chain).toUpperCase()
&& String(c && c.payCoin).toUpperCase() === String(coin).toUpperCase())
const deductibleAmount = Number((cfgHit && cfgHit.deductibleAmount) || 0)
const fee = Number((cfgHit && cfgHit.fee) || 0)
const rows = []
const list = Array.isArray(shop.productMachineDtoList) ? shop.productMachineDtoList : []
let groupSubtotal = 0
list.forEach(m => {
if (!set.has(m.id) || !this.isOnShelf(m)) return
const baseUnit = this.getMachineUnitPriceBySelection(shop, m)
@@ -1368,17 +1398,28 @@ export default {
leaseTime: leaseDays,
subtotal
})
groupSubtotal += subtotal
const prev = totalsCentsByCoin.get(coinSymbol) || 0
totalsCentsByCoin.set(coinSymbol, prev + this.toCents(subtotal))
count += 1
})
if (rows.length) {
const enough = groupSubtotal >= deductibleAmount || deductibleAmount <= 0
// 未满足起付额:总额加上手续费
if (!enough && fee > 0) {
const prev = totalsCentsByCoin.get(coinSymbol) || 0
totalsCentsByCoin.set(coinSymbol, prev + this.toCents(fee))
}
groups.push({
shopId: shop.id,
shopName: shop.name || '',
coinSymbol,
payLabel,
items: rows
items: rows,
deductibleAmount,
fee,
enough,
groupSubtotal
})
}
})

View File

@@ -27,8 +27,11 @@ export default {
minPower: null,
maxPower: null,
minPowerDissipation: null,
maxPowerDissipation: null
maxPowerDissipation: null,
unit: 'GH/S'
},
// 实际算力单位选项
powerUnitOptions: ['KH/S', 'MH/S', 'GH/S', 'TH/S', 'PH/S'],
// 排序状态true 升序false 降序
sortStates: {
priceSort: true,
@@ -228,6 +231,7 @@ export default {
// 支付方式条件:有值才传
if (this.filters.chain && String(this.filters.chain).trim()) q.chain = String(this.filters.chain).trim()
if (this.filters.coin && String(this.filters.coin).trim()) q.coin = String(this.filters.coin).trim()
if (this.filters.unit && String(this.filters.unit).trim()) q.unit = String(this.filters.unit).trim()
addNum(this.filters, 'minPrice', 'minPrice')
addNum(this.filters, 'maxPrice', 'maxPrice')
addNum(this.filters, 'minPower', 'minPower')

View File

@@ -87,6 +87,9 @@
<el-input-number v-model="filters.minPower" :min="0" :step="0.1" :precision="2" :controls="false" size="small" class="filter-control" />
<span class="filter-sep">-</span>
<el-input-number v-model="filters.maxPower" :min="0" :step="0.1" :precision="2" :controls="false" size="small" class="filter-control" />
<el-select v-model="filters.unit" placeholder="单位" size="small" class="filter-control" style="max-width: 140px;">
<el-option v-for="u in powerUnitOptions" :key="u" :label="u" :value="u" />
</el-select>
</div>
</div>
@@ -375,7 +378,8 @@ export default {
minPower: null,
maxPower: null,
minPowerDissipation: null,
maxPowerDissipation: null
maxPowerDissipation: null,
unit: 'GH/S'
}
this.handleSearchFilters()
},