This commit is contained in:
李远 2026-03-12 18:56:54 +08:00
parent ba89a965c7
commit 76ca0186dd
7 changed files with 155 additions and 205 deletions

View File

@ -109,7 +109,7 @@ const staticMenuList = ref<ElMenuItem[]>(
{
id: 32,
label: '代理管理',
path: '3-2', // index="3-2"
path: '/account/agent', // index="3-2"
icon: ''
},
{

View File

@ -103,6 +103,14 @@ const routes = [
title: '客户管理', // 左侧菜单显示的标题
}
},
{
path: 'agent',
name: 'Agent',
component: () => import('@/views/account/agent/index.vue'),
meta: {
title: '代理管理', // 左侧菜单显示的标题
}
}
]
},
]

View File

@ -1,5 +1,67 @@
<template>
<div>
<h1>代理商管理</h1>
<div class="agent">
<AgentSearch :search-form="agentSearchForm" :search-options="agentSearchOptions" @search="handleSearch"
@reset="handleReset">
</AgentSearch>
<AgentTable :table-data="agentTree" :columns="agentTableColumnsOptions" row-key="id" />
<AgentPagination v-model="agentSearchForm.page" v-model:page-size-value="agentSearchForm.pageSize"
:total="agentSearchForm.total" @pagination-change="handlePaginationChange" />
<AgentDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" :fullscreen="true"
@cancel="handleCancel" @close="handleClose">
<template #header>
<div class="dialog-header">
<span class="dialog-title">查看点差</span>
<span class="dialog-close-text" @click="dialogVisible = false">关闭</span>
</div>
</template>
<AgentTable :table-data="agentPointTree" :columns="agentPointTableColumnsOptions" row-key="id" />
</AgentDialog>
</div>
</template>
</template>
<script lang="ts" setup>
//
import AgentSearch from '@/components/common/Search.vue'
import AgentTable from '@/components/common/Table.vue'
import AgentPagination from '@/components/common/Pagination.vue'
import AgentDialog from '@/components/common/Dialog.vue'
//
import { agentSearch, agentTableColumns, agentPointTableColumns } from './options'
//
const agentSearchOptions = ref(agentSearch)
const agentSearchForm = ref({
username: '',
status: '正常',
startDateTime: '',
endDateTime: '',
page: 1,
pageSize: 10,
total: 100,
})
//
const agentTree = ref<any[]>([])
const agentTableColumnsOptions = ref(agentTableColumns)
//
const dialogVisible = ref(true)
const dialogTitle = ref('查看点差')
const dialogType = ref('add')
const dialogWidth = ref('100%')
const agentPointTree = ref<any[]>([])
const agentPointTableColumnsOptions = ref(agentPointTableColumns)
</script>
<style scoped lang="scss">
.agent {
:deep(.el-dialog) {
.el-dialog__footer {
display: none;
}
}
}
</style>

View File

@ -0,0 +1,48 @@
// 获取当前年份
const currentYear = new Date().getFullYear()
// 定义禁用日期函数:只能选择今年及以后的日期
const disabledDate = (time: Date) => {
// 时间早于今年1月1日则禁用
return time.getTime() < new Date(currentYear, 0, 1).getTime()
}
//定义客户搜索表单配置
export const agentSearch = [
{ prop: 'username', label: '用户名', type: 'input' as const, placeholder: '用户名', width: '120px' },
{
prop: "startDateTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
width: '180px',
disabledDate
},
{
prop: "endDateTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
width: '180px',
disabledDate
},
]
// 定义表格列配置
export const agentTableColumns = [
{ prop: 'id', label: 'ID', align: 'center' as const },
{ prop: 'username', label: '代理名称', align: 'center' as const },
{ prop: 'registerTime', label: '注册时间', align: 'center' as const },
{ prop: 'status', label: '状态', align: 'center' as const },
{ prop: 'pointDifference', label: '点差', align: 'center' as const },
{ prop: 'feeRate', label: '手续费', align: 'center' as const },
{ prop: 'rebateRate', label: '手续费返佣', align: 'center' as const },
{ prop: 'pointDifference2', label: '点差', align: 'center' as const },
{ prop: 'rebateTotalAmount', label: '返佣总金额', align: 'center' as const },
{ prop: 'clientCount', label: '客户数量', align: 'center' as const },
{ prop: 'level', label: '级别', align: 'center' as const },
]
// 定义点差表格列配置
export const agentPointTableColumns = [
{ prop: 'varietyName', label: '品种名称', align: 'center' as const },
{ prop: 'varietyCode', label: '品种编号', align: 'center' as const },
{ prop: 'pointDifference', label: '可用点差', align: 'center' as const },
{ prop: 'assignedPointDifference', label: '已分配点差', align: 'center' as const },
]

View File

@ -204,16 +204,25 @@ const handleDialogType = (type: string) => {
//
const getOptions = async () => {
//
const agentOptions = await getAgentOptionsApi()
//
const feeTemplateOptions = await getFeeTemplateOptionsApi()
//
const riskTemplateOptions = await getRiskTemplateOptionsApi()
try {
//
const [agentRes, feeTemplateRes, riskTemplateRes] = await Promise.all([
getAgentOptionsApi(),
getFeeTemplateOptionsApi(),
getRiskTemplateOptionsApi()
]);
clientFormOptionsMap.value.feeTemplate = mapObjectToOptions(feeTemplateOptions as Record<string, string>)
clientFormOptionsMap.value.riskTemplate = mapObjectToOptions(riskTemplateOptions as Record<string, string>)
clientFormOptionsMap.value.agentUsername = mapObjectToOptions(agentOptions as Record<string, string>)
const agentOptions = mapObjectToOptions(agentRes as Record<string, string>);
const feeTemplateOptions = mapObjectToOptions(feeTemplateRes as Record<string, string>);
const riskTemplateOptions = mapObjectToOptions(riskTemplateRes as Record<string, string>);
//
clientFormOptionsMap.value.agentUsername = agentOptions;
clientFormOptionsMap.value.feeTemplate = feeTemplateOptions;
clientFormOptionsMap.value.riskTemplate = riskTemplateOptions;
} catch (error) {
console.error('获取表单选项失败:', error);
}
}
/**
@ -305,10 +314,7 @@ const handleSubmit = async () => {
}
}
//
const handleCancel = () => {
dialogVisible.value = false
dialogType.value = 'add'
const resetForm = () => {
clientForm.value = {
//
feeTemplate: '',
@ -319,25 +325,28 @@ const handleCancel = () => {
email: '',
phone: '',
countryCode: '+86',
//
isUpgrade: 1,
//
userName: '',
status: 1,
id: '',
}
}
//
const handleCancel = () => {
dialogVisible.value = false
dialogType.value = 'add'
resetForm()
}
//
const handleClose = () => {
dialogVisible.value = false
dialogType.value = 'add'
clientForm.value = {
//
feeTemplate: '',
//
riskTemplate: '',
//
agentUsername: '',
email: '',
phone: '',
countryCode: '+86',
}
resetForm()
}
</script>

View File

@ -1,47 +0,0 @@
// 建议单独创建 types.ts 文件管理所有类型
// types.ts
export interface ClientSearchForm {
page: number;
pageSize: number;
username: string;
status: '正常' | '禁用';
startDateTime: string;
endDateTime: string;
}
export interface ClientItem {
id: string | number;
username: string;
status: 1 | 2;
email?: string;
phone?: string;
countryCode?: string;
feeTemplate?: string | number;
riskTemplate?: string | number;
agentUsername?: string;
isUpgrade?: 1 | 2;
par_uid?: string | number;
parent?: {
id: string | number;
username: string;
};
}
export interface ClientForm {
id: string;
feeTemplate: string | number;
riskTemplate: string | number;
agentUsername: string | number;
email: string;
phone: string;
countryCode: string;
isUpgrade: 1 | 2;
userName: string;
status: 1 | 2;
}
export interface ClientListResponse {
data: ClientItem[];
total: number;
per_page: number | string;
}

View File

@ -1,130 +0,0 @@
<template>
<div class="client">
<!-- 搜索组件 -->
<ClientSearch :search-form="searchForm" :search-options="clientSearchOptions" @search="handleSearch"
@reset="handleReset">
<!-- 这里可以插入自定义插槽如果需要 -->
</ClientSearch>
<!-- 下方的表格区域与你的图片对应 -->
<el-table :data="tableData" border>
<el-table-column prop="username" label="用户名" />
<el-table-column prop="registerStartTime" label="注册开始时间" />
<el-table-column prop="registerEndTime" label="注册结束时间" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
{{ row.status === 1 ? '开启' : '关闭' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default>
<el-button link type="primary">搜索</el-button>
<el-button link type="primary">重置</el-button>
<el-button link type="primary">新增用户</el-button>
</template>
</el-table-column>
</el-table>
</div>
<ClientPagination v-model="currentPage" v-model:page-size-value="pageSize" :total="total"
@pagination-change="handlePaginationChange" />
</template>
<script lang="ts" setup>
//
import ClientSearch from '@/components/common/Search.vue'
import ClientTable from '@/components/common/Table.vue'
import ClientPagination from '@/components/common/Pagination.vue'
//
import { clientSearchOptions } from './options'
//
const searchForm = ref({
username: '', //
registerTime: [], // daterange
status: '' // /
})
// 3.
const handleSearch = () => {
console.log('发起查询,参数:', searchForm)
// registerTime start end
const params = {
...searchForm.value,
registerStartTime: searchForm.value.registerTime[0] || '',
registerEndTime: searchForm.value.registerTime[1] || ''
}
delete params.registerTime //
//
// api.getUserList(params).then(res => {
// tableData.value = res.list
// })
}
// 4.
const handleReset = () => {
//
searchForm.value.username = ''
searchForm.value.registerTime = []
searchForm.value.status = ''
//
handleSearch()
}
//
handleSearch()
//
const currentPage = ref<number>(1) //
const pageSize = ref<number>(50) //
const total = ref<number>(100) //
//
onMounted(() => {
fetchData()
})
//
const fetchData = async () => {
try {
//
// const res = await api.getList({ page: currentPage.value, size: pageSize.value })
//
const res = {
list: [/* 业务数据 */],
total: 100 //
}
tableData.value = res.list
total.value = res.total
} catch (error) {
console.error('数据请求失败:', error)
}
}
//
const handlePaginationChange = ({ currentPage: page, pageSize: size }: { currentPage: number, pageSize: number }) => {
//
currentPage.value = page
pageSize.value = size
//
fetchData()
}
</script>