This commit is contained in:
2026-06-08 16:56:03 +08:00
parent c0f0aeea56
commit 8a35a78ff0
2 changed files with 457 additions and 53 deletions

View File

@ -187,7 +187,133 @@
@close="handleRightClickDialogClose" @close="handleRightClickDialogClose"
> >
<!-- 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw' --> <!-- 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw' -->
<!-- 取款表单特殊处理 -->
<template v-if="rightClickDialogType === 'deposit'">
<div class="withdraw-form">
<!-- 账户信息 -->
<div class="form-section">
<div class="section-title">账户信息</div>
<el-form label-width="120px" label-position="left">
<el-form-item label="账户名">
<el-input v-model="rightClickMarketForm.username" disabled />
</el-form-item>
<el-form-item label="币种">
<el-input v-model="rightClickMarketForm.currency" disabled />
</el-form-item>
</el-form>
</div>
<!-- 金额信息根据角色显示不同字段 -->
<div class="form-section">
<div class="section-title">取款金额</div>
<el-form label-width="140px" label-position="left">
<!-- 手续费佣金 -->
<el-form-item label="手续费佣金">
<el-input
v-model="rightClickMarketForm.withdraw_fee_handle"
type="number"
placeholder="请输入手续费佣金"
@input="handleWithdrawAmountInput('withdraw_fee_handle')"
>
<template #append>最大: {{ rightClickMarketForm.commission_fee_handling_max || '0' }}</template>
</el-input>
</el-form-item>
<!-- 点差佣金 -->
<el-form-item label="点差佣金">
<el-input
v-model="rightClickMarketForm.withdraw_point_diff"
type="number"
placeholder="请输入点差佣金"
@input="handleWithdrawAmountInput('withdraw_point_diff')"
>
<template #append>最大: {{ rightClickMarketForm.commission_point_diff_max || '0' }}</template>
</el-input>
</el-form-item>
<!-- 服务费平台承包商特殊做市商 -->
<el-form-item
v-if="[1, 2, 3].includes(currentRow?.role_id * 1)"
label="服务费"
>
<el-input
v-model="rightClickMarketForm.withdraw_service_fee"
type="number"
placeholder="请输入服务费"
@input="handleWithdrawAmountInput('withdraw_service_fee')"
>
<template #append>最大: {{ rightClickMarketForm.service_max || '0' }}</template>
</el-input>
</el-form-item>
<!-- 风险金仅平台 -->
<el-form-item v-if="currentRow?.role_id === 1" label="风险金">
<el-input
v-model="rightClickMarketForm.withdraw_risk_fee"
type="number"
placeholder="请输入风险金"
@input="handleWithdrawAmountInput('withdraw_risk_fee')"
>
<template #append>最大: {{ rightClickMarketForm.risk_max || '0' }}</template>
</el-input>
</el-form-item>
<!-- 盈利特殊做市商普通做市商 -->
<el-form-item
v-if="[3, 4].includes(currentRow?.role_id * 1)"
label="盈利"
>
<el-input
v-model="rightClickMarketForm.withdraw_head_fee"
type="number"
placeholder="请输入盈利"
@input="handleWithdrawAmountInput('withdraw_head_fee')"
>
<template #append>最大: {{ rightClickMarketForm.closing_profit_max || '0' }}</template>
</el-input>
</el-form-item>
<!-- 合计金额 -->
<el-form-item label="合计取款金额">
<el-input :value="calculateTotalWithdrawAmount(rightClickMarketForm)" disabled>
<template #append>USD</template>
</el-input>
</el-form-item>
</el-form>
</div>
<!-- 必填信息 -->
<div class="form-section">
<div class="section-title">必填信息</div>
<el-form label-width="120px" label-position="left">
<el-form-item label="钱包地址" required>
<el-input
v-model="rightClickMarketForm.withdraw_address"
placeholder="请输入钱包地址"
/>
</el-form-item>
<el-form-item label="取款渠道" required>
<el-select
v-model="rightClickMarketForm.channel_id"
placeholder="请选择取款渠道"
style="width: 100%"
>
<el-option
v-for="item in withdrawChannelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
</div>
</div>
</template>
<!-- 其他表单保持原有逻辑 -->
<MarketForm <MarketForm
v-else
:form-data="rightClickMarketForm" :form-data="rightClickMarketForm"
:form-rules="rightClickMarketFormRules" :form-rules="rightClickMarketFormRules"
:form-items="rightClickMarketFormItemOptions" :form-items="rightClickMarketFormItemOptions"
@ -200,6 +326,7 @@ defineOptions({
name: 'Business', name: 'Business',
}) })
// //
import { nextTick } from 'vue'
import MarketSearch from '@/components/common/Search.vue' import MarketSearch from '@/components/common/Search.vue'
import MarketTable from '@/components/common/Table.vue' import MarketTable from '@/components/common/Table.vue'
import { usePageLoading, useButtonLoading } from '@/composables/useLoading' import { usePageLoading, useButtonLoading } from '@/composables/useLoading'
@ -220,6 +347,8 @@ import {
acceptOrdersFormItemRules, acceptOrdersFormItemRules,
transferFormItemList, transferFormItemList,
transferFormItemRules, transferFormItemRules,
getWithdrawFormConfig,
getWithdrawFormRules,
} from './options' } from './options'
import { useUserStore } from '@/stores/modules/user.ts' import { useUserStore } from '@/stores/modules/user.ts'
import { rules } from './rules' import { rules } from './rules'
@ -236,6 +365,7 @@ import {
updateCapital, updateCapital,
editAgentBail, editAgentBail,
} from '@/api/modules/profile/business.ts' } from '@/api/modules/profile/business.ts'
import { getAgentWithdrawChannel, agentWithdraw } from '@/api/modules/capital/withdraw'
const userStore = useUserStore() const userStore = useUserStore()
@ -443,49 +573,81 @@ const handleRowContextMenu = (row: any, column: any, event: any) => {
const handleAction = (key: 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw') => { const handleAction = (key: 'account' | 'acceptOrders' | 'transfer' | 'deposit' | 'withdraw') => {
console.log('handleAction', key, currentRow.value) console.log('handleAction', key, currentRow.value)
if (!currentRow.value) return if (!currentRow.value) return
switch (key) { // 使
case 'account': rightClickMarketForm.value = {}
rightClickMarketFormItemOptions.value = accountFormItemList nextTick(() => {
rightClickMarketFormRules.value = accountFormItemRules switch (key) {
rightClickMarketForm.value = { case 'account':
target_user_id: currentRow.value!.wallet_capital.user_id, rightClickMarketFormItemOptions.value = accountFormItemList
username: currentRow.value!.username, rightClickMarketFormRules.value = accountFormItemRules
currency: 'USD', rightClickMarketForm.value = {
amount_old: currentRow.value!.wallet_capital.amount, target_user_id: currentRow.value!.wallet_capital.user_id,
amount: null, username: currentRow.value!.username,
amount_new: null, currency: 'USD',
} amount_old: currentRow.value!.wallet_capital.amount,
break amount: null,
case 'acceptOrders': amount_new: null,
rightClickMarketFormItemOptions.value = acceptOrdersFormItemList }
rightClickMarketFormRules.value = acceptOrdersFormItemRules break
rightClickMarketForm.value = { case 'acceptOrders':
target_user_id: currentRow.value!.wallet_capital.user_id, rightClickMarketFormItemOptions.value = acceptOrdersFormItemList
username: currentRow.value!.username, rightClickMarketFormRules.value = acceptOrdersFormItemRules
currency: 'USD', rightClickMarketForm.value = {
bail_stop_order_old: currentRow.value!.wallet_capital.bail_stop_order, target_user_id: currentRow.value!.wallet_capital.user_id,
bail_stop_order: '', username: currentRow.value!.username,
} currency: 'USD',
break bail_stop_order_old: currentRow.value!.wallet_capital.bail_stop_order,
case 'transfer': bail_stop_order: '',
rightClickMarketFormItemOptions.value = transferFormItemList }
rightClickMarketFormRules.value = transferFormItemRules break
rightClickMarketForm.value = { case 'transfer':
target_user_id: currentRow.value!.wallet_capital.user_id, rightClickMarketFormItemOptions.value = transferFormItemList
username: currentRow.value!.username, rightClickMarketFormRules.value = transferFormItemRules
currency: 'USD', rightClickMarketForm.value = {
bail_change_order_old: currentRow.value!.wallet_capital.bail_change_order, target_user_id: currentRow.value!.wallet_capital.user_id,
bail_change_order: '', username: currentRow.value!.username,
} currency: 'USD',
break bail_change_order_old: currentRow.value!.wallet_capital.bail_change_order,
case 'deposit': bail_change_order: '',
break }
case 'withdraw': break
return ElMessage.warning('暂无此功能') case 'deposit':
break // ID
} const targetRoleId = currentRow.value!.role_id * 1
rightClickDialogType.value = key //
rightClickDialogVisible.value = true rightClickMarketFormItemOptions.value = getWithdrawFormConfig(targetRoleId)
rightClickMarketFormRules.value = getWithdrawFormRules(targetRoleId)
//
fetchWithdrawChannel()
//
rightClickMarketForm.value = {
target_user_id: currentRow.value!.wallet_capital.user_id,
username: currentRow.value!.username,
currency: 'USD',
//
commission_fee_handling_max: currentRow.value!.wallet_capital.commission_fee_handling || '0', //
commission_point_diff_max: currentRow.value!.wallet_capital.commission_point_diff || '0', //
service_max: currentRow.value!.wallet_capital.service || '0', //
risk_max: currentRow.value!.wallet_capital.risk || '0', //
closing_profit_max: currentRow.value!.wallet_capital.closing_profit || '0', //
//
withdraw_fee_handle: '',
withdraw_point_diff: '',
withdraw_service_fee: '',
withdraw_risk_fee: '',
withdraw_head_fee: '',
//
withdraw_address: '',
channel_id: '',
}
break
case 'withdraw':
ElMessage.warning('暂无此功能')
return
}
rightClickDialogType.value = key
rightClickDialogVisible.value = true
})
} }
const handleRightClickDialogSubmit = () => { const handleRightClickDialogSubmit = () => {
@ -513,6 +675,7 @@ const handleRightClickDialogSubmit = () => {
}) })
break break
case 'deposit': case 'deposit':
handleWithdrawSubmit()
break break
case 'withdraw': case 'withdraw':
ElMessage.warning('暂无此功能') ElMessage.warning('暂无此功能')
@ -529,6 +692,102 @@ const handleRightClickDialogClose = () => {
rightClickDialogVisible.value = false rightClickDialogVisible.value = false
} }
//
const withdrawChannelOptions = ref<{ label: string; value: number }[]>([])
//
const fetchWithdrawChannel = async () => {
try {
const res = await getAgentWithdrawChannel()
withdrawChannelOptions.value = res.map((item: any) => ({
label: item.name,
value: item.id,
}))
} catch (error) {
console.error('获取取款渠道列表失败', error)
}
}
//
const handleWithdrawSubmit = async () => {
const form = rightClickMarketForm.value
//
if (!form.withdraw_address) {
ElMessage.warning('请输入钱包地址')
return
}
if (!form.channel_id) {
ElMessage.warning('请选择取款渠道')
return
}
//
const params = {
user_id: form.target_user_id,
amount: calculateTotalWithdrawAmount(form),
channel_id: form.channel_id,
withdraw_address: form.withdraw_address,
withdraw_fee_handle: form.withdraw_fee_handle || '0',
withdraw_point_diff: form.withdraw_point_diff || '0',
withdraw_service_fee: form.withdraw_service_fee || '0',
withdraw_head_fee: form.withdraw_head_fee || '0',
withdraw_risk_fee: form.withdraw_risk_fee || '0',
}
try {
startSubmitLoading()
await agentWithdraw(params)
ElMessage.success('取款申请提交成功')
rightClickDialogVisible.value = false
//
getMarketList()
} catch (error) {
console.error('取款提交失败', error)
} finally {
stopSubmitLoading()
}
}
//
const calculateTotalWithdrawAmount = (form: any): string => {
const feeHandle = parseFloat(form.withdraw_fee_handle) || 0
const pointDiff = parseFloat(form.withdraw_point_diff) || 0
const serviceFee = parseFloat(form.withdraw_service_fee) || 0
const headFee = parseFloat(form.withdraw_head_fee) || 0
const riskFee = parseFloat(form.withdraw_risk_fee) || 0
return String(feeHandle + pointDiff + serviceFee + headFee + riskFee)
}
//
const validateWithdrawAmount = (value: string, maxValue: string): boolean => {
if (!value || !maxValue) return true
return parseFloat(value) <= parseFloat(maxValue)
}
//
const handleWithdrawAmountInput = (field: string) => {
const form = rightClickMarketForm.value
const maxFieldMap: Record<string, string> = {
withdraw_fee_handle: 'commission_fee_handling_max',
withdraw_point_diff: 'commission_point_diff_max',
withdraw_service_fee: 'service_max',
withdraw_risk_fee: 'risk_max',
withdraw_head_fee: 'closing_profit_max',
}
const maxField = maxFieldMap[field]
if (!maxField) return
const currentValue = parseFloat(form[field]) || 0
const maxValue = parseFloat(form[maxField]) || 0
if (currentValue > maxValue) {
ElMessage.warning(`输入金额不能超过最大可取金额 ${maxValue}`)
//
form[field] = String(maxValue)
}
}
/** /**
* @description 数据处理方法 * @description 数据处理方法
* 映射表格数据 * 映射表格数据
@ -947,11 +1206,9 @@ const handleSubmit = async () => {
params.flag = 2 params.flag = 2
params.role_id = '5' params.role_id = '5'
} }
// // null
if (marketForm.value.level === '3') { params.is_base_ts = marketForm.value.level === '3' ? marketForm.value.is_base_ts : null
params.is_base_ts = marketForm.value.is_base_ts params.base_ts = marketForm.value.level === '3' && marketForm.value.is_base_ts !== 1 ? marketForm.value.base_ts : null
params.base_ts = marketForm.value.is_base_ts === 1 ? 0 : marketForm.value.base_ts
}
await addMarketApi(params) await addMarketApi(params)
// 5. // 5.
await getMarketList() await getMarketList()
@ -970,11 +1227,9 @@ const handleSubmit = async () => {
flag: flag, flag: flag,
fee_setting_id: '', fee_setting_id: '',
} }
// // null
if (marketForm.value.level === '3') { params.is_base_ts = marketForm.value.level === '3' ? marketForm.value.is_base_ts : null
params.is_base_ts = marketForm.value.is_base_ts params.base_ts = marketForm.value.level === '3' && marketForm.value.is_base_ts !== 1 ? marketForm.value.base_ts : null
params.base_ts = marketForm.value.is_base_ts === 1 ? 0 : marketForm.value.base_ts
}
// 4. // 4.
await editMarketApi(params) await editMarketApi(params)
// 5. // 5.
@ -1096,4 +1351,26 @@ const handleCancel = async () => {
.profit-negative { .profit-negative {
color: #F56C6C; color: #F56C6C;
} }
//
.withdraw-form {
padding: 0 10px;
.form-section {
margin-bottom: 24px;
.section-title {
font-size: 14px;
font-weight: 500;
color: #303133;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 1px solid #ebeef5;
}
.el-form-item {
margin-bottom: 16px;
}
}
}
</style> </style>

View File

@ -145,4 +145,131 @@ export const transferFormItemList = [
export const transferFormItemRules = { export const transferFormItemRules = {
bail_change_order: [{ required: true, message: '请输入调整金额', trigger: ['blur', 'change'] }], bail_change_order: [{ required: true, message: '请输入调整金额', trigger: ['blur', 'change'] }],
}
// 取款表单配置(根据不同角色显示不同字段)
// 平台(1): 币种、手续费佣金、点差佣金、服务费、风险金
// 承包商(2): 币种、手续费佣金、点差佣金、服务费
// 特殊做市商(3): 币种、手续费佣金、点差佣金、服务费、盈利
// 普通做市商(4): 币种、手续费佣金、点差佣金、盈利
// 代理(5): 币种、手续费佣金、点差佣金
export interface WithdrawFormConfig {
prop: string
label: string
type: 'input' | 'select'
disabled?: boolean
required?: boolean
placeholder?: string
max?: number | string
}
export const getWithdrawFormConfig = (roleId: number): WithdrawFormConfig[] => {
const baseConfig: WithdrawFormConfig[] = [
{ prop: 'currency', label: '币种', type: 'input', disabled: true },
]
// 手续费佣金(所有角色都有)
const feeHandlingConfig: WithdrawFormConfig = {
prop: 'withdraw_fee_handle',
label: '手续费佣金',
type: 'input',
required: true,
placeholder: '请输入手续费佣金',
}
// 点差佣金(所有角色都有)
const pointDiffConfig: WithdrawFormConfig = {
prop: 'withdraw_point_diff',
label: '点差佣金',
type: 'input',
required: true,
placeholder: '请输入点差佣金',
}
// 服务费(平台、承包商、特殊做市商)
const serviceFeeConfig: WithdrawFormConfig = {
prop: 'withdraw_service_fee',
label: '服务费',
type: 'input',
required: true,
placeholder: '请输入服务费',
}
// 风险金(仅平台)
const riskFeeConfig: WithdrawFormConfig = {
prop: 'withdraw_risk_fee',
label: '风险金',
type: 'input',
required: true,
placeholder: '请输入风险金',
}
// 盈利(特殊做市商、普通做市商)
const headFeeConfig: WithdrawFormConfig = {
prop: 'withdraw_head_fee',
label: '盈利',
type: 'input',
required: true,
placeholder: '请输入盈利',
}
switch (roleId) {
case 1: // 平台
return [
...baseConfig,
feeHandlingConfig,
pointDiffConfig,
serviceFeeConfig,
riskFeeConfig,
]
case 2: // 承包商
return [
...baseConfig,
feeHandlingConfig,
pointDiffConfig,
serviceFeeConfig,
]
case 3: // 特殊做市商
return [
...baseConfig,
feeHandlingConfig,
pointDiffConfig,
serviceFeeConfig,
headFeeConfig,
]
case 4: // 普通做市商
return [
...baseConfig,
feeHandlingConfig,
pointDiffConfig,
headFeeConfig,
]
case 5: // 一级代理
return [
...baseConfig,
feeHandlingConfig,
pointDiffConfig,
]
default:
return baseConfig
}
}
// 取款表单验证规则
export const getWithdrawFormRules = (roleId: number) => {
const rules: Record<string, any[]> = {
withdraw_address: [{ required: true, message: '请输入钱包地址', trigger: ['blur', 'change'] }],
channel_id: [{ required: true, message: '请选择取款渠道', trigger: ['change'] }],
}
// 添加各角色的验证规则
const config = getWithdrawFormConfig(roleId)
config.forEach((item) => {
if (item.required) {
rules[item.prop] = [{ required: true, message: `请输入${item.label}`, trigger: ['blur', 'change'] }]
}
})
return rules
} }