diff --git a/src/api/modules/account/agent.ts b/src/api/modules/account/agent.ts new file mode 100644 index 0000000..c557ed3 --- /dev/null +++ b/src/api/modules/account/agent.ts @@ -0,0 +1,23 @@ +import { request } from '@/api'; +import type { searchParams, pointDiffConfigParams } from '@/api/types/account/agent' + +// 获取代理列表 +export async function getAgentListApi(params: searchParams): Promise { + return request.get('/agent/getAgentList2', { ...params }) +} +//获取代理点差配置 +export async function getPointDiffConfigApi(params: pointDiffConfigParams): Promise { + return request.get('/agent/getSelfVarietyPointDiffConfig',{...params}) +} +//获取风控模板选项 +export async function getRiskTemplateOptionsApi(): Promise { + return request.get('/agent/getRiskControlOptions') +} +//获取手续费模板选项 +export async function getFeeTemplateOptionsApi(): Promise { + return request.get('user/getFeeSettingOptions') +} +//编辑代理点差 +export async function editPointDiffConfigApi(params: pointDiffConfigParams): Promise { + return request.post('/agent/editAgent',{...params}) +} \ No newline at end of file diff --git a/src/api/modules/account/client.ts b/src/api/modules/account/client.ts index 1d6b8fc..d8e3e03 100644 --- a/src/api/modules/account/client.ts +++ b/src/api/modules/account/client.ts @@ -1,8 +1,8 @@ import { request } from '@/api'; -import type { accountSearchParams, accountListResponse, accountCreateParams } from '@/api/types/account' +import type { searchParams, accountListResponse, accountCreateParams } from '@/api/types/account/client' // 获取客户列表 -export async function getClientListApi(params: accountSearchParams): Promise { +export async function getClientListApi(params: searchParams): Promise { return request.get('/user/getUserList', { ...params }) } diff --git a/src/api/modules/account/market.ts b/src/api/modules/account/market.ts new file mode 100644 index 0000000..2e753bc --- /dev/null +++ b/src/api/modules/account/market.ts @@ -0,0 +1,12 @@ +import { request } from '@/api'; +import type{ searchParams,pointDiffConfigParams } from '@/api/types/account/market' + +// 查询做市商列表 +export async function getMarketListApi(params: searchParams): Promise { + return request.get('agent/getAgentList', { ...params }) +} + +//获取代理点差配置 +export async function getPointDiffConfigApi(params: pointDiffConfigParams): Promise { + return request.get('/agent/getSelfVarietyPointDiffConfig',{...params}) +} \ No newline at end of file diff --git a/src/api/modules/system/menu.ts b/src/api/modules/system/menu.ts index 08c082a..8fe3076 100644 --- a/src/api/modules/system/menu.ts +++ b/src/api/modules/system/menu.ts @@ -3,7 +3,7 @@ import type { MenuFormParams, DeleteMenuParams, MenuListResponse -} from '@/api/types/menu'; +} from '@/api/types/system/menu'; /** * 获取菜单列表 diff --git a/src/api/modules/system/role.ts b/src/api/modules/system/role.ts index 1b75072..27ff165 100644 --- a/src/api/modules/system/role.ts +++ b/src/api/modules/system/role.ts @@ -6,7 +6,7 @@ import type { GetRolePermissionParams, RoleListResponse, PermissionIdsResponse -} from '@/api/types/role'; +} from '@/api/types/system/role'; /** * 获取角色列表 diff --git a/src/api/types/account.d.ts b/src/api/types/account.d.ts index 00b63dd..100a94c 100644 --- a/src/api/types/account.d.ts +++ b/src/api/types/account.d.ts @@ -1,11 +1,5 @@ -/** - * @description 客户列表查询参数 - * @param {accountSearchParams} params - 查询参数类型 - * @response {accountListResponse} 客户列表响应类型 - * - */ -// 客户列表查询参数 -export interface accountSearchParams { +// 通用查询参数 +export interface searchParams { page?: number page_size?: number username?: string @@ -14,6 +8,14 @@ export interface accountSearchParams { reg_end_time?: string } +/** + * @description 客户列表查询参数 + * @param {accountSearchParams} params - 查询参数类型 + * @response {accountListResponse} 客户列表响应类型 + * + */ + + // 定义列表项的类型 interface UserItem { id: number; @@ -33,6 +35,7 @@ export interface accountListResponse { data: UserItem[]; total: number; per_page: number; + current_page: number; } /** @@ -53,3 +56,8 @@ export interface accountCreateParams { is_levelup?: number; status?: number; } + +//获取代理点差配置 +export interface pointDiffConfigParams { + user_id: number | string +} \ No newline at end of file diff --git a/src/api/types/account/agent.d.ts b/src/api/types/account/agent.d.ts new file mode 100644 index 0000000..5ed7719 --- /dev/null +++ b/src/api/types/account/agent.d.ts @@ -0,0 +1,16 @@ +// 通用查询参数 +export interface searchParams { + page?: number + page_size?: number + username?: string + status?: string | number + reg_start_time?: string + reg_end_time?: string + user_name?: string +} + + +//获取代理点差配置 +export interface pointDiffConfigParams { + user_id: number | string +} \ No newline at end of file diff --git a/src/api/types/account/client.d.ts b/src/api/types/account/client.d.ts new file mode 100644 index 0000000..52cfacb --- /dev/null +++ b/src/api/types/account/client.d.ts @@ -0,0 +1,58 @@ +// 通用查询参数 +export interface searchParams { + page?: number + page_size?: number + username?: string + status?: string | number + reg_start_time?: string + reg_end_time?: string +} + +/** + * @description 客户列表查询参数 + * @param {accountSearchParams} params - 查询参数类型 + * @response {accountListResponse} 客户列表响应类型 + * + */ + + +// 定义列表项的类型 +interface UserItem { + id: number; + username: string; + par_uid: number; + created_at: string; // 时间字符串类型 + status: number; + parent: ParentUser; // 嵌套的父级用户对象 +} + +// 定义完整响应数据的类型 +interface UserResponse { + data: UserItem[]; // 数据是 UserItem 类型的数组 +} + +export interface accountListResponse { + data: UserItem[]; + total: number; + per_page: number; + current_page: number; +} + +/** + * @description 客户创建类型 + * @param {accountCreateParams} params - 创建参数类型 + * @response {void} 无响应体 + */ +// 客户创建类型 +export interface accountCreateParams { + reg_type?: number + email?: string + mobile?: string + parent_id?: number | string + fee_setting_id?: number | string + risk_control_id?: number | string + user_id?: string; + username?: string; + is_levelup?: number; + status?: number; +} \ No newline at end of file diff --git a/src/api/types/account/market.d.ts b/src/api/types/account/market.d.ts new file mode 100644 index 0000000..b861522 --- /dev/null +++ b/src/api/types/account/market.d.ts @@ -0,0 +1,8 @@ +// 查询参数 +export interface searchParams { + user_name?: string +} +//获取代理点差配置 +export interface pointDiffConfigParams { + user_id: number | string +} \ No newline at end of file diff --git a/src/api/types/menu.d.ts b/src/api/types/system/menu.d.ts similarity index 96% rename from src/api/types/menu.d.ts rename to src/api/types/system/menu.d.ts index f7fb633..4e3f014 100644 --- a/src/api/types/menu.d.ts +++ b/src/api/types/system/menu.d.ts @@ -1,4 +1,4 @@ -import type { ApiResponse } from './index'; +import type { ApiResponse } from '../index'; /** 菜单基础参数类型(新增/编辑通用) */ export interface MenuFormParams { diff --git a/src/api/types/role.d.ts b/src/api/types/system/role.d.ts similarity index 95% rename from src/api/types/role.d.ts rename to src/api/types/system/role.d.ts index bb8edff..6013ee5 100644 --- a/src/api/types/role.d.ts +++ b/src/api/types/system/role.d.ts @@ -1,4 +1,4 @@ -import type { ApiResponse } from './index'; +import type { ApiResponse } from '../index'; // 角色基础参数(创建/编辑通用) export interface RoleFormParams { diff --git a/src/components/common/Pagination.vue b/src/components/common/Pagination.vue index 3586f9d..10b82c0 100644 --- a/src/components/common/Pagination.vue +++ b/src/components/common/Pagination.vue @@ -1,9 +1,8 @@ @@ -32,7 +31,7 @@ const props = defineProps({ // 可选的每页条数 pageSizes: { type: Array, - default: () => [10, 20, 50, 100] + default: () => [1, 10, 20, 50, 100] as unknown[] }, // 是否禁用分页 disabled: { @@ -44,16 +43,6 @@ const props = defineProps({ type: Boolean, default: true }, - // 是否为小型分页 - small: { - type: Boolean, - default: false - }, - // 只有一页时是否隐藏 - hideOnSinglePage: { - type: Boolean, - default: true - }, // 分页布局(Element Plus 原生配置) layout: { type: String, @@ -112,5 +101,6 @@ const handleCurrentChange = (val: number) => { position: fixed; bottom: 20px; right: 20px; + z-index: 1000; } diff --git a/src/components/common/Table.vue b/src/components/common/Table.vue index 04e4963..4e729e3 100644 --- a/src/components/common/Table.vue +++ b/src/components/common/Table.vue @@ -44,4 +44,11 @@ const props = withDefaults(defineProps(), { border: true, highlightCurrentRow: true, }) - \ No newline at end of file + + + diff --git a/src/components/layout/Sidebar.vue b/src/components/layout/Sidebar.vue index 7f31b5c..4c35298 100644 --- a/src/components/layout/Sidebar.vue +++ b/src/components/layout/Sidebar.vue @@ -115,7 +115,7 @@ const staticMenuList = ref( { id: 33, label: '做市商管理', - path: '3-3', // index="3-3" + path: '/account/market-maker', // index="3-3" icon: '' } ] diff --git a/src/router/index.ts b/src/router/index.ts index 6924704..5512f55 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -110,6 +110,14 @@ const routes = [ meta: { title: '代理管理', // 左侧菜单显示的标题 } + }, + { + path: 'market-maker', + name: 'MarketMaker', + component: () => import('@/views/account/market-maker/index.vue'), + meta: { + title: '做市商管理', // 左侧菜单显示的标题 + } } ] }, diff --git a/src/views/account/agent/index.vue b/src/views/account/agent/index.vue index 89fa338..2811c24 100644 --- a/src/views/account/agent/index.vue +++ b/src/views/account/agent/index.vue @@ -4,19 +4,29 @@ @reset="handleReset"> - + + + + + - - - + + @@ -27,9 +37,13 @@ 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 AgentForm from '@/components/common/Form.vue' + +//接口 +import { getAgentListApi, getPointDiffConfigApi, getRiskTemplateOptionsApi, getFeeTemplateOptionsApi,editPointDiffConfigApi } from '@/api/modules/account/agent' // 引入配置 -import { agentSearch, agentTableColumns, agentPointTableColumns } from './options' +import { agentSearch, agentTableColumns, agentPointTableColumns, PointDiffFormItem } from './options' //定义客户搜索表单配置 const agentSearchOptions = ref(agentSearch) @@ -39,7 +53,7 @@ const agentSearchForm = ref({ startDateTime: '', endDateTime: '', page: 1, - pageSize: 10, + pageSize: 100, total: 100, }) @@ -48,12 +62,266 @@ const agentTree = ref([]) const agentTableColumnsOptions = ref(agentTableColumns) // 定义弹窗配置 -const dialogVisible = ref(true) +const dialogVisible = ref(false) const dialogTitle = ref('查看点差') +const dialogFullscreen = ref(false) const dialogType = ref('add') -const dialogWidth = ref('100%') const agentPointTree = ref([]) const agentPointTableColumnsOptions = ref(agentPointTableColumns) + +// 定义弹窗表单配置 +const isEdit = ref(false) +const agentFormItems = ref(PointDiffFormItem) +const agentFormRules = ref({ + username: [{ required: true, message: '请输入代理名称', trigger: ['blur'] }], + parentUsername: [{ required: true, message: '请输入所属上级', trigger: ['blur'] }], + feeRate: [{ required: true, message: '请输入手续费', trigger: ['blur'] }], + riskTemplate: [{ required: true, message: '请选择风控模板', trigger: ['change'] }], + feeTemplate: [{ required: true, message: '请选择手续费模板', trigger: ['change'] }], +}) +const agentForm = ref({ + username: '', + parentUsername: '', + feeRate: '', + riskTemplate: '', + feeTemplate: '', +}) +const agentFormOptionsMap = ref({ + riskTemplate: [], + feeTemplate: [], +}) + + + +/** + * @description 统一获取数据 + */ +/** + * 处理字符串数值:转数字 + 相加 + 保留五位小数 + * @param {Array} strNums - 待处理的字符串数值数组(如 ["0.00000", "0.00000"]) + * @returns {number} 相加后保留五位小数的数字(最终结果) + */ +function sumStrNumsWith5Decimals(strNums: string[]) { + // 1. 初始化总和 + let total = 0; + + // 2. 遍历数组,逐个转换并累加 + strNums.forEach(strNum => { + // 转数字(处理空值/非数字,兜底为0) + const num = parseFloat(strNum) || 0; + total += num; + }); + + // 3. 保留五位小数(四舍五入),转回数字类型 + const result = parseFloat(total.toFixed(5)); + + return result; +} + +// 映射对象为数组通用方法 +const mapObjectToOptions = (obj: Record) => { + console.log('obj', obj) + return Object.entries(obj).map(([label, value]) => ({ + label, // 模板/代理名称 + value // 模板/代理ID + })) +} + +//获取代理列表 +const fetchAgentList = async () => { + const params = { + page: agentSearchForm.value.page, + page_size: agentSearchForm.value.pageSize, + user_name: agentSearchForm.value.username, + reg_start_time: agentSearchForm.value.startDateTime.length > 0 ? `${agentSearchForm.value.startDateTime} 0:00:00` : '', + reg_end_time: agentSearchForm.value.endDateTime.length > 0 ? `${agentSearchForm.value.endDateTime} 23:59:59` : '', + } + try { + const data = await getAgentListApi(params) + //分页数据 + agentSearchForm.value.total = data.total || 0 + agentSearchForm.value.pageSize = Number(data.per_page) || 0 + + // 表格数据 + agentTree.value = data.data.map((item: any) => { + + //针对当前item提取需要相加的字段(每次循环都重新取当前行数据) + const walletNums = [ + // 兜底空值,避免undefined导致计算错误 + item.wallet_capital?.commission_fee_handling || '0.00000', + item.wallet_capital?.commission_point_diff || '0.00000' + ]; + // 计算当前行的累加值 + const rebateTotalAmount = sumStrNumsWith5Decimals(walletNums); + + return { + ...item, + createTime: item.created_at || '', + feeRate: item.wallet_capital.fee_handling_percent, + rebateRate: item.wallet_capital.commission_fee_handling, + pointDifference: item.wallet_capital.commission_point_diff, + rebateTotalAmount: rebateTotalAmount, + clientCount: item.son_user.length, + level: item.role.title, + parentUsername: item.par_uid === item.parent.id ? item.parent.username : '', + } + }) + } catch (err) { + console.error('获取代理列表失败', err) + } +} +//获取代理点差配置 +const fetchAgentPointDiffConfig = async (id: number | string) => { + console.log(id) + const params = { + user_id: id + } + try { + const data = await getPointDiffConfigApi(params) + // 表格数据 + agentPointTree.value = data.data.map((item: any) => ({ + ...item, + varietyName: item.name, + varietyCode: item.code, + pointDifference: item.point_diff, + assignedPointDifference: item.target_point_diff + })) + } catch (err) { + console.error('获取代理点差配置失败', err) + } +} + +//统一获取表单选项 +const optionsFetched = ref(false) +const getOptions = async () => { + // 已获取过选项则直接返回,避免重复请求 + if (optionsFetched.value) return + + try { + const [riskTemplateRes, feeTemplateRes] = await Promise.all([ + getRiskTemplateOptionsApi(), // 风控模板请求 → 对应 riskTemplateRes + getFeeTemplateOptionsApi(), // 手续费模板请求 → 对应 feeTemplateRes + ]) + console.log('获取表单选项:', riskTemplateRes, feeTemplateRes) + // 修正映射:label=名称,value=ID + + agentFormOptionsMap.value.riskTemplate = mapObjectToOptions(feeTemplateRes as Record) + agentFormOptionsMap.value.feeTemplate = riskTemplateRes.map((item: any) => ({ + label: item.name, + value: item.id + })) + + optionsFetched.value = true // 标记已获取 + } catch (error) { + console.error('获取表单选项失败:', error) + } +} + + +/** + * @description 页面加载完成后获取数据 + */ +onMounted(() => { + fetchAgentList() +}) + +/** + * @description 搜索方法 + */ +const handleSearch = () => { + fetchAgentList() +} +const handleReset = () => { + // 处理重置逻辑 + agentSearchForm.value = { + username: '', + status: '正常', + startDateTime: '', + endDateTime: '', + page: 1, + pageSize: 10, + total: 100, + } + fetchAgentList() +} +const handleDialogType = (type: string) => { + console.log('handleDialogType', type) + if (type === 'edit') { + isEdit.value = true + dialogFullscreen.value = false + } else { + isEdit.value = false + dialogFullscreen.value = true + } +} + +/** + * @description 查看点差方法 + */ +const handlePointDifference = (row: any) => { + dialogVisible.value = true + dialogTitle.value = '查看点差' + dialogType.value = 'view' + handleDialogType(dialogType.value) + console.log(dialogType.value) + fetchAgentPointDiffConfig(row.id) +} + +/** + * @description 编辑方法 + */ +const handleEdit = (row: any) => { + dialogVisible.value = true + dialogTitle.value = '编辑点差' + dialogType.value = 'edit' + dialogFullscreen.value = false + handleDialogType(dialogType.value) + console.log(dialogType.value) + getOptions() + // fetchAgentPointDiffConfig(row.id) + +} + +/** + * @description 分页方法 + */ +const handlePaginationChange = (page: { currentPage: number, pageSize: number }) => { + agentSearchForm.value.page = page.currentPage + agentSearchForm.value.pageSize = page.pageSize + handleSearch() +} + +/** + * @description dialog方法 + */ + +const handleSubmit = async () => { + if (dialogType.value === 'edit') { + const params = { + user_id: "", + toucun_percent: "", + point_diffs_json: "", + fee_handling_percent: "", + } + await editPointDiffConfigApi(params) + await fetchAgentList() + dialogVisible.value = false + } else { + + } +} + +// 弹窗取消 +const handleCancel = () => { + dialogVisible.value = false + dialogType.value = 'view' +} + +// 弹窗关闭 +const handleClose = () => { + dialogVisible.value = false + dialogType.value = 'view' +} diff --git a/src/views/account/agent/options.ts b/src/views/account/agent/options.ts index 881afec..712d1c0 100644 --- a/src/views/account/agent/options.ts +++ b/src/views/account/agent/options.ts @@ -25,17 +25,19 @@ export const agentSearch = [ // 定义表格列配置 export const agentTableColumns = [ - { prop: 'id', label: 'ID', align: 'center' as const }, + { prop: 'id', label: 'ID', align: 'center' as const, width: '80px' }, { 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: 'createTime', label: '注册时间', align: 'center' as const }, + { slotName: 'status', 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: 'pointDifference', label: '点差返佣', align: 'center' as const }, + { slotName: 'pointDifference', 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 }, + { prop: 'parentUsername', label: '所属上级', align: 'center' as const }, + { slotName: 'edit', label: '编辑', align: 'center' as const }, ] @@ -46,3 +48,17 @@ export const agentPointTableColumns = [ { prop: 'pointDifference', label: '可用点差', align: 'center' as const }, { prop: 'assignedPointDifference', label: '已分配点差', align: 'center' as const }, ] + +//编辑点差form配置 +export const PointDiffFormItem = [ + //代理名称 + { prop: 'username', label: '代理名称', type: 'input' as const, placeholder: '代理名称', width: '120px' }, + //所属上级 + { prop: 'parentUsername', label: '所属上级', type: 'input' as const, placeholder: '所属上级', width: '120px' }, + //手续费 + { prop: 'feeRate', label: '手续费', type: 'input' as const, placeholder: '手续费', width: '120px' }, + //风控模板 + { prop: 'riskTemplate', label: '风控模板', type: 'select' as const, placeholder: '风控模板', width: '120px' }, + //手续费模板 + { prop: 'feeTemplate', label: '手续费模板', type: 'select' as const, placeholder: '手续费模板', width: '120px' }, +] diff --git a/src/views/account/client/index.vue b/src/views/account/client/index.vue index 3b95222..788fc7b 100644 --- a/src/views/account/client/index.vue +++ b/src/views/account/client/index.vue @@ -20,8 +20,8 @@ - + ([]) const treeProps = ref({ children: 'parent', + label: 'username' }) // 定义分页配置 const total = ref(0) -const pageSize = ref(1) -const currentPage = ref(1) // 定义dialog配置 const dialogTitle = ref('') @@ -136,6 +135,7 @@ interface ClientFormOptionsMap { riskTemplate: FormOption[]; agentUsername: FormOption[]; isUpgrade: FormOption[]; + status: FormOption[]; } const clientFormOptionsMap = ref({ feeTemplate: [], @@ -145,12 +145,16 @@ const clientFormOptionsMap = ref({ { label: '是', value: 1 }, { label: '否', value: 2 } ], + status: [ + { label: '正常', value: 1 }, + { label: '禁用', value: 2 } + ], }) // 获取账户列表 const fetchClientList = async () => { const params = { - page: clientSearchForm.value.page, + page: clientSearchForm.value.currentPage, page_size: clientSearchForm.value.pageSize, username: clientSearchForm.value.username, status: clientSearchForm.value.status === '正常' ? 1 : 2, @@ -163,12 +167,12 @@ const fetchClientList = async () => { // 映射所属代理用户名 agentUsername: item.par_uid === item.parent?.id ? item.parent?.username : '', })); - //把接口返回的分页字段赋值 - total.value = data.total; // 总条数 - pageSize.value = Number(data.per_page); // 转成数字,和组件保持一致 + //把接口返回的分页字段赋值给分页组件 + total.value = Number(data.total) + clientSearchForm.value.currentPage = Number(data.current_page) + clientSearchForm.value.pageSize = Number(data.per_page) } onMounted(async () => { - console.log('客户列表', clientTree.value) await fetchClientList() }) /** @@ -179,7 +183,6 @@ onMounted(async () => { const handleSearch = async () => { try { await fetchClientList() - console.log('客户列表', clientSearchForm.value) } catch (err) { console.error('获取客户列表失败', err) } @@ -188,13 +191,14 @@ const handleSearch = async () => { // 搜索重置 const handleReset = () => { clientSearchForm.value = { - page: 1, - pageSize: 10, + currentPage: 1, + pageSize: 1, username: '', status: '正常', startDateTime: '', endDateTime: '', } + fetchClientList() // 重置后自动刷新列表 } // 客户表单选项切换 @@ -202,26 +206,36 @@ const handleDialogType = (type: string) => { clientFormOptions.value = type === 'add' ? clientAddFormItem : clientChangeFormItem } +// 映射对象为数组通用方法 +const mapObjectToOptions = (obj: Record) => { + return Object.entries(obj).map(([label, value]) => ({ + label, // 模板/代理名称 + value // 模板/代理ID + })) +} + //统一获取表单选项 +const optionsFetched = ref(false) const getOptions = async () => { + // 已获取过选项则直接返回,避免重复请求 + if (optionsFetched.value) return + try { - // 并行请求,提升性能 const [agentRes, feeTemplateRes, riskTemplateRes] = await Promise.all([ getAgentOptionsApi(), getFeeTemplateOptionsApi(), getRiskTemplateOptionsApi() - ]); + ]) - const agentOptions = mapObjectToOptions(agentRes as Record); - const feeTemplateOptions = mapObjectToOptions(feeTemplateRes as Record); - const riskTemplateOptions = mapObjectToOptions(riskTemplateRes as Record); + // 修正映射:label=名称,value=ID + clientFormOptionsMap.value.agentUsername = mapObjectToOptions(agentRes as Record) + clientFormOptionsMap.value.feeTemplate = mapObjectToOptions(feeTemplateRes as Record) + clientFormOptionsMap.value.riskTemplate = mapObjectToOptions(riskTemplateRes as Record) - // 更新表单选项 - clientFormOptionsMap.value.agentUsername = agentOptions; - clientFormOptionsMap.value.feeTemplate = feeTemplateOptions; - clientFormOptionsMap.value.riskTemplate = riskTemplateOptions; + optionsFetched.value = true // 标记已获取 } catch (error) { - console.error('获取表单选项失败:', error); + console.error('获取表单选项失败:', error) + ElMessage.error('获取表单选项失败,请稍后重试') } } @@ -252,8 +266,9 @@ const handleChange = async (row: any) => { } // 分页事件 -const handlePaginationChange = (page: number) => { - clientSearchForm.value.page = page +const handlePaginationChange = (page: { currentPage: number, pageSize: number }) => { + clientSearchForm.value.currentPage = page.currentPage + clientSearchForm.value.pageSize = page.pageSize handleSearch() } @@ -261,15 +276,6 @@ const handlePaginationChange = (page: number) => { * @description: dialog事件 */ - -// 映射对象为数组通用方法 -const mapObjectToOptions = (obj: Record) => { - return Object.entries(obj).map(([label, value]) => ({ - label: label, // 模板名称作为显示标签 - value: value // 模板ID作为对应值 - })); -} - // 客户添加 const handleAdd = async () => { dialogVisible.value = true @@ -296,7 +302,6 @@ const handleSubmit = async () => { await fetchClientList() dialogVisible.value = false } else { - console.log('编辑客户', clientForm.value) const params = { user_id: clientForm.value.id, risk_control_id: clientForm.value.riskTemplate, diff --git a/src/views/account/client/options.ts b/src/views/account/client/options.ts index 4380b85..50c654a 100644 --- a/src/views/account/client/options.ts +++ b/src/views/account/client/options.ts @@ -55,7 +55,7 @@ export const clientTableColumns = [ { prop: 'created_at', label: '注册时间', align: 'center' as const }, { prop: 'agentUsername', label: '所属代理', align: 'center' as const }, { label: '状态', slotName: 'status', align: 'center' as const }, - { label: '操作', slotName: 'action', align: 'center' as const } + { label: '操作', slotName: 'action', align: 'center' as const } ] //定义添加客户form配置 @@ -65,7 +65,7 @@ export const clientAddFormItem = [ { prop: 'feeTemplate', label: '手续费模板', type: 'select' as const, placeholder: '选择手续费模板' }, { prop: 'riskTemplate', label: '风控模板', type: 'select' as const, placeholder: '选择风控模板' }, { prop: 'agentUsername', label: '所属上级', type: 'select' as const, placeholder: '所属上级' }, - { prop: 'phoneOrEmail', label: '', type: 'slot' as const, slotName: 'phoneOrEmail'}, + { prop: 'phoneOrEmail', label: '', type: 'slot' as const, slotName: 'phoneOrEmail' }, ] //定义修改客户form配置 @@ -74,20 +74,21 @@ export const clientChangeFormItem = [ { prop: 'riskTemplate', label: '风控模板', type: 'select' as const, placeholder: '选择风控模板' }, { prop: 'changeName', label: '客户名称', type: 'input' as const, placeholder: '客户名称' }, { prop: 'isUpgrade', label: '是否升级为代理', type: 'radio' as const, placeholder: '是否升级为代理', labelWidth: '140px' }, + { prop: 'status', label: '选择状态', type: 'radio' as const, placeholder: '请选择状态', labelWidth: '140px' }, ] // 国家码选项 interface CountryItem { - name: string - code: string + name: string + code: string } export const countryOptions = ref([ - { name: '中国', code: '+86' }, - { name: '中国台湾', code: '+886' }, - { name: '中国香港', code: '+852' }, - { name: '中国澳门', code: '+853' }, - { name: '韩国', code: '+82' }, - { name: '美国', code: '+1' }, - { name: '新加坡', code: '+65' } + { name: '中国', code: '+86' }, + { name: '中国台湾', code: '+886' }, + { name: '中国香港', code: '+852' }, + { name: '中国澳门', code: '+853' }, + { name: '韩国', code: '+82' }, + { name: '美国', code: '+1' }, + { name: '新加坡', code: '+65' } ]) \ No newline at end of file diff --git a/src/views/account/client/rules.ts b/src/views/account/client/rules.ts index 6035bc6..f40a49d 100644 --- a/src/views/account/client/rules.ts +++ b/src/views/account/client/rules.ts @@ -27,6 +27,10 @@ export const rules = (): FormRules => { isUpgrade: [ { required: true, message: '请选择是否升级为代理', trigger: ['blur'] }, ], + //选择状态 + status: [ + { required: true, message: '请选择状态', trigger: ['blur'] }, + ], //客户名称 changeName: [ { required: true, message: '请输入客户名称', trigger: ['blur'] }, diff --git a/src/views/account/market-maker/index.vue b/src/views/account/market-maker/index.vue index 0fbd73e..d4c0f49 100644 --- a/src/views/account/market-maker/index.vue +++ b/src/views/account/market-maker/index.vue @@ -1,5 +1,307 @@ + + + diff --git a/src/views/account/market-maker/options.ts b/src/views/account/market-maker/options.ts new file mode 100644 index 0000000..9f6be99 --- /dev/null +++ b/src/views/account/market-maker/options.ts @@ -0,0 +1,64 @@ +//做市商搜索配置 + +export const marketSearch = [ + { label: '账户名', prop: 'accountName', type: 'input', placeholder: '请输入账户名', width: '340px', }, +] + +export const marketTableColumns = [ + { label: 'ID', prop: 'id', align: 'center' as const }, + //代理关系 + { label: '代理关系', prop: 'agentRelation', align: 'center' as const }, + //账户名 + { label: '账户名', prop: 'accountName', align: 'center' as const }, + //级别 + { label: '级别', prop: 'level', align: 'center' as const }, + //基本账户 + { label: '基本账户', prop: 'basicAccount', align: 'center' as const }, + //保证金 + { label: '保证金', prop: 'margin', align: 'center' as const }, + //停止接单保证金 + { label: '停止接单保证金', prop: 'stopOrderMargin', align: 'center' as const, width: '160px' }, + //持仓转移保证金 + { label: '持仓转移保证金', prop: 'positionTransferMargin', align: 'center' as const, width: '160px' }, + //点差返佣 + { label: '点差返佣', prop: 'pointSpreadCommission', align: 'center' as const }, + //点差 + { label: '点差', slotName: 'pointSpread', align: 'center' as const }, + //手续费比例 + { label: '手续费比例', prop: 'commissionRatio', align: 'center' as const }, + //手续费返佣 + { label: '手续费返佣', prop: 'commissionReturn', align: 'center' as const }, + //平仓盈亏 + { label: '平仓盈亏', prop: 'closeProfitLoss', align: 'center' as const }, + //浮动盈亏 + { label: '浮动盈亏', prop: 'floatProfitLoss', align: 'center' as const }, + //风险金 + { label: '风险金', prop: 'riskMargin', align: 'center' as const }, + //服务费 + { label: '服务费', prop: 'serviceFee', align: 'center' as const }, +] + +//做市商添加配置 +export const marketFormItem = [ + { label: '账户名称', prop: 'accountName', type: 'input', placeholder: '请输入账户名称', }, + //级别 + { + label: '级别', prop: 'level', type: 'select', placeholder: '请选择级别', options: [ + { label: '一级', value: '1' }, + { label: '二级', value: '2' }, + { label: '三级', value: '3' }, + ] + }, + //所属上级 + { label: '所属上级', prop: 'parentAccountName', type: 'select', placeholder: '请输入所属上级账户名称', }, + //头寸 + { label: '头寸', prop: 'position', type: 'input', placeholder: '请输入头寸', }, + //手续费 + { label: '手续费', prop: 'commissionRatio', type: 'input', placeholder: '请输入手续费', }, +] +export const marketPointTableColumns = ([ + { 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 }, +]) \ No newline at end of file diff --git a/src/views/user/Login.vue b/src/views/user/Login.vue index dad4bd4..7fdf850 100644 --- a/src/views/user/Login.vue +++ b/src/views/user/Login.vue @@ -126,7 +126,7 @@ const handleLogin = async () => { mobile: loginForm.value.phone, login_type: getStorage('loginType', 'session') === 'email' ? 1 : 2, code: loginForm.value.code, - password: md5Encrypt(loginForm.value.password) + password: loginForm.value.password }; await userStore.login(loginParams); activeTab.value = 'email'; // 重置tab