BUG修复及代理列表

This commit is contained in:
Songsl 2026-04-27 17:57:38 +08:00
parent 12dd2268ac
commit bfe93f348d
10 changed files with 903 additions and 777 deletions

View File

@ -1,23 +0,0 @@
import { request } from '@/api';
import type { searchParams, pointDiffConfigParams } from '@/api/types/account/agent'
// 获取代理列表
export async function getAgentListApi(params: searchParams): Promise<any> {
return request.get<any>('/agent/getAgentList2', { ...params })
}
//获取代理点差配置
export async function getPointDiffConfigApi(params: pointDiffConfigParams): Promise<any> {
return request.get<any>('/agent/getSelfVarietyPointDiffConfig',{...params})
}
//获取风控模板选项
export async function getRiskTemplateOptionsApi(): Promise<any> {
return request.get<any>('/agent/getRiskControlOptions')
}
//获取手续费模板选项
export async function getFeeTemplateOptionsApi(): Promise<any> {
return request.get<any>('user/getFeeSettingOptions')
}
//编辑代理点差
export async function editPointDiffApi(params: pointDiffConfigParams): Promise<any> {
return request.post<any>('/agent/editAgent',{...params})
}

View File

@ -0,0 +1,7 @@
import { request } from '@/api';
import type { searchParams, pointDiffConfigParams } from '@/api/types/account/agent'
// 获取代理列表
export async function getAgentListApi(params: searchParams): Promise<any> {
return request.get<any>('/agent/getAgentList2', { ...params })
}

View File

@ -1,20 +1,31 @@
<template> <template>
<div> <div>
<!-- 搜索 --> <!-- 搜索 -->
<TransferSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" <TransferSearch
@reset="handleReset"> :search-form="searchForm"
:search-options="searchOptions"
@search="handleSearch"
@reset="handleReset"
>
<template #button="{ form }"> <template #button="{ form }">
<el-button type="primary" @click="handleExport()"> <el-button type="primary" @click="handleExport()"> 导出 </el-button>
导出
</el-button>
</template> </template>
</TransferSearch> </TransferSearch>
<!-- 表格 --> <!-- 表格 -->
<TransferTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="id" ref="tableRef"> <TransferTable
:table-data="tableTree"
:columns="tableColumnsOptions"
row-key="id"
ref="tableRef"
>
</TransferTable> </TransferTable>
<!-- 分页 --> <!-- 分页 -->
<TransferPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <TransferPagination
@pagination-change="handlePaginationChange" /> v-model="currentPage"
v-model:pageSizeValue="pageSize"
:total="total"
@pagination-change="handlePaginationChange"
/>
</div> </div>
</template> </template>
@ -36,7 +47,7 @@ import {exportToExcel} from '@/utils/exportToExcel'
*/ */
const searchForm = ref({ const searchForm = ref({
transferAccount: '', transferAccount: '',
level: '', type: '',
transferTime: '', transferTime: '',
}) })
const searchOptions = ref(search) const searchOptions = ref(search)
@ -59,7 +70,7 @@ const getTransferDetailList = async () => {
const params = { const params = {
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value, page_size: pageSize.value,
type: '', type: searchForm.value.type || '',
start_time: searchForm.value.transferTime?.[0] || '2026-02-20 0:00:00', start_time: searchForm.value.transferTime?.[0] || '2026-02-20 0:00:00',
end_time: searchForm.value.transferTime?.[1] || '2026-03-20 23:59:59', end_time: searchForm.value.transferTime?.[1] || '2026-03-20 23:59:59',
user_name: searchForm.value.transferAccount || '', user_name: searchForm.value.transferAccount || '',
@ -84,7 +95,6 @@ const getTransferDetailList = async () => {
transferAmount: item.amount, transferAmount: item.amount,
// //
arrivalAmount: item.amount, arrivalAmount: item.amount,
})) }))
// //
total.value = data.total total.value = data.total

View File

@ -7,18 +7,18 @@ export const search = [
label: '转账账户', label: '转账账户',
prop: 'transferAccount', prop: 'transferAccount',
type: 'input' as const, type: 'input' as const,
placeholder: '请输入转账账户' placeholder: '请输入转账账户',
}, },
//级别 //级别
{ {
label: '转账类型', label: '转账类型',
prop: 'level', prop: 'type',
type: 'select' as const, type: 'select' as const,
placeholder: '请选择转账类型', placeholder: '请选择转账类型',
options: [ options: [
{ label: '客户', value: '1' }, { label: '客户', value: '1' },
{ label: '三方', value: '2' }, { label: '三方', value: '2' },
] ],
}, },
//选择时间 //选择时间
{ {

View File

@ -1,20 +1,38 @@
<template> <template>
<div> <div>
<!-- 搜索 --> <!-- 搜索 -->
<CustomerListSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" <CustomerListSearch
@reset="handleReset"></CustomerListSearch> :search-form="searchForm"
:search-options="searchOptions"
@search="handleSearch"
@reset="handleReset"
></CustomerListSearch>
<!-- 表格 --> <!-- 表格 -->
<CustomerListTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="userId" <CustomerListTable
:tree-props="treeProps" :default-sort="{ prop: 'createTime', order: 'descending' }" :table-data="tableTree"
@expand-change="handleGetSubList"> :columns="tableColumnsOptions"
row-key="userId"
:default-sort="{ prop: 'createTime', order: 'descending' }"
@expand-change="handleGetSubList"
>
<template #marginRatio="{ row }"> <template #marginRatio="{ row }">
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleMarginRatio(row)"> <el-button
v-if="row.role_id === 5"
type="primary"
size="small"
@click="handleMarginRatio(row)"
>
修改 修改
</el-button> </el-button>
</template> </template>
<template #commissionRatio="{ row }"> <template #commissionRatio="{ row }">
{{ row.commissionRatio }} {{ row.commissionRatio }}
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleCommissionRatio(row)"> <el-button
v-if="row.role_id === 5"
type="primary"
size="small"
@click="handleCommissionRatio(row)"
>
修改 修改
</el-button> </el-button>
</template> </template>
@ -25,25 +43,53 @@
</template> </template>
</CustomerListTable> </CustomerListTable>
<!-- 分页 --> <!-- 分页 -->
<CustomerListPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <CustomerListPagination
@pagination-change="handlePaginationChange" /> v-model="currentPage"
v-model:pageSizeValue="pageSize"
:total="total"
@pagination-change="handlePaginationChange"
/>
<!-- dialog --> <!-- dialog -->
<CustomerListDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" <CustomerListDialog
:fullscreen="dialogFullscreen" :show-footer="dialogType !== 'view'" @confirm="handleSubmit" :visible="dialogVisible"
@cancel="handleCancel" @close="handleClose"> :title="dialogTitle"
<CustomerListTable :table-data="marginRatioTree" :columns="marginRatioTableColumnsOptions" row-key="id" :type="dialogType"
v-if="dialogType === 'editMarginRatio'"> :fullscreen="dialogFullscreen"
:show-footer="dialogType !== 'view'"
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
>
<CustomerListTable
:table-data="marginRatioTree"
:columns="marginRatioTableColumnsOptions"
row-key="id"
v-if="dialogType === 'editMarginRatio'"
style="height: 500px"
>
<template #assignedPointDiff="{ row }"> <template #assignedPointDiff="{ row }">
<el-form :model="row" :rules="marginRatioRules(row)" :ref="el => setFormRef(el, row.id)"> <el-form
:model="row"
:rules="marginRatioRules(row)"
:ref="(el) => setFormRef(el, row.id)"
>
<el-form-item prop="assignedPointDifference"> <el-form-item prop="assignedPointDifference">
<el-input v-model="row.assignedPointDifference" size="small" placeholder="请输入点差" /> <el-input
v-model="row.assignedPointDifference"
size="small"
placeholder="请输入点差"
/>
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
</CustomerListTable> </CustomerListTable>
<CustomerListForm :form-data="commissionRatioForm" :form-rules="commissionRatioFormRules" <CustomerListForm
:form-items="commissionRatioFormItemOptions" ref="commissionRatioFormRef" :form-data="commissionRatioForm"
v-if="dialogType === 'editCommissionRatio'"></CustomerListForm> :form-rules="commissionRatioFormRules"
:form-items="commissionRatioFormItemOptions"
ref="commissionRatioFormRef"
v-if="dialogType === 'editCommissionRatio'"
></CustomerListForm>
</CustomerListDialog> </CustomerListDialog>
<!-- dialog表格 --> <!-- dialog表格 -->
</div> </div>
@ -60,7 +106,8 @@ import CustomerListForm from '@/components/common/Form.vue'
import { search, tableColumns, marginRatioTableColumns, commissionRatioFormItem } from './options' import { search, tableColumns, marginRatioTableColumns, commissionRatioFormItem } from './options'
// //
import { getCustomerListApi, getSelfVarietyPointDiffConfigApi, editCustomerApi } from '@/api/modules/agent/customerList' import { getSelfVarietyPointDiffConfigApi, editCustomerApi } from '@/api/modules/agent/customerList'
import { getAgentListApi } from '@/api/modules/profile/agent.ts'
// //
import { getStorage } from '@/utils/storage' import { getStorage } from '@/utils/storage'
@ -71,7 +118,6 @@ const router = useRouter()
const userInfo: any = getStorage('userInfo') const userInfo: any = getStorage('userInfo')
const userId = ref(userInfo?.id || '') const userId = ref(userInfo?.id || '')
/** /**
* @description: 定义搜索数据 * @description: 定义搜索数据
*/ */
@ -122,7 +168,11 @@ const marginRatioRules = (row: any) => {
return { return {
assignedPointDifference: [ assignedPointDifference: [
{ required: true, message: '请输入数字', trigger: ['blur', 'change'] }, { required: true, message: '请输入数字', trigger: ['blur', 'change'] },
{ pattern: /^\d+(\.\d+)?$/, message: '只能输入数字(可带小数)', trigger: ['blur', 'change'] }, {
pattern: /^\d+(\.\d+)?$/,
message: '只能输入数字(可带小数)',
trigger: ['blur', 'change'],
},
{ {
validator: (rule: any, value: any, callback: any) => { validator: (rule: any, value: any, callback: any) => {
const inputVal = Number(value || 0) const inputVal = Number(value || 0)
@ -134,15 +184,12 @@ const marginRatioRules = (row: any) => {
callback() callback()
} }
}, },
trigger: ['blur', 'change'] trigger: ['blur', 'change'],
} },
] ],
} }
} }
/** /**
* @description: 定义手续费form数据 * @description: 定义手续费form数据
*/ */
@ -154,7 +201,7 @@ const commissionRatioFormRules = {
commissionRatio: [ commissionRatio: [
{ required: true, message: '请输入手续费分成比例', trigger: ['blur', 'change'] }, { required: true, message: '请输入手续费分成比例', trigger: ['blur', 'change'] },
{ pattern: /^\d+(\.\d+)?$/, message: '只能输入数字(可带小数)', trigger: ['blur', 'change'] }, { pattern: /^\d+(\.\d+)?$/, message: '只能输入数字(可带小数)', trigger: ['blur', 'change'] },
] ],
} }
const commissionRatioFormItemOptions = ref(commissionRatioFormItem) const commissionRatioFormItemOptions = ref(commissionRatioFormItem)
const selectId = ref('') const selectId = ref('')
@ -168,38 +215,33 @@ const roleMap: any = {
3: '特殊做市商', 3: '特殊做市商',
4: '普通做市商', 4: '普通做市商',
5: '代理', 5: '代理',
6: '用户' 6: '用户',
} }
/** /**
* @description: 定义公共请求数据方法 * @description: 定义公共请求数据方法
*/ */
// //
const getCustomerList = async (id: string) => { const getCustomerList = async () => {
const params = { const params = {
user_id: id,
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value, page_size: pageSize.value,
user_name: searchForm.value.accountName, 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_start_time: searchForm.value.startTime,
reg_end_time: searchForm.value.endTime.length > 0 ? `${searchForm.value.endTime} 23:59:59` : '2026-03-01 23:59:59', reg_end_time: searchForm.value.endTime,
status: searchForm.value.status, status: searchForm.value.status,
} }
const data: any = await getCustomerListApi(params) const data: any = await getAgentListApi(params)
tableTree.value = data.data.map((item: any) => ({ tableTree.value = data.data.map((item: any) => ({
accountName: item.username, accountName: item.username,
userId: item.id, userId: item.id,
status: item.status === 1 ? '正常' : '禁用', status: item.status === 1 ? '正常' : '禁用',
role: roleMap[item.role_id] || '未知', role: item.role.title || '未知',
accountQty: item.account[0].account_count, accountQty: item.son_user[0].son_user_count,
commissionRatio: item.wallet_capital.fee_handling_percent, commissionRatio: item.wallet_capital.fee_handling_percent,
createTime: item.created_at, createTime: item.created_at,
role_id: item.role_id, role_id: item.role_id,
children: item.role_id === 5 ? [{
hasChildren: true,
}] : undefined,
})) }))
// //
@ -214,12 +256,12 @@ const getSelfVarietyPointDiffConfig = async (id: string) => {
user_id: id, user_id: id,
} }
const data: any = await getSelfVarietyPointDiffConfigApi(params) const data: any = await getSelfVarietyPointDiffConfigApi(params)
marginRatioTree.value = data.data.map((item: any) => ({ marginRatioTree.value = data.map((item: any) => ({
id: item.id, id: item.id,
varietyName: item.name, varietyName: item.name,
varietyCode: item.code, varietyCode: item.code,
pointDifference: item.point_diff, pointDifference: item.point_diff,
assignedPointDifference: item.target_point_diff assignedPointDifference: item.target_point_diff,
})) }))
} }
@ -227,14 +269,14 @@ const getSelfVarietyPointDiffConfig = async (id: string) => {
* @description: 页面加载完成需要请求的数据 * @description: 页面加载完成需要请求的数据
*/ */
onMounted(() => { onMounted(() => {
getCustomerList(userId.value) getCustomerList()
}) })
/** /**
* @description: 定义搜索方法 * @description: 定义搜索方法
*/ */
const handleSearch = async () => { const handleSearch = async () => {
getCustomerList(userId.value) getCustomerList()
} }
const handleReset = () => { const handleReset = () => {
searchForm.value = { searchForm.value = {
@ -243,21 +285,21 @@ const handleReset = () => {
endTime: '', endTime: '',
status: '', status: '',
} }
getCustomerList(userId.value) getCustomerList()
} }
/** /**
* @description: 定义表格方法 * @description: 定义表格方法
*/ */
const handleDetail = (row: any) => { const handleDetail = (row: any) => {
console.log('查看详情', row); console.log('查看详情', row)
router.push(`/agent/customerDetail/${row.userId}`) router.push(`/agent/customerDetail/${row.userId}`)
} }
// //
const handleMarginRatio = (row: any) => { const handleMarginRatio = (row: any) => {
getSelfVarietyPointDiffConfig(row.userId) getSelfVarietyPointDiffConfig(row.userId)
console.log('修改点差', row); console.log('修改点差', row)
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '修改点差' dialogTitle.value = '修改点差'
dialogType.value = 'editMarginRatio' dialogType.value = 'editMarginRatio'
@ -266,11 +308,12 @@ const handleMarginRatio = (row: any) => {
// //
const handleCommissionRatio = (row: any) => { const handleCommissionRatio = (row: any) => {
console.log('修改手续费比例', row); console.log('修改手续费比例', row)
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '修改手续费' dialogTitle.value = '修改手续费'
dialogType.value = 'editCommissionRatio' dialogType.value = 'editCommissionRatio'
selectId.value = row.userId selectId.value = row.userId
commissionRatioForm.value.commissionRatio = row.commissionRatio
} }
// //
@ -284,7 +327,7 @@ const handleGetSubList = async (row: any) => {
reg_end_time: '', reg_end_time: '',
status: '', status: '',
} }
const data: any = await getCustomerListApi(params) const data: any = await getAgentListApi(params)
if (data.data.length === 0) { if (data.data.length === 0) {
ElMessage({ ElMessage({
message: '暂无数据', message: '暂无数据',
@ -302,18 +345,23 @@ const handleGetSubList = async (row: any) => {
commissionRatio: item.wallet_capital.fee_handling_percent, commissionRatio: item.wallet_capital.fee_handling_percent,
createTime: item.created_at, createTime: item.created_at,
role_id: item.role_id, role_id: item.role_id,
children: item.role_id === 5 ? [{ children:
item.role_id === 5
? [
{
hasChildren: true, hasChildren: true,
}] : undefined, },
]
: undefined,
})) }))
} }
/** /**
* @description: 定义分页方法 * @description: 定义分页方法
*/ */
const handlePaginationChange = (page: { currentPage: number, size: number }) => { const handlePaginationChange = (page: { currentPage: number; size: number }) => {
currentPage.value = page.currentPage currentPage.value = page.currentPage
getCustomerList(userId.value) getCustomerList()
} }
/** /**
@ -358,8 +406,12 @@ const handleSubmit = async () => {
if (dialogType.value === 'editCommissionRatio') { if (dialogType.value === 'editCommissionRatio') {
await commissionRatioFormRef.value.validate() await commissionRatioFormRef.value.validate()
try { try {
await editCustomerApi({ ...params, fee_handling_percent: commissionRatioForm.value.commissionRatio }) await editCustomerApi({
...params,
fee_handling_percent: commissionRatioForm.value.commissionRatio,
})
dialogVisible.value = false dialogVisible.value = false
await getCustomerList()
} catch (err) { } catch (err) {
console.log('提交失败:', err) console.log('提交失败:', err)
} }

View File

@ -1,18 +1,28 @@
export const search = [ export const search = [
// 账号名称 // 账号名称
{ prop: 'accountName', label: '账号名称', type: 'input' as const, placeholder: '请输入账号名称', width: '150px' }, {
prop: 'accountName',
label: '账号名称',
type: 'input' as const,
placeholder: '请输入账号名称',
width: '150px',
},
// 开始时间 // 开始时间
{ {
prop: "startTime", label: '注册开始时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器 prop: 'startTime',
label: '注册开始时间',
type: 'date' as const,
dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD',
}, },
// 结束时间 // 结束时间
{ {
prop: "endTime", label: '注册结束时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器 prop: 'endTime',
label: '注册结束时间',
type: 'date' as const,
dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD', valueFormat: 'YYYY-MM-DD',
}, },
// 状态
{ prop: 'status', label: '状态', type: 'select' as const, placeholder: '请选择状态' },
] ]
export const tableColumns = [ export const tableColumns = [
@ -33,7 +43,7 @@ export const tableColumns = [
// 注册时间 // 注册时间
{ prop: 'createTime', label: '注册时间', sortable: true }, { prop: 'createTime', label: '注册时间', sortable: true },
// 操作 // 操作
{ label: '操作', slotName: 'action' } // { label: '操作', slotName: 'action' }
] ]
// 点差表格配置 // 点差表格配置

View File

@ -1,12 +1,14 @@
<template> <template>
<div class="market"> <div class="market">
<!-- 搜索 --> <!-- 搜索 -->
<MarketSearch :search-form="marketSearchForm" :search-options="marketSearchOptions" @search="handleSearch" <MarketSearch
@reset="handleReset"> :search-form="marketSearchForm"
:search-options="marketSearchOptions"
@search="handleSearch"
@reset="handleReset"
>
<template #button="{ form }"> <template #button="{ form }">
<el-button type="primary" @click="handleAddMarket()"> <el-button type="primary" @click="handleAddMarket()"> 添加 </el-button>
添加
</el-button>
<el-button type="primary" :disabled="!selectedRow" @click="handleEditMarket()"> <el-button type="primary" :disabled="!selectedRow" @click="handleEditMarket()">
编辑 编辑
</el-button> </el-button>
@ -14,35 +16,61 @@
</MarketSearch> </MarketSearch>
<!-- 表格 --> <!-- 表格 -->
<MarketTable :table-data="marketTree" :columns="marketTableColumnsOptions" row-key="id" <MarketTable
@row-click="handleRowClick"> :table-data="marketTree"
:columns="marketTableColumnsOptions"
row-key="id"
@row-click="handleRowClick"
>
<template #pointSpread="{ row }"> <template #pointSpread="{ row }">
<el-button type="primary" size="small" @click="handleViewPointDiff(row)"> <el-button type="primary" size="small" @click="handleViewPointDiff(row)"> 查看 </el-button>
查看
</el-button>
</template> </template>
</MarketTable> </MarketTable>
<!-- 分页 --> <!-- 分页 -->
<MarketPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <MarketPagination
@pagination-change="handlePaginationChange" /> v-model="currentPage"
v-model:pageSizeValue="pageSize"
:total="total"
@pagination-change="handlePaginationChange"
/>
</div> </div>
<!-- dialog --> <!-- dialog -->
<MarketDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" :fullscreen="dialogFullscreen" <MarketDialog
:show-footer="dialogType !== 'view'" @confirm="handleSubmit" @cancel="handleCancel" @close="handleClose"> :visible="dialogVisible"
:title="dialogTitle"
:type="dialogType"
:fullscreen="dialogFullscreen"
:show-footer="dialogType !== 'view'"
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
>
<!-- 表单 --> <!-- 表单 -->
<MarketForm :form-data="marketForm" :form-rules="marketFormRules" :form-items="marketFormItemOptions" <MarketForm
:options-map="marketFormOptionsMap" ref="marketFormRef" v-if="dialogType !== 'view'"> :form-data="marketForm"
:form-rules="marketFormRules"
:form-items="marketFormItemOptions"
:options-map="marketFormOptionsMap"
ref="marketFormRef"
v-if="dialogType !== 'view'"
>
<template #phoneOrEmail="{ formData }" v-if="dialogType === 'add'"> <template #phoneOrEmail="{ formData }" v-if="dialogType === 'add'">
<div class="phone-email"> <div class="phone-email">
<div class="tab-btn"> <div class="tab-btn">
<el-button :type="activeTab === 'email' ? 'primary' : 'default'" size="small" <el-button
@click="activeTab = 'email'"> :type="activeTab === 'email' ? 'primary' : 'default'"
size="small"
@click="activeTab = 'email'"
>
邮箱 邮箱
</el-button> </el-button>
<el-button :type="activeTab === 'phone' ? 'primary' : 'default'" size="small" <el-button
@click="activeTab = 'phone'"> :type="activeTab === 'phone' ? 'primary' : 'default'"
size="small"
@click="activeTab = 'phone'"
>
手机号 手机号
</el-button> </el-button>
</div> </div>
@ -52,8 +80,12 @@
</el-form-item> </el-form-item>
<el-form-item prop="phone" class="phone-item" v-if="activeTab === 'phone'"> <el-form-item prop="phone" class="phone-item" v-if="activeTab === 'phone'">
<el-select v-model="marketForm.countryCode" placeholder="请选择国家区号"> <el-select v-model="marketForm.countryCode" placeholder="请选择国家区号">
<el-option v-for="item in countryOptions" :key="item.code" :label="item.code" <el-option
:value="item.code"> v-for="item in countryOptions"
:key="item.code"
:label="item.code"
:value="item.code"
>
<div class="country-option"> <div class="country-option">
<span class="country-name">{{ item.name }}</span> <span class="country-name">{{ item.name }}</span>
<span class="country-code">{{ item.code }}</span> <span class="country-code">{{ item.code }}</span>
@ -68,11 +100,16 @@
</MarketForm> </MarketForm>
<!-- 点差表格 --> <!-- 点差表格 -->
<MarketTable :table-data="marketPointTree" :columns="marketPointTableColumnsOptions" row-key="id"> <MarketTable
:table-data="marketPointTree"
:columns="marketPointTableColumnsOptions"
row-key="id"
style="height: 300px"
>
<template #assignedPointDiff="{ row }"> <template #assignedPointDiff="{ row }">
<el-form :model="row" :rules="rules(marketForm, row)"> <el-form :model="row" :rules="rules(marketForm, row)">
<el-form-item prop="assignedPointDifference"> <el-form-item prop="pointDifference">
<el-input v-model="row.assignedPointDifference" size="small" placeholder="请输入点差" /> <el-input v-model="row.pointDifference" size="small" placeholder="请输入点差" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
@ -89,19 +126,32 @@ import MarketDialog from '@/components/common/Dialog.vue'
import MarketForm from '@/components/common/Form.vue' import MarketForm from '@/components/common/Form.vue'
// //
import { marketSearch, marketTableColumns, marketFormItem, marketPointTableColumns, countryOptions, viewMarketPointTableColumns } from './options' import {
marketSearch,
marketTableColumns,
marketFormItem,
marketPointTableColumns,
countryOptions,
viewMarketPointTableColumns,
} from './options'
import { rules } from './rules' import { rules } from './rules'
// //
import { getMarketListApi, getPointDiffConfigListApi, getParAgentListApi, getRiskTemplateListApi, addMarketApi, editMarketApi } from '@/api/modules/account/market' import {
getMarketListApi,
getPointDiffConfigListApi,
getParAgentListApi,
getRiskTemplateListApi,
addMarketApi,
editMarketApi,
} from '@/api/modules/account/market'
/** /**
* @description 定义搜索数据 * @description 定义搜索数据
*/ */
const marketSearchForm = ref({ const marketSearchForm = ref({
accountName: '' accountName: '',
}) })
const marketSearchOptions = ref(marketSearch) const marketSearchOptions = ref(marketSearch)
@ -158,11 +208,12 @@ const marketFormOptionsMap = ref<{
riskControlTemplate: SelectOption[] riskControlTemplate: SelectOption[]
}>({ }>({
level: [ level: [
{ label: '平台', value: '1' }, // { label: '', value: '1' },
{ label: '承包商', value: '2' }, { label: '承包商', value: '2' },
{ label: '特殊做市', value: '3' }, { label: '特殊做市', value: '3' },
{ label: '普通做市', value: '4' }, { label: '普通做市', value: '4' },
{ label: '一级代理', value: '5' }, { label: '一级代理', value: '5' },
{ label: '二级代理', value: '6' },
], ],
parentAccountName: [], parentAccountName: [],
riskControlTemplate: [], riskControlTemplate: [],
@ -174,8 +225,8 @@ const activeTab = ref('email')
const marketPointTree = ref<any>([]) const marketPointTree = ref<any>([])
const marketPointTableColumnsOptions = computed(() => { const marketPointTableColumnsOptions = computed(() => {
return dialogType.value !== 'view' ? marketPointTableColumns : viewMarketPointTableColumns; return dialogType.value !== 'view' ? marketPointTableColumns : viewMarketPointTableColumns
}); })
// //
const selectedRow = ref<any>(null) const selectedRow = ref<any>(null)
/** /**
@ -197,7 +248,7 @@ const mapMarketTree = (data: any) => {
pointSpreadCommission: item.wallet_capital.commission_point_diff, // pointSpreadCommission: item.wallet_capital.commission_point_diff, //
commissionRatio: item.wallet_capital.fee_handling_percent, // commissionRatio: item.wallet_capital.fee_handling_percent, //
commissionReturn: item.wallet_capital.commission_fee_handling, // commissionReturn: item.wallet_capital.commission_fee_handling, //
floatProfitLoss: "后续添加",// floatProfitLoss: '后续添加', //
closeProfitLoss: item.wallet_capital.closing_profit, // closeProfitLoss: item.wallet_capital.closing_profit, //
riskMargin: item.wallet_capital.risk, // riskMargin: item.wallet_capital.risk, //
serviceFee: item.wallet_capital.service, // serviceFee: item.wallet_capital.service, //
@ -225,12 +276,12 @@ const handleMarketFormLinkage = async (type: 'level' | 'parentAccountName', valu
// //
const data = await getParAgentListApi({ role_id: value }) const data = await getParAgentListApi({ role_id: value })
console.log('datasssssssssssss', data); console.log('datasssssssssssss', data)
// //
marketFormOptionsMap.value.parentAccountName = data.map((item: any) => ({ marketFormOptionsMap.value.parentAccountName = data.map((item: any) => ({
label: item.username, label: item.username,
value: String(item.id), // value: String(item.id), //
row: item row: item,
})) }))
} }
@ -242,7 +293,9 @@ const handleMarketFormLinkage = async (type: 'level' | 'parentAccountName', valu
if (!value) return // if (!value) return //
// value // value
const rulesData = marketFormOptionsMap.value.parentAccountName.find((item) => item.value === value) const rulesData = marketFormOptionsMap.value.parentAccountName.find(
(item) => item.value === value,
)
if (!rulesData) return // if (!rulesData) return //
// //
@ -265,7 +318,6 @@ const handleMarketFormLinkage = async (type: 'level' | 'parentAccountName', valu
} }
} }
/** /**
* @description 统一数据获取 * @description 统一数据获取
*/ */
@ -274,7 +326,7 @@ const getMarketList = async () => {
const params = { const params = {
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value, page_size: pageSize.value,
user_name: marketSearchForm.value.accountName user_name: marketSearchForm.value.accountName,
} }
const data = await getMarketListApi(params) const data = await getMarketListApi(params)
// //
@ -291,7 +343,7 @@ const getRiskTemplateList = async () => {
// //
marketFormOptionsMap.value.riskControlTemplate = data.map((item: any) => ({ marketFormOptionsMap.value.riskControlTemplate = data.map((item: any) => ({
label: item.name, label: item.name,
value: item.id // value: item.id, //
})) }))
} }
@ -313,7 +365,7 @@ watch(
(newLevel) => { (newLevel) => {
handleMarketFormLinkage('level', newLevel) handleMarketFormLinkage('level', newLevel)
}, },
{ immediate: false } // { immediate: false }, //
) )
// //
@ -322,7 +374,7 @@ watch(
(newParentAccountName) => { (newParentAccountName) => {
handleMarketFormLinkage('parentAccountName', newParentAccountName) handleMarketFormLinkage('parentAccountName', newParentAccountName)
}, },
{ immediate: false } { immediate: false },
) )
/** /**
@ -341,8 +393,7 @@ const initMarketForm = {
commissionRatio: '', commissionRatio: '',
maxPositionRatio: '', maxPositionRatio: '',
maxCommissionRatio: '', maxCommissionRatio: '',
}; }
/** /**
* @description search方法 * @description search方法
@ -355,7 +406,7 @@ const handleSearch = async () => {
// //
const handleReset = async () => { const handleReset = async () => {
marketSearchForm.value = { marketSearchForm.value = {
accountName: '' accountName: '',
} }
currentPage.value = 1 currentPage.value = 1
pageSize.value = 10 pageSize.value = 10
@ -369,24 +420,24 @@ const handleAddMarket = async () => {
dialogType.value = 'add' dialogType.value = 'add'
// 2. // 2.
marketForm.value = { ...initMarketForm } marketForm.value = { ...initMarketForm }
dialogFullscreen.value = false; dialogFullscreen.value = false
} }
// //
const handleEditMarket = async () => { const handleEditMarket = async () => {
const row = selectedRow.value; const row = selectedRow.value
console.log('rowrowrowrowrow', row); console.log('rowrowrowrowrow', row)
// ID // ID
const getParentIdFromPath = (path: string, level: number) => { const getParentIdFromPath = (path: string, level: number) => {
const segments = path.split('/').filter(Boolean); const segments = path.split('/').filter(Boolean)
const levelNum = Number(level); const levelNum = Number(level)
const parentIndex = levelNum - 2; const parentIndex = levelNum - 2
if (levelNum <= 1 || segments.length <= parentIndex) return ''; if (levelNum <= 1 || segments.length <= parentIndex) return ''
return segments[parentIndex]; return segments[parentIndex]
}; }
const parentId = getParentIdFromPath(row.path, row.level); const parentId = getParentIdFromPath(row.path, row.level)
console.log('解析后的上级ID:', parentId); console.log('解析后的上级ID:', parentId)
// //
marketForm.value = { marketForm.value = {
@ -399,39 +450,37 @@ const handleEditMarket = async () => {
commissionRatio: row.commissionRatio || '', commissionRatio: row.commissionRatio || '',
maxPositionRatio: row.wallet_capital.toucun_percent || '', maxPositionRatio: row.wallet_capital.toucun_percent || '',
maxCommissionRatio: row.wallet_capital.fee_handling_percent || '', maxCommissionRatio: row.wallet_capital.fee_handling_percent || '',
}; }
console.log(marketForm.value); console.log(marketForm.value)
try { try {
// //
await handleMarketFormLinkage('level', marketForm.value.level); await handleMarketFormLinkage('level', marketForm.value.level)
if (parentId) { if (parentId) {
marketForm.value.parentAccountName = parentId; marketForm.value.parentAccountName = parentId
} }
// //
if (row.id) { if (row.id) {
const data = await getPointDiffConfigListApi({ user_id: row.id }); const data = await getPointDiffConfigListApi({ user_id: row.id })
marketPointTree.value = data.map((item: any) => ({ marketPointTree.value = data.map((item: any) => ({
...item, ...item,
varietyName: item.name, varietyName: item.name,
varietyCode: item.code, varietyCode: item.code,
pointDifference: item.point_diff, pointDifference: item.point_diff,
assignedPointDifference: item.target_point_diff || '', // assignedPointDifference: item.target_point_diff || '', //
})); }))
} }
// //
dialogVisible.value = true; dialogVisible.value = true
dialogTitle.value = '编辑'; dialogTitle.value = '编辑'
dialogType.value = 'edit'; dialogType.value = 'edit'
dialogFullscreen.value = false; dialogFullscreen.value = false
} catch (error) { } catch (error) {
console.error('编辑数据加载失败:', error); console.error('编辑数据加载失败:', error)
}
} }
};
/** /**
* @description 表格方法 * @description 表格方法
@ -439,22 +488,22 @@ const handleEditMarket = async () => {
// //
const handleViewPointDiff = async (row: any) => { const handleViewPointDiff = async (row: any) => {
try { try {
const data = await getPointDiffConfigListApi({ user_id: row.role_id }); const data = await getPointDiffConfigListApi({ user_id: row.role_id })
marketPointTree.value = data.map((item: any) => ({ marketPointTree.value = data.map((item: any) => ({
...item, ...item,
varietyName: item.name, varietyName: item.name,
varietyCode: item.code, varietyCode: item.code,
pointDifference: item.point_diff, pointDifference: item.point_diff,
assignedPointDifference: item.target_point_diff || '' assignedPointDifference: item.target_point_diff || '',
})); }))
// //
dialogVisible.value = true; dialogVisible.value = true
dialogTitle.value = '查看点差'; dialogTitle.value = '查看点差'
dialogType.value = 'view'; dialogType.value = 'view'
dialogFullscreen.value = true; dialogFullscreen.value = true
} catch (error) { } catch (error) {
console.error('加载点差数据失败:', error); console.error('加载点差数据失败:', error)
} }
} }
@ -471,37 +520,44 @@ const handleRowClick = (row: any) => {
* @description 分页方法 * @description 分页方法
*/ */
// //
const handlePaginationChange = async (page: { currentPage: number, pageSize: number }) => { const handlePaginationChange = async (page: { currentPage: number; pageSize: number }) => {
currentPage.value = page.currentPage currentPage.value = page.currentPage
pageSize.value = page.pageSize pageSize.value = page.pageSize
await getMarketList() await getMarketList()
} }
/** /**
* @description dialog方法 * @description dialog方法
*/ */
// : { "1":"42", "2":"38" } // : { "1":"42", "2":"38" }
const formatPointDiffToObject = () => { const formatPointDiffToObject = () => {
if (!marketPointTree.value || !marketPointTree.value.length) return {}; if (!marketPointTree.value || !marketPointTree.value.length) return {}
// //
const pointDiffObj: Record<string, string> = {}; const pointDiffObj: Record<string, string> = {}
console.log(marketPointTree.value)
// { : } // { : }
marketPointTree.value.forEach((item: { id: string | number; assignedPointDifference: string }) => { for (let i = 0; i < marketPointTree.value.length; i++) {
// const item = marketPointTree.value[i]
pointDiffObj[String(item.id)] = item.assignedPointDifference || '0'; if (item.pointDifference > item.point_diff) {
}); ElMessage.error('已分配差值不能大于可分配点差')
return false
}
pointDiffObj[String(item.id)] = item.pointDifference || '0'
}
return pointDiffObj; // return pointDiffObj //
}; }
// //
const handleSubmit = async () => { const handleSubmit = async () => {
// console.log('', marketPointTree.value); // console.log('', marketPointTree.value);
await marketFormRef.value?.validate() await marketFormRef.value?.validate()
const pointDiffObj = formatPointDiffToObject() const pointDiffObj = formatPointDiffToObject()
console.log('pointDiffObj', pointDiffObj)
if (!pointDiffObj) return
if (dialogType.value === 'add') { if (dialogType.value === 'add') {
const params = { const params = {
role_id: marketForm.value.level, role_id: marketForm.value.level,
@ -517,6 +573,11 @@ const handleSubmit = async () => {
risk_control_id: marketForm.value.riskControlTemplate, risk_control_id: marketForm.value.riskControlTemplate,
fee_setting_id: '', fee_setting_id: '',
} }
if (marketForm.value.level === '5') params.flag = 1
if (marketForm.value.level === '6') {
params.flag = 2
params.role_id = '5'
}
await addMarketApi(params) await addMarketApi(params)
// 5. // 5.
await getMarketList() await getMarketList()

View File

@ -75,12 +75,17 @@ export const countryOptions = ref<CountryItem[]>([
]) ])
//编辑点差表格列配置 //编辑点差表格列配置
export const marketPointTableColumns = ([ export const marketPointTableColumns = [
{ prop: 'varietyName', label: '名称', align: 'center' as const }, { prop: 'varietyName', label: '名称', align: 'center' as const },
{ prop: 'varietyCode', label: '编号', align: 'center' as const }, { prop: 'varietyCode', label: '编号', align: 'center' as const },
{ prop: 'pointDifference', label: '可分配点差', align: 'center' as const }, { prop: 'point_diff', label: '可分配点差', align: 'center' as const },
{ prop: 'assignedPointDifference', label: '已分配点差', align: 'center' as const, slotName: 'assignedPointDiff' }, {
]) prop: 'pointDifference',
label: '已分配点差',
align: 'center' as const,
slotName: 'assignedPointDiff',
},
]
// 查看点差表格列配置 // 查看点差表格列配置
export const viewMarketPointTableColumns = ([ export const viewMarketPointTableColumns = ([

View File

@ -85,7 +85,7 @@ import { rules } from './rules'
const clientSearchOptions = ref(clientSearch) const clientSearchOptions = ref(clientSearch)
const clientSearchForm = ref({ const clientSearchForm = ref({
username: '', username: '',
status: '正常', status: 1,
startDateTime: '', startDateTime: '',
endDateTime: '', endDateTime: '',
}) })
@ -172,7 +172,7 @@ const getClientList = async () => {
page: currentPage.value, page: currentPage.value,
page_size: pageSize.value, page_size: pageSize.value,
username: clientSearchForm.value.username, username: clientSearchForm.value.username,
status: clientSearchForm.value.status === '正常' ? 1 : 2, status: clientSearchForm.value.status || '',
reg_start_time: clientSearchForm.value.startDateTime.length > 0 ? `${clientSearchForm.value.startDateTime} 0:00:00` : '', reg_start_time: clientSearchForm.value.startDateTime.length > 0 ? `${clientSearchForm.value.startDateTime} 0:00:00` : '',
reg_end_time: clientSearchForm.value.endDateTime.length > 0 ? `${clientSearchForm.value.endDateTime} 23:59:59` : '', reg_end_time: clientSearchForm.value.endDateTime.length > 0 ? `${clientSearchForm.value.endDateTime} 23:59:59` : '',
} }

View File

@ -306,12 +306,14 @@ const handleEdit = () => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '编辑合约品种' dialogTitle.value = '编辑合约品种'
dialogType.value = 'edit' dialogType.value = 'edit'
dialogFormItemOptions.value[4]!.disabled = true
} }
const handleAdd = () => { const handleAdd = () => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = '添加合约品种' dialogTitle.value = '添加合约品种'
dialogType.value = 'add' dialogType.value = 'add'
dialogFormItemOptions.value[4]!.disabled = false
varietyForm.value = { varietyForm.value = {
varietyName: '', varietyName: '',
varietyCode: '', varietyCode: '',
@ -420,6 +422,8 @@ const handleSubmit = async () => {
if (dialogType.value === 'edit') { if (dialogType.value === 'edit') {
console.log(params) console.log(params)
if (params.point_diff_max < params.point_diff)
return ElMessage.warning('最大点差不能小于最小点差')
await editVarietyApi({ await editVarietyApi({
...params, ...params,
is_default: varietyForm.value.isDefault, is_default: varietyForm.value.isDefault,