调整抢单页面的风格。

This commit is contained in:
zhonghua.li
2026-06-12 00:08:40 +08:00
parent 8b17dff25b
commit 7800d4f268
2 changed files with 387 additions and 125 deletions

View File

@@ -1,14 +1,33 @@
<template>
<div class="app-container">
<el-card class="filter-container" shadow="never">
<el-form :model="queryParams" :inline="true" label-width="100px">
<el-form-item label="租户ID">
<el-form :model="queryParams" :inline="true" label-width="100px" class="filter-form-row">
<el-form-item class="filter-form-actions">
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button
type="warning"
icon="el-icon-refresh"
:loading="syncLoading"
@click="handleSyncFromHxr"
>
同步货品
</el-button>
<el-button
type="danger"
icon="el-icon-shopping-cart-full"
:loading="rushBuyLoading"
:disabled="!multipleSelection.length"
@click="handleRushBuy"
>
开始抢单
</el-button>
</el-form-item>
<el-form-item label="租户ID" class="filter-form-field">
<el-select
v-model="queryParams.tenantId"
filterable
clearable
placeholder="请选择租户"
style="width: 220px"
:loading="tenantLoading"
>
<el-option
@@ -19,116 +38,113 @@
/>
</el-select>
</el-form-item>
<el-form-item label="租户名称">
<el-input v-model="queryParams.tenantName" clearable placeholder="租户名称" style="width: 160px" />
<el-form-item label="登录账号" class="filter-form-field">
<el-input v-model="queryParams.loginAccount" clearable placeholder="登录账号" />
</el-form-item>
<el-form-item label="登录账号">
<el-input v-model="queryParams.loginAccount" clearable placeholder="登录账号" style="width: 160px" />
<el-form-item label="昵称" class="filter-form-field">
<el-input v-model="queryParams.nickname" clearable placeholder="昵称" />
</el-form-item>
<el-form-item label="昵称">
<el-input v-model="queryParams.nickname" clearable placeholder="昵称" style="width: 140px" />
<el-form-item label="推荐人手机" class="filter-form-field">
<el-input v-model="queryParams.referrerPhone" clearable placeholder="推荐人手机号" />
</el-form-item>
<el-form-item label="推荐人手机">
<el-input v-model="queryParams.referrerPhone" clearable placeholder="推荐人手机号" style="width: 160px" />
<el-form-item label="推荐人姓名" class="filter-form-field">
<el-input v-model="queryParams.referrerName" clearable placeholder="推荐人姓名" />
</el-form-item>
<el-form-item label="推荐人姓名">
<el-input v-model="queryParams.referrerName" clearable placeholder="推荐人姓名" style="width: 140px" />
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="createTimeRange"
type="datetimerange"
range-separator=""
start-placeholder="开始"
end-placeholder="结束"
value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']"
style="width: 360px"
/>
</el-form-item>
<el-form-item>
<el-form-item class="filter-form-query">
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
<el-button icon="el-icon-delete" @click="resetQuery">清空</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="action-container" shadow="never">
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button
type="warning"
icon="el-icon-refresh"
:loading="syncLoading"
style="margin-left: 12px"
@click="handleSyncFromHxr"
>
同步货品
</el-button>
<el-button
type="danger"
icon="el-icon-shopping-cart-full"
:loading="rushBuyLoading"
:disabled="!multipleSelection.length"
style="margin-left: 12px"
@click="handleRushBuy"
>
开始抢单
</el-button>
</el-card>
<el-card class="table-container" shadow="never">
<el-table
ref="dataTable"
v-loading="loading"
:data="list"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="租户ID" prop="tenantId" min-width="180" show-overflow-tooltip />
<el-table-column label="租户名称" prop="tenantName" min-width="120" show-overflow-tooltip />
<el-table-column label="登录账号" prop="loginAccount" min-width="120" show-overflow-tooltip />
<el-table-column label="昵称" prop="nickname" min-width="100" show-overflow-tooltip />
<el-table-column label="抢购单数" prop="maxGrabCount" width="90" align="center" />
<el-table-column label="最大金额" prop="maxGrabAmount" width="90" align="center" />
<el-table-column label="前端Token" prop="tokenFront" min-width="160" show-overflow-tooltip />
<el-table-column label="最新充值点数" prop="latestRechargePoints" width="110" align="center" />
<el-table-column label="剩余点数" prop="remainingPoints" width="90" align="center" />
<el-table-column label="累计点数" prop="totalPoints" width="90" align="center" />
<el-table-column label="是否启用" prop="enabled" width="90" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.enabled === 1 ? 'success' : 'info'" size="small">
{{ scope.row.enabled === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="抢单结果" prop="rushBuyResult" min-width="160" show-overflow-tooltip />
<el-table-column label="最后抢单时间" prop="lastRushBuyTime" min-width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.lastRushBuyTime) }}
</template>
</el-table-column>
<el-table-column label="推荐人姓名" prop="referrerName" min-width="100" show-overflow-tooltip />
<el-table-column label="推荐人手机" prop="referrerPhone" min-width="120" show-overflow-tooltip />
<el-table-column label="登录网址" prop="loginUrl" min-width="160" show-overflow-tooltip />
<el-table-column label="创建时间" prop="createTime" min-width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column label="修改时间" prop="updateTime" min-width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.updateTime) }}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" @click="handleCopy(scope.row)">复制</el-button>
<el-button type="text" style="color:#F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div v-loading="loading" class="purchase-apply-sheet-wrap">
<table v-if="list.length" class="purchase-apply-sheet">
<thead>
<tr>
<th class="cell-nickname-check">
<span class="cell-nickname-check-inner">
<el-checkbox
:indeterminate="selectAllIndeterminate"
:value="selectAllChecked"
@input="handleSelectAllChange"
/>
<span>登录账号</span>
</span>
</th>
<th>租户名称</th>
<th>昵称</th>
<th>抢购单数</th>
<th>最大金额</th>
<th class="col-long-text">前端Token</th>
<th>最新充值点数</th>
<th>剩余点数</th>
<th>累计点数</th>
<th>是否启用</th>
<th class="col-rush-buy-result">抢单结果</th>
<th class="col-last-rush-buy-time">最后抢单时间</th>
<th>推荐人姓名</th>
<th>推荐人手机</th>
<th>创建时间</th>
<th class="col-actions">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in list" :key="row.id || rowIndex">
<td class="cell-nickname-check">
<span class="cell-nickname-check-inner">
<el-checkbox
:value="isRowSelected(getRowKey(row, rowIndex))"
@input="setRowSelected(getRowKey(row, rowIndex), $event)"
/>
<span>{{ row.loginAccount || '-' }}</span>
</span>
</td>
<td>
<el-tooltip v-if="row.tenantName" :content="row.tenantName" placement="top">
<span class="cell-ellipsis">{{ row.tenantName }}</span>
</el-tooltip>
<span v-else class="cell-ellipsis">-</span>
</td>
<td><span class="cell-ellipsis">{{ row.nickname || '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.maxGrabCount != null ? row.maxGrabCount : '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.maxGrabAmount != null ? row.maxGrabAmount : '-' }}</span></td>
<td class="col-long-text">
<el-tooltip v-if="row.tokenFront" :content="row.tokenFront" placement="top">
<span class="cell-ellipsis">{{ row.tokenFront }}</span>
</el-tooltip>
<span v-else>-</span>
</td>
<td><span class="cell-ellipsis">{{ row.latestRechargePoints != null ? row.latestRechargePoints : '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.remainingPoints != null ? row.remainingPoints : '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.totalPoints != null ? row.totalPoints : '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.enabled === 1 ? '启用' : '禁用' }}</span></td>
<td class="col-rush-buy-result">
<el-tooltip
v-if="row.rushBuyResult"
placement="top"
popper-class="rush-buy-result-tooltip"
>
<div slot="content" class="rush-buy-result-tooltip-content">
{{ formatRushBuyResultTooltip(row.rushBuyResult) }}
</div>
<span class="cell-ellipsis">{{ row.rushBuyResult }}</span>
</el-tooltip>
<span v-else>-</span>
</td>
<td class="col-last-rush-buy-time"><span class="cell-ellipsis">{{ formatDateTime(row.lastRushBuyTime) }}</span></td>
<td><span class="cell-ellipsis">{{ row.referrerName || '-' }}</span></td>
<td><span class="cell-ellipsis">{{ row.referrerPhone || '-' }}</span></td>
<td><span class="cell-ellipsis">{{ formatDateTime(row.createTime) }}</span></td>
<td class="col-actions">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleCopy(row)">复制</el-button>
<el-button type="text" style="color:#F56C6C;" @click="handleDelete(row)">删除</el-button>
</td>
</tr>
</tbody>
</table>
<div v-else class="purchase-apply-sheet-empty">暂无数据</div>
</div>
<el-pagination
:current-page="queryParams.current"
@@ -334,10 +350,9 @@ export default {
rushBuyLoading: false,
tenantLoading: false,
list: [],
multipleSelection: [],
selectedRowKeys: [],
total: 0,
tenantOptions: [],
createTimeRange: [],
dialogVisible: false,
dialogTitle: '',
isEdit: false,
@@ -345,7 +360,6 @@ export default {
current: 1,
size: 10,
tenantId: '',
tenantName: '',
loginAccount: '',
nickname: '',
referrerPhone: '',
@@ -359,6 +373,25 @@ export default {
}
}
},
computed: {
multipleSelection() {
return this.list.filter((row, index) => this.isRowSelected(this.getRowKey(row, index)))
},
visibleRowKeys() {
return this.list.map((row, index) => this.getRowKey(row, index))
},
selectAllChecked() {
const keys = this.visibleRowKeys
if (!keys.length) return false
return keys.every((key) => this.selectedRowKeys.includes(key))
},
selectAllIndeterminate() {
const keys = this.visibleRowKeys
if (!keys.length) return false
const selectedCount = keys.filter((key) => this.selectedRowKeys.includes(key)).length
return selectedCount > 0 && selectedCount < keys.length
}
},
created() {
this.getTenantOptions()
this.initDefaultTenantFilter()
@@ -396,8 +429,31 @@ export default {
this.tenantLoading = false
})
},
handleSelectionChange(selection) {
this.multipleSelection = selection
handleSelectAllChange(checked) {
const visibleKeys = this.visibleRowKeys
if (checked) {
const selected = new Set([...this.selectedRowKeys, ...visibleKeys])
this.selectedRowKeys = Array.from(selected)
return
}
const visibleSet = new Set(visibleKeys)
this.selectedRowKeys = this.selectedRowKeys.filter((key) => !visibleSet.has(key))
},
getRowKey(row, rowIndex) {
if (row && row.id != null && row.id !== '') return String(row.id)
return `rush-order-account-${rowIndex}`
},
isRowSelected(key) {
return this.selectedRowKeys.includes(key)
},
setRowSelected(key, checked) {
const selected = new Set(this.selectedRowKeys)
if (checked) selected.add(key)
else selected.delete(key)
this.selectedRowKeys = Array.from(selected)
},
clearRowSelection() {
this.selectedRowKeys = []
},
handleSyncFromHxr() {
const tenantId = (this.queryParams.tenantId || '').trim() || this.getTenantIdFromBusinessHeaders()
@@ -481,9 +537,7 @@ export default {
})
.finally(() => {
this.loading = false
this.$nextTick(() => {
this.$refs.dataTable && this.$refs.dataTable.clearSelection()
})
this.clearRowSelection()
})
},
buildListParams() {
@@ -491,15 +545,11 @@ export default {
current: this.queryParams.current,
size: this.queryParams.size,
tenantId: this.queryParams.tenantId || undefined,
tenantName: this.queryParams.tenantName || undefined,
loginAccount: this.queryParams.loginAccount || undefined,
nickname: this.queryParams.nickname || undefined,
referrerPhone: this.queryParams.referrerPhone || undefined,
referrerName: this.queryParams.referrerName || undefined
}
const range = this.createTimeRange || []
if (range[0]) params.createTimeStart = range[0]
if (range[1]) params.createTimeEnd = range[1]
Object.keys(params).forEach((key) => {
if (params[key] === undefined || params[key] === '') delete params[key]
})
@@ -514,13 +564,11 @@ export default {
current: 1,
size: 10,
tenantId: '',
tenantName: '',
loginAccount: '',
nickname: '',
referrerPhone: '',
referrerName: ''
}
this.createTimeRange = []
this.initDefaultTenantFilter()
this.fetchList()
},
@@ -628,6 +676,14 @@ export default {
resetFormData() {
this.form = DEFAULT_FORM()
},
formatRushBuyResultTooltip(text) {
if (!text) return ''
return String(text)
.split('|')
.map((item) => item.trim())
.filter(Boolean)
.join('\n')
},
formatDateTime(dateTime) {
if (!dateTime) return '-'
const date = new Date(String(dateTime).replace('T', ' '))
@@ -646,12 +702,169 @@ export default {
<style lang="scss" scoped>
.app-container {
.filter-container,
.action-container {
$table-border: #000;
$header-bg: #ffd966;
.filter-container {
margin-bottom: 20px;
.filter-form-row {
display: flex;
flex-wrap: nowrap;
align-items: center;
width: 100%;
::v-deep .el-form-item {
margin-right: 12px;
margin-bottom: 0;
}
::v-deep .el-form-item__label {
white-space: nowrap;
flex-shrink: 0;
}
.filter-form-field {
flex: 1 1 0;
min-width: 0;
display: flex;
align-items: center;
::v-deep .el-form-item__content {
flex: 1;
min-width: 0;
}
::v-deep .el-input,
::v-deep .el-select {
width: 100%;
}
}
.filter-form-actions,
.filter-form-query {
flex: 0 0 auto;
margin-right: 0;
white-space: nowrap;
::v-deep .el-form-item__content {
display: flex;
flex-wrap: nowrap;
gap: 12px;
}
}
.filter-form-actions {
margin-right: 12px;
}
}
}
.table-container {
.purchase-apply-sheet-wrap {
overflow-x: auto;
}
.purchase-apply-sheet {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
color: #000;
font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
font-size: 14px;
text-align: center;
th,
td {
border: 1px solid $table-border;
padding: 8px 6px;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: normal;
}
thead th {
background-color: $header-bg;
font-weight: 700;
white-space: nowrap;
}
tbody td {
background-color: #fff;
::v-deep .el-tooltip {
display: block;
max-width: 100%;
overflow: hidden;
}
}
.col-last-rush-buy-time {
width: 190px;
max-width: 190px;
}
.col-rush-buy-result,
.col-long-text {
width: 180px;
max-width: 180px;
}
.cell-nickname-check {
width: 168px;
max-width: 168px;
}
.cell-ellipsis {
display: block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.col-actions {
width: 160px;
overflow: visible;
text-overflow: clip;
}
.cell-nickname-check-inner {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
max-width: 100%;
vertical-align: middle;
> span:last-child {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
::v-deep .el-checkbox {
margin-right: 0;
}
::v-deep .el-checkbox__label {
display: none;
}
}
}
.purchase-apply-sheet-empty {
padding: 40px 0;
text-align: center;
color: #909399;
border: 1px solid $table-border;
background-color: #fff;
}
.el-pagination {
margin-top: 20px;
text-align: right;
@@ -659,3 +872,14 @@ export default {
}
}
</style>
<style lang="scss">
.rush-buy-result-tooltip {
max-width: 360px;
}
.rush-buy-result-tooltip-content {
white-space: pre-line;
line-height: 1.5;
}
</style>

View File

@@ -72,7 +72,21 @@
<el-table-column label="成功抢单总金额" prop="maxGrabAmount" width="120" align="center" />
<el-table-column label="抢单总次数" prop="maxGrabCount" width="100" align="center" />
<el-table-column label="抢单失败次数" prop="rushBuyFailCount" width="110" align="center" />
<el-table-column label="抢单结果" prop="rushBuyResult" min-width="160" show-overflow-tooltip />
<el-table-column label="抢单结果" prop="rushBuyResult" min-width="480">
<template slot-scope="scope">
<el-tooltip
v-if="scope.row.rushBuyResult"
placement="top"
popper-class="rush-buy-result-tooltip"
>
<div slot="content" class="rush-buy-result-tooltip-content">
{{ formatRushBuyResultTooltip(scope.row.rushBuyResult) }}
</div>
<span class="rush-buy-result-cell">{{ scope.row.rushBuyResult }}</span>
</el-tooltip>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="最后抢单时间" prop="lastRushBuyTime" min-width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.lastRushBuyTime) }}
@@ -83,11 +97,6 @@
{{ formatDateTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column label="修改时间" prop="updateTime" min-width="160">
<template slot-scope="scope">
{{ formatDateTime(scope.row.updateTime) }}
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="140">
<template slot-scope="scope">
<el-button type="text" @click="handleEdit(scope.row)">编辑</el-button>
@@ -480,6 +489,14 @@ export default {
resetFormData() {
this.form = DEFAULT_FORM()
},
formatRushBuyResultTooltip(text) {
if (!text) return ''
return String(text)
.split('|')
.map((item) => item.trim())
.filter(Boolean)
.join('\n')
},
formatDateTime(dateTime) {
if (!dateTime) return '-'
const date = new Date(String(dateTime).replace('T', ' '))
@@ -508,6 +525,27 @@ export default {
margin-top: 20px;
text-align: right;
}
.rush-buy-result-cell {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
}
}
}
</style>
<style lang="scss">
.rush-buy-result-tooltip {
max-width: 360px;
}
.rush-buy-result-tooltip-content {
white-space: pre-line;
word-break: break-all;
line-height: 1.5;
}
</style>