计算持仓合计

This commit is contained in:
tony 2026-07-24 23:02:25 +08:00
parent a628313e9a
commit bb9d01bdf6
2 changed files with 82 additions and 14 deletions

View File

@ -1,12 +1,20 @@
<template>
<el-table :data="list" size="small" stripe class="pos-table" max-height="320">
<el-table
:data="list"
size="small"
stripe
class="pos-table"
max-height="320"
show-summary
:summary-method="getSummaries"
>
<el-table-column prop="rank" label="名次" width="56" />
<el-table-column prop="name" label="会员简称" min-width="110" />
<el-table-column :prop="String(qtyKey)" :label="qtyLabel" min-width="90" />
<el-table-column label="增减" min-width="80">
<el-table-column prop="change" label="增减" min-width="80">
<template #default="{ row }">
<span :class="row.change >= 0 ? 'price-up' : 'chg-down'">
{{ row.change > 0 ? '+' : '' }}{{ row.change }}
{{ formatChange(row.change) }}
</span>
</template>
</el-table-column>
@ -16,7 +24,7 @@
<script setup lang="ts">
import type { PositionRow } from '../../types'
withDefaults(
const props = withDefaults(
defineProps<{
list: PositionRow[]
qtyKey?: keyof PositionRow
@ -27,6 +35,30 @@ withDefaults(
qtyLabel: '数量',
},
)
function formatChange(n: number): string {
return `${n > 0 ? '+' : ''}${n}`
}
function getSummaries(param: {
columns: { property?: string }[]
data: PositionRow[]
}): string[] {
const { columns, data } = param
const qtyTotal = data.reduce((acc, row) => acc + Number(row[props.qtyKey] ?? 0), 0)
const changeTotal = data.reduce((acc, row) => acc + Number(row.change ?? 0), 0)
return columns.map((column) => {
if (column.property === 'name') return '合计'
if (column.property === String(props.qtyKey)) {
return String(qtyTotal)
}
if (column.property === 'change') {
return formatChange(changeTotal)
}
return ''
})
}
</script>
<style scoped>
@ -34,6 +66,11 @@ withDefaults(
width: 100%;
}
.pos-table :deep(.el-table__footer-wrapper td) {
font-weight: 600;
background: var(--el-fill-color-light, #f5f7fa);
}
.chg-down {
color: var(--short);
}

View File

@ -1,23 +1,27 @@
<template>
<el-table :data="list" size="small" stripe class="profit-table" max-height="360">
<el-table
:data="list"
size="small"
stripe
class="profit-table"
max-height="360"
show-summary
:summary-method="getSummaries"
>
<el-table-column prop="rank" label="名次" width="56" />
<el-table-column prop="name" label="会员简称" min-width="110" />
<el-table-column label="盈利金额" min-width="120">
<el-table-column prop="profit" label="盈利金额" min-width="120">
<template #default="{ row }">
<span :class="row.profit >= 0 ? 'price-up' : 'price-down'">
{{ formatProfit(row.profit) }}
</span>
</template>
</el-table-column>
<el-table-column label="净持仓" min-width="90">
<template #default="{ row }">
{{ row.netQty }}
</template>
</el-table-column>
<el-table-column label="增减" min-width="80">
<el-table-column prop="netQty" label="净持仓" min-width="90" />
<el-table-column prop="change" label="增减" min-width="80">
<template #default="{ row }">
<span :class="row.change >= 0 ? 'price-up' : 'chg-down'">
{{ row.change > 0 ? '+' : '' }}{{ row.change }}
{{ formatChange(row.change) }}
</span>
</template>
</el-table-column>
@ -44,6 +48,28 @@ function formatProfit(n: number): string {
}
return `${sign}${abs.toFixed(0)}`
}
function formatChange(n: number): string {
return `${n > 0 ? '+' : ''}${n}`
}
function getSummaries(param: {
columns: { property?: string }[]
data: ProfitRow[]
}): string[] {
const { columns, data } = param
const profitTotal = data.reduce((acc, row) => acc + Number(row.profit ?? 0), 0)
const netQtyTotal = data.reduce((acc, row) => acc + Number(row.netQty ?? 0), 0)
const changeTotal = data.reduce((acc, row) => acc + Number(row.change ?? 0), 0)
return columns.map((column) => {
if (column.property === 'name') return '合计'
if (column.property === 'profit') return formatProfit(profitTotal)
if (column.property === 'netQty') return String(netQtyTotal)
if (column.property === 'change') return formatChange(changeTotal)
return ''
})
}
</script>
<style scoped>
@ -51,6 +77,11 @@ function formatProfit(n: number): string {
width: 100%;
}
.profit-table :deep(.el-table__footer-wrapper td) {
font-weight: 600;
background: var(--el-fill-color-light, #f5f7fa);
}
.chg-down {
color: var(--short);
}