This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"></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"></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"></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"></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"></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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user