This commit is contained in:
李远 2026-03-25 09:28:14 +08:00
parent 4f0ba2fa59
commit dc548d1d53
14 changed files with 633 additions and 14 deletions

View File

@ -0,0 +1,6 @@
import { request } from '@/api';
// 获取资金流水列表
export const getCustomCapitalFlowListApi = (params: any) => {
return request.get('user/FundFlowRecords', {...params})
}

View File

@ -0,0 +1,5 @@
//获取代理客户列表接口
import { request } from '@/api';
export const getCustomerListApi = (params: any) => {
return request.get('/agent/getAgentUserList', {...params})
}

View File

@ -0,0 +1,6 @@
import { request } from '@/api';
// 获取跟订单列表
export const getCustomTradeOrderListApi = (params: any) => {
return request.get('/orderRecords/getList', {...params})
}

View File

@ -5,7 +5,7 @@
<!-- 动态表头列 -->
<template v-for="(column, index) in columns" :key="index">
<el-table-column v-if="!column.slotName" :prop="column.prop" :label="column.label" :width="column.width"
:align="column.align || 'left'" />
:align="column.align || 'left'" :sortable="column.sortable" />
<!-- 具名插槽列 -->
<el-table-column v-else :label="column.label" :width="column.width" :align="column.align || 'left'">
@ -26,6 +26,7 @@ interface TableColumn {
width?: string | number
align?: 'left' | 'center' | 'right'
slotName?: string //
sortable?: boolean //
}
//

View File

@ -1,5 +1,114 @@
<template>
<div>
客户资金流水
<!-- 搜索 -->
<CustomerCapitalFlowSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
@reset="handleReset">
</CustomerCapitalFlowSearch>
<!-- 表格 -->
<CustomerCapitalFlowTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" />
<!-- 分页 -->
<CustomerCapitalFlowPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@pagination-change="handlePaginationChange" />
</div>
</template>
<script setup lang="ts">
//
import CustomerCapitalFlowSearch from '@/components/common/Search.vue'
import CustomerCapitalFlowTable from '@/components/common/Table.vue'
import CustomerCapitalFlowPagination from '@/components/common/Pagination.vue'
//
import { search, tableColumns } from './options'
//
import { getCustomCapitalFlowListApi } from '@/api/modules/agent/customCapitalFlow'
//
/**
* @description: 定义搜索数据
*/
const searchForm = ref({
accountName: '',
userId: '',
startTime: '',
endTime: '',
})
const searchOptions = ref(search)
/**
* @description: 定义表格数据
*/
const tableTree = ref([])
const tableColumnsOptions = ref(tableColumns)
/**
* @description: 定义分页数据
*/
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
/**
* @description: 定义公共请求数据方法
*/
const getCustomerCapitalFlowList = async () => {
const params = {
page: currentPage.value,
page_size: pageSize.value,
start_time: searchForm.value.startTime.length > 0 ? `${searchForm.value.startTime} 0:00:00` : '2026-01-01 0:00:00',
end_time: searchForm.value.endTime.length > 0 ? `${searchForm.value.endTime} 23:59:59` : '2026-03-15 23:59:59',
user_name: searchForm.value.accountName,
account_id: '',
}
const data: any = await getCustomCapitalFlowListApi(params)
//
// table
tableTree.value = data.data.map((item: any) => ({
id:item.account_id,
flowNo:'',
accountName:item.user.username,
amount:item.amount,
fundType:'',
status:'',
operationType:'',
createTime:item.created_at,
}))
//
total.value = data.total
currentPage.value = data.current_page
pageSize.value = Number(data.per_page)
}
/**
* @description: 页面加载完成需要请求的数据
*/
onMounted(() => {
getCustomerCapitalFlowList()
})
/**
* @description: 定义搜索方法
*/
const handleSearch = () => {
getCustomerCapitalFlowList()
}
const handleReset = () => {
searchForm.value = {
accountName: '',
userId: '',
startTime: '',
endTime: '',
}
getCustomerCapitalFlowList()
}
/**
* @description: 定义分页方法
*/
const handlePaginationChange = (page: { currentPage: number, size: number }) => {
currentPage.value = page.currentPage
getCustomerCapitalFlowList()
}
</script>

View File

@ -0,0 +1,35 @@
export const search = [
// 账号名称
{ prop: 'accountName', label: '账号名称', type: 'input' as const, placeholder: '请输入账号名称', width: '150px' },
// 开始时间
{
prop: "startTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
},
// 结束时间
{
prop: "endTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
},
// 选择账号
{ prop: 'userId', label: '账号', type: 'select' as const, placeholder: '请选择账号' },
]
export const tableColumns = [
// 流水id
{ prop: 'id', label: '流水id' },
// 流水单号
{ prop: 'flowNo', label: '流水单号' },
// 账户名称
{ prop: 'accountName', label: '账户名称' },
// 金额
{ prop: 'amount', label: '金额' },
// 资金类别
{ prop: 'fundType', label: '资金类别' },
// 状态
{ prop: 'status', label: '状态' },
// 操作方式
{ prop: 'operationType', label: '操作方式' },
// 时间
{ prop: 'createTime', label: '时间' },
]

View File

@ -0,0 +1 @@
<template></template>

View File

@ -1,5 +1,186 @@
<template>
<div>
客户列表
<!-- 搜索 -->
<CustomerListSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
@reset="handleReset"></CustomerListSearch>
<!-- 表格 -->
<CustomerListTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" :tree-props="treeProps" :default-sort="{ prop: 'createTime', order: 'descending' }">
<template #accountName="{ row }">
<div style="display: flex; align-items: center;">
{{ row.accountName }}
<el-icon style="margin-left: 5px; cursor: pointer;" @click="handleGetSubList(row)">
<Plus />
</el-icon>
</div>
</template>
<template #marginRatio="{ row }">
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleEdit(row)">
修改
</el-button>
</template>
<template #commissionRatio="{ row }">
{{ row.commissionRatio }}
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleEdit(row)">
修改
</el-button>
</template>
<template #action="{ row }">
<el-button link type="primary" size="small" @click="handleDetail(row)">
查看详情
</el-button>
</template>
<template #empty="{ row }">
<el-empty v-if="row.isEmpty" description="暂无下级" style="padding: 10px 0; text-align: center;" />
</template>
</CustomerListTable>
<!-- 分页 -->
<CustomerListPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@pagination-change="handlePaginationChange" />
<!-- dialog -->
<!-- dialog表格 -->
</div>
</template>
<script setup lang="ts">
import { Plus } from '@element-plus/icons-vue'
//
import CustomerListSearch from '@/components/common/Search.vue'
import CustomerListTable from '@/components/common/Table.vue'
import CustomerListPagination from '@/components/common/Pagination.vue'
import CustomerListDialog from '@/components/common/Dialog.vue'
import CustomerListForm from '@/components/common/Form.vue'
//
import { search, tableColumns } from './options'
//
import { getCustomerListApi } from '@/api/modules/agent/customerList'
//
import { getStorage } from '@/utils/storage'
/**
* @description: 获取用户id
*/
const userInfo: any = getStorage('userInfo')
const userId = ref(userInfo?.id || '')
/**
* @description: 定义搜索数据
*/
const searchForm = ref({
accountName: '',
startTime: '',
endTime: '',
status: '',
})
const searchOptions = ref(search)
const tableColumnsOptions = ref(tableColumns)
/**
* @description: 定义表格数据
*/
const tableTree = ref([])
const treeProps = { children: 'children' }
/**
* @description: 定义分页数据
*/
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
/**
* @description: 定义弹窗数据
*/
/**
* @description: 定义弹窗表格数据
*/
/**
* @description: 角色映射方法
*/
const roleMap: any = {
1: '平台',
2: '承包商',
3: '特殊做市商',
4: '普通做市商',
5: '代理',
6: '用户'
}
/**
* @description: 定义公共请求数据方法
*/
const getCustomerList = async (id: string) => {
console.log('用户id', id);
const params = {
user_id: id,
page: currentPage.value,
page_size: pageSize.value,
user_name: searchForm.value.accountName,
reg_start_time: searchForm.value.startTime.length > 0 ? `${searchForm.value.startTime} 0:00:00` : '2026-01-01 0:00:00',
reg_end_time: searchForm.value.endTime.length > 0 ? `${searchForm.value.endTime} 23:59:59` : '2026-03-01 23:59:59',
status: searchForm.value.status,
}
const data: any = await getCustomerListApi(params)
tableTree.value = data.data.map((item: any) => ({
accountName: item.username,
userId: item.id,
status: item.status === 1 ? '正常' : '禁用',
role: roleMap[item.role_id] || '未知',
accountQty: item.account[0].account_count,
marginRatio: "这是按钮",
commissionRatio: item.wallet_capital.fee_handling_percent,
createTime: item.created_at,
role_id: item.role_id,
children: [],
}))
//
total.value = data.total
currentPage.value = data.current_page
pageSize.value = Number(data.per_page)
}
/**
* @description: 页面加载完成需要请求的数据
*/
onMounted(() => {
getCustomerList(userId.value)
})
/**
* @description: 定义搜索方法
*/
const handleSearch = async () => {
getCustomerList(userId.value)
}
const handleReset = () => {
searchForm.value = {
accountName: '',
startTime: '',
endTime: '',
status: '',
}
getCustomerList(userId.value)
}
/**
* @description: 定义表格方法
*/
//
const handleGetSubList = async (row: any) => {
console.log('获取子列表', row);
}
/**
* @description: 定义分页方法
*/
const handlePaginationChange = (page: { currentPage: number, size: number }) => {
currentPage.value = page.currentPage
getCustomerList(userId.value)
}
/**
* @description: 定义弹窗方法
*/
/**
* @description: 定义弹窗表格方法
*/
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,37 @@
export const search = [
// 账号名称
{ prop: 'accountName', label: '账号名称', type: 'input' as const, placeholder: '请输入账号名称', width: '150px' },
// 开始时间
{
prop: "startTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
},
// 结束时间
{
prop: "endTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
},
// 状态
{ prop: 'status', label: '状态', type: 'select' as const, placeholder: '请选择状态' },
]
export const tableColumns = [
// 账号名称
{ label: '账号名称', slotName: 'accountName', emptySpan: { colspan: 999 } },
// 账号id
{ prop: 'userId', label: '账号id' },
// 状态
{ prop: 'status', label: '状态' },
// 账号角色
{ prop: 'role', label: '账号角色' },
// 账号数量
{ prop: 'accountQty', label: '账号数量' },
// 点差分配比例
{ prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' },
// 手续费分成比例
{ prop: 'commissionRatio', label: '手续费分成比例', slotName: 'commissionRatio' },
// 注册时间
{ prop: 'createTime', label: '注册时间' ,sortable:true},
// 操作
{ label: '操作', slotName: 'action' }
]

View File

@ -1,5 +1,135 @@
<template>
<div>
客户交易订单
<!-- 搜索 -->
<CustomerTradeOrderSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
@reset="handleReset">
</CustomerTradeOrderSearch>
<div class="bar" v-if="searchForm.orderId === '1'">
<div>持仓量:0</div>
<div>手续费:0.00 USD</div>
<div>交易盈亏:0.00 USD</div>
</div>
<!-- 表格 -->
<CustomerTradeOrderTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" />
<!-- 分页 -->
<CustomerTradeOrderPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@pagination-change="handlePaginationChange" />
</div>
</template>
<script setup lang="ts">
//
import CustomerTradeOrderSearch from '@/components/common/Search.vue'
import CustomerTradeOrderTable from '@/components/common/Table.vue'
import CustomerTradeOrderPagination from '@/components/common/Pagination.vue'
//
import { search, tradeOrderTableColumns, positionOrderTableColumns } from './options'
//
import { getCustomTradeOrderListApi } from '@/api/modules/agent/customerTradeOrder'
//
/**
* @description: 定义搜索数据
*/
const searchForm = ref({
accountName: '',
orderId: '2',
tradeType: '',
startTime: '',
endTime: '',
})
const searchOptions = ref(search)
/**
* @description: 定义表格数据
*/
const tableTree = ref([])
const tableColumnsOptions = computed(() => {
return searchForm.value.orderId === "1" ? tradeOrderTableColumns : positionOrderTableColumns
})
/**
* @description: 定义分页数据
*/
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
/**
* @description: 定义公共请求数据方法
*/
const getCustomerTradeOrderList = async () => {
const params = {
page: currentPage.value,
page_size: pageSize.value,
user_name: searchForm.value.accountName,
account_id: searchForm.value.accountName,
order_no: '',
type: searchForm.value.tradeType,
start_time: searchForm.value.startTime.length > 0 ? `${searchForm.value.startTime} 0:00:00` : '2026-01-01 0:00:00',
end_time: searchForm.value.endTime.length > 0 ? `${searchForm.value.endTime} 23:59:59` : '2026-01-01 23:59:59',
}
const data: any = await getCustomTradeOrderListApi(params)
//
// table
tableTree.value = data.data.map((item: any) => ({
accountName: item.user.username,
orderId: item.order_id,
variety: item.variety.name,
type: item.type === 1 ? '买入' : '卖出',
quantity: item.num,
openPrice: item.build_price,
closePrice: item.close_price,
amount: item.amount,
createdTime: item.created_at,
}))
//
total.value = data.total
currentPage.value = data.current_page
pageSize.value = Number(data.per_page)
}
/**
* @description: 页面加载完成需要请求的数据
*/
onMounted(() => {
getCustomerTradeOrderList()
})
/**
* @description: 定义搜索方法
*/
const handleSearch = () => {
getCustomerTradeOrderList()
}
const handleReset = () => {
searchForm.value = {
accountName: '',
orderId: '',
tradeType: '',
startTime: '',
endTime: '',
}
getCustomerTradeOrderList()
}
/**
* @description: 定义分页方法
*/
const handlePaginationChange = (page: { currentPage: number, size: number }) => {
currentPage.value = page.currentPage
getCustomerTradeOrderList()
}
</script>
<style scoped lang="scss">
.bar {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
}
</style>

View File

@ -0,0 +1,106 @@
/**
* @description:
*/
export const search = [
// 账户名
{
label: '账户名',
prop: 'accountName',
type: 'input' as const,
placeholder: '请输入账户名',
width: '140px'
},
{
label: '订单',
prop: 'orderId',
type: 'select' as const,
options: [
{
label: '持仓订单',
value: '1'
},
{
label: '交易订单',
value: '2'
},
],
width: '140px'
},
// 选择交易类型
{
label: '交易类型',
prop: 'tradeType',
type: 'select' as const,
options: [
{
label: '全部',
value: '1'
},
{
label: '买入',
value: '2'
},
{
label: '卖出',
value: '3'
},
],
width: '140px'
},
// 开始时间
{
prop: "startTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
width: '140px'
},
// 结束时间
{
prop: "endTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
width: '140px'
},
]
/**
* @description:
*/
// 持仓订单
export const tradeOrderTableColumns = [
// 账户名
{ label: '账户名', prop: 'accountName' },
// 交易类型
{ label: '交易类型', prop: 'tradeType' },
// 交易品种
{ label: '交易品种', prop: 'variety' },
// 开仓时间
{ label: '开仓时间', prop: 'openTime' },
// 开仓价格
{ label: '开仓价格', prop: 'openPrice' },
// 平仓时间
{ label: '平仓时间', prop: 'closeTime' },
// 平仓价格
{ label: '平仓价格', prop: 'closePrice' },
// 浮动盈亏
{ label: '浮动盈亏', prop: 'floatProfit' },
]
//交易订单
export const positionOrderTableColumns = [
// 账户名
{ label: '账户名', prop: 'accountName' },
//订单编号
{ label: '订单编号', prop: 'orderId' },
//品种名称
{ label: '品种名称', prop: 'variety' },
//类型
{ label: '类型', prop: 'type' },
//数量
{ label: '数量', prop: 'quantity' },
//开仓价格
{ label: '开仓价格', prop: 'openPrice' },
//平仓价格
{ label: '平仓价格', prop: 'closePrice' },
//金额
{ label: '金额', prop: 'amount' },
//创建时间
{ label: '创建时间', prop: 'createdTime' },
]

View File

@ -14,7 +14,7 @@
<!-- 分页 -->
<FollowRecordPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@change="handleChange" />
@pagination-change="handlePaginationChange" />
</div>
</template>
@ -113,7 +113,8 @@ const handleExport = () => {
/**
* @description: 定义分页方法
*/
const handleChange = (page: { currentPage: number, size: number }) => {
const handlePaginationChange = (page: { currentPage: number, size: number }) => {
currentPage.value = page.currentPage
getFollowList()
}
</script>

View File

@ -14,7 +14,7 @@
<!-- 分页 -->
<LeadRecordPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@change="handleChange" />
@pagination-change="handlePaginationChange" />
</div>
</template>
@ -55,7 +55,7 @@ const total = ref(0)
/**
* @description: 定义公共请求数据方法
*/
const getFollowList = async () => {
const getLeadList = async () => {
const params = {
page: currentPage.value,
page_size: pageSize.value,
@ -84,14 +84,14 @@ const getFollowList = async () => {
* @description: 页面加载完成需要请求的数据
*/
onMounted(() => {
getFollowList()
getLeadList()
})
/**
* @description: 定义搜索方法
*/
const handleSearch = async () => {
console.log("搜索");
getFollowList()
getLeadList()
}
const handleReset = () => {
console.log('重置搜索')
@ -100,7 +100,7 @@ const handleReset = () => {
startTime: '',
endTime: '',
}
getFollowList()
getLeadList()
}
const handleExport = () => {
exportToExcel({
@ -113,7 +113,8 @@ const handleExport = () => {
/**
* @description: 定义分页方法
*/
const handleChange = (page: { currentPage: number, size: number }) => {
const handlePaginationChange = (page: { currentPage: number, size: number }) => {
currentPage.value = page.currentPage
getLeadList()
}
</script>

View File

@ -13,7 +13,7 @@
<PositionStatTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" />
<!-- 分页 -->
<PositionStatPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" @change="handleChange" />
<PositionStatPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" @pagination-change="handlePaginationChange" />
</div>
</template>
@ -82,7 +82,7 @@ const handleExport = () => {
/**
* @description: 定义分页方法
*/
const handleChange = (page: {currentPage: number, size: number}) => {
const handlePaginationChange = (page: {currentPage: number, size: number}) => {
currentPage.value = page.currentPage
}
</script>