修改bug
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 8m39s

This commit is contained in:
sexygoat
2026-03-11 17:09:35 +08:00
parent bd45f7a224
commit d43de4cd06
37 changed files with 2552 additions and 1696 deletions

View File

@@ -33,14 +33,29 @@
:pageSize="pagination.pageSize"
:total="pagination.total"
:marginTop="10"
:row-class-name="getRowClassName"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@row-contextmenu="handleRowContextMenu"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 鼠标悬浮提示 -->
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
<!-- 右键菜单 -->
<ArtMenuRight
ref="contextMenuRef"
:menu-items="contextMenuItems"
:menu-width="120"
@select="handleContextMenuSelect"
/>
<!-- 新增/编辑对话框 -->
<ElDialog
v-model="dialogVisible"
@@ -105,7 +120,11 @@
import type { SearchFormItem } from '@/types'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { useTableContextMenu } from '@/composables/useTableContextMenu'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { formatDateTime } from '@/utils/business/format'
import {
CommonStatus,
@@ -122,6 +141,17 @@
const loading = ref(false)
const submitLoading = ref(false)
const tableRef = ref()
const contextMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
const currentRow = ref<any>(null)
// 使用表格右键菜单功能
const {
showContextMenuHint,
hintPosition,
getRowClassName,
handleCellMouseEnter,
handleCellMouseLeave
} = useTableContextMenu()
// 搜索表单初始值
const initialSearchState = {
@@ -188,8 +218,7 @@
{ label: '运营商类型', prop: 'carrier_type' },
{ label: '运营商描述', prop: 'description' },
{ label: '状态', prop: 'status' },
{ label: '创建时间', prop: 'created_at' },
{ label: '操作', prop: 'operation' }
{ label: '创建时间', prop: 'created_at' }
]
const formRef = ref<FormInstance>()
@@ -271,35 +300,6 @@
label: '创建时间',
width: 180,
formatter: (row: any) => formatDateTime(row.created_at)
},
{
prop: 'operation',
label: '操作',
width: 150,
fixed: 'right',
formatter: (row: any) => {
const buttons = []
if (hasAuth('carrier:edit')) {
buttons.push(
h(ArtButtonTable, {
type: 'edit',
onClick: () => showDialog('edit', row)
})
)
}
if (hasAuth('carrier:delete')) {
buttons.push(
h(ArtButtonTable, {
type: 'delete',
onClick: () => deleteCarrier(row)
})
)
}
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
}
}
])
@@ -469,10 +469,51 @@
console.error(error)
}
}
// 右键菜单项配置
const contextMenuItems = computed((): MenuItemType[] => {
const items: MenuItemType[] = []
if (hasAuth('carrier:edit')) {
items.push({ key: 'edit', label: '编辑' })
}
if (hasAuth('carrier:delete')) {
items.push({ key: 'delete', label: '删除' })
}
return items
})
// 处理表格行右键菜单
const handleRowContextMenu = (row: any, column: any, event: MouseEvent) => {
event.preventDefault()
event.stopPropagation()
currentRow.value = row
contextMenuRef.value?.show(event)
}
// 处理右键菜单选择
const handleContextMenuSelect = (item: MenuItemType) => {
if (!currentRow.value) return
switch (item.key) {
case 'edit':
showDialog('edit', currentRow.value)
break
case 'delete':
deleteCarrier(currentRow.value)
break
}
}
</script>
<style scoped lang="scss">
.carrier-page {
height: 100%;
}
:deep(.el-table__row.table-row-with-context-menu) {
cursor: pointer;
}
</style>

View File

@@ -46,15 +46,21 @@
:pageSize="pagination.pageSize"
:total="pagination.total"
:marginTop="10"
:row-class-name="getRowClassName"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@row-contextmenu="handleRowContextMenu"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 鼠标悬浮提示 -->
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
<!-- 右键菜单 -->
<ArtMenuRight
ref="contextMenuRef"
@@ -242,8 +248,10 @@
} from '@/types/api/commission'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { useTableContextMenu } from '@/composables/useTableContextMenu'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { formatDateTime, formatMoney } from '@/utils/business/format'
import {
@@ -259,6 +267,15 @@
const route = useRoute()
// 使用表格右键菜单功能
const {
showContextMenuHint,
hintPosition,
getRowClassName,
handleCellMouseEnter,
handleCellMouseLeave
} = useTableContextMenu()
// 主表格状态
const loading = ref(false)
const tableRef = ref()
@@ -629,4 +646,8 @@
padding: 0;
}
}
:deep(.el-table__row.table-row-with-context-menu) {
cursor: pointer;
}
</style>

View File

@@ -1,89 +1,5 @@
<template>
<div class="my-commission-page">
<!-- 佣金概览卡片 -->
<ElRow :gutter="20" style="margin-bottom: 20px">
<ElCol :xs="24" :sm="12" :md="8" :lg="4">
<ElCard shadow="hover">
<div class="stat-card">
<div
class="stat-icon"
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
>
<i class="iconfont-sys">&#xe71d;</i>
</div>
<div class="stat-content">
<div class="stat-label">总佣金</div>
<div class="stat-value">{{ formatMoney(summary.total_commission) }}</div>
</div>
</div>
</ElCard>
</ElCol>
<ElCol :xs="24" :sm="12" :md="8" :lg="4">
<ElCard shadow="hover">
<div class="stat-card">
<div
class="stat-icon"
style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
>
<i class="iconfont-sys">&#xe71e;</i>
</div>
<div class="stat-content">
<div class="stat-label">可提现佣金</div>
<div class="stat-value">{{ formatMoney(summary.available_commission) }}</div>
</div>
</div>
</ElCard>
</ElCol>
<ElCol :xs="24" :sm="12" :md="8" :lg="4">
<ElCard shadow="hover">
<div class="stat-card">
<div
class="stat-icon"
style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)"
>
<i class="iconfont-sys">&#xe720;</i>
</div>
<div class="stat-content">
<div class="stat-label">冻结佣金</div>
<div class="stat-value">{{ formatMoney(summary.frozen_commission) }}</div>
</div>
</div>
</ElCard>
</ElCol>
<ElCol :xs="24" :sm="12" :md="8" :lg="4">
<ElCard shadow="hover">
<div class="stat-card">
<div
class="stat-icon"
style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%)"
>
<i class="iconfont-sys">&#xe71f;</i>
</div>
<div class="stat-content">
<div class="stat-label">提现中佣金</div>
<div class="stat-value">{{ formatMoney(summary.withdrawing_commission) }}</div>
</div>
</div>
</ElCard>
</ElCol>
<ElCol :xs="24" :sm="12" :md="8" :lg="4">
<ElCard shadow="hover">
<div class="stat-card">
<div
class="stat-icon"
style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"
>
<i class="iconfont-sys">&#xe721;</i>
</div>
<div class="stat-content">
<div class="stat-label">已提现佣金</div>
<div class="stat-value">{{ formatMoney(summary.withdrawn_commission) }}</div>
</div>
</div>
</ElCard>
</ElCol>
</ElRow>
<!-- 标签页 -->
<ElCard shadow="never">
<ElTabs v-model="activeTab">
@@ -841,37 +757,6 @@
<style lang="scss" scoped>
.my-commission-page {
.stat-card {
display: flex;
gap: 16px;
align-items: center;
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
font-size: 28px;
color: white;
border-radius: 12px;
}
.stat-content {
flex: 1;
.stat-label {
margin-bottom: 8px;
font-size: 14px;
color: var(--el-text-color-secondary);
}
.stat-value {
font-size: 20px;
font-weight: 600;
color: var(--el-text-color-primary);
}
}
}
// 样式已移动到分析页的佣金概览组件
}
</style>

View File

@@ -1,78 +1,8 @@
<template>
<ArtTableFullScreen>
<div class="withdrawal-settings-page" id="table-full-screen">
<!-- 当前生效配置卡片 -->
<ElCard shadow="never" class="current-setting-card" v-if="currentSetting">
<template #header>
<div class="card-header">
<div class="header-left">
<span class="header-title">当前生效配置</span>
<ElTag type="success" effect="dark">生效中</ElTag>
</div>
<div class="header-right">
<span class="creator-info"
>{{ currentSetting.creator_name || '-' }} 创建于
{{ formatDateTime(currentSetting.created_at) }}</span
>
</div>
</div>
</template>
<div class="setting-info">
<div class="info-card">
<div
class="info-icon"
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
>
<i class="el-icon">💰</i>
</div>
<div class="info-content">
<div class="info-label">最低提现金额</div>
<div class="info-value">{{ formatMoney(currentSetting.min_withdrawal_amount) }}</div>
</div>
</div>
<div class="info-card">
<div
class="info-icon"
style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
>
<i class="el-icon">📊</i>
</div>
<div class="info-content">
<div class="info-label">手续费率</div>
<div class="info-value">{{ formatFeeRate(currentSetting.fee_rate) }}</div>
</div>
</div>
<div class="info-card">
<div
class="info-icon"
style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)"
>
<i class="el-icon">🔢</i>
</div>
<div class="info-content">
<div class="info-label">每日提现次数</div>
<div class="info-value">{{ currentSetting.daily_withdrawal_limit }} </div>
</div>
</div>
<div class="info-card">
<div
class="info-icon"
style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"
>
<i class="el-icon"></i>
</div>
<div class="info-content">
<div class="info-label">到账天数</div>
<div class="info-value">{{
currentSetting.arrival_days === 0 ? '实时到账' : `${currentSetting.arrival_days}`
}}</div>
</div>
</div>
</div>
</ElCard>
<!-- 配置列表 -->
<ElCard shadow="never" class="art-table-card" style="margin-top: 20px">
<ElCard shadow="never" class="art-table-card">
<!-- 表格头部 -->
<ArtTableHeader
:columnList="columnOptions"
@@ -168,9 +98,6 @@
const tableRef = ref()
const formRef = ref<FormInstance>()
// 当前生效的配置
const currentSetting = ref<WithdrawalSettingItem | null>(null)
// 配置列表
const settingsList = ref<WithdrawalSettingItem[]>([])
@@ -254,26 +181,9 @@
])
onMounted(() => {
loadData()
loadSettingsList()
})
// 加载数据
const loadData = async () => {
await Promise.all([loadCurrentSetting(), loadSettingsList()])
}
// 加载当前生效配置
const loadCurrentSetting = async () => {
try {
const res = await CommissionService.getCurrentWithdrawalSetting()
if (res.code === 0 && res.data) {
currentSetting.value = res.data
}
} catch (error) {
console.error('获取当前配置失败:', error)
}
}
// 加载配置列表
const loadSettingsList = async () => {
loading.value = true
@@ -291,7 +201,7 @@
// 刷新数据
const handleRefresh = () => {
loadData()
loadSettingsList()
}
// 显示新增对话框
@@ -323,7 +233,7 @@
ElMessage.success('新增配置成功')
dialogVisible.value = false
formEl.resetFields()
loadData()
loadSettingsList()
} catch (error) {
console.error(error)
} finally {
@@ -336,99 +246,6 @@
<style lang="scss" scoped>
.withdrawal-settings-page {
.current-setting-card {
:deep(.el-card__header) {
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
.header-left {
display: flex;
gap: 12px;
align-items: center;
.header-title {
font-size: 16px;
font-weight: 600;
color: #fff;
}
}
.header-right {
.creator-info {
font-size: 13px;
color: rgb(255 255 255 / 90%);
}
}
}
.setting-info {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
padding: 4px 0;
@media (width <= 1400px) {
grid-template-columns: repeat(2, 1fr);
}
@media (width <= 768px) {
grid-template-columns: 1fr;
}
.info-card {
display: flex;
gap: 16px;
align-items: center;
padding: 20px;
background: var(--el-fill-color-light);
border-radius: 8px;
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 12px rgb(0 0 0 / 10%);
transform: translateY(-2px);
}
.info-icon {
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
font-size: 24px;
border-radius: 12px;
}
.info-content {
flex: 1;
min-width: 0;
.info-label {
margin-bottom: 4px;
font-size: 13px;
color: var(--el-text-color-secondary);
}
.info-value {
overflow: hidden;
font-size: 18px;
font-weight: 600;
color: var(--el-text-color-primary);
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.form-tip {
margin-top: 4px;
font-size: 12px;