调整金额&编辑客户
This commit is contained in:
parent
28c86ad0c4
commit
6d46c13f40
|
|
@ -61,3 +61,28 @@ export async function logoutApi(params: { device_no: string }) {
|
||||||
export async function sendCodeApi(params: SendCodeParams) {
|
export async function sendCodeApi(params: SendCodeParams) {
|
||||||
return request.post<string>('/sendCode', params);
|
return request.post<string>('/sendCode', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整用户金额
|
||||||
|
* @param params 调整金额参数(目标用户ID/调整金额)
|
||||||
|
* @returns Promise<boolean> 调整成功返回true
|
||||||
|
*/
|
||||||
|
export async function updateCapitalApi(params: { target_user_id: number; amount: string }) {
|
||||||
|
return request.post<boolean>('/user/updateCapital', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改用户信息
|
||||||
|
* @param params 修改用户参数(用户ID/风控模板ID/手续费模板ID/用户名/是否升级/状态)
|
||||||
|
* @returns Promise<boolean> 修改成功返回true
|
||||||
|
*/
|
||||||
|
export async function editUserApi(params: {
|
||||||
|
user_id: number;
|
||||||
|
risk_control_id?: string | number;
|
||||||
|
fee_setting_id?: string | number;
|
||||||
|
username?: string;
|
||||||
|
is_levelup?: number;
|
||||||
|
status?: number;
|
||||||
|
}) {
|
||||||
|
return request.post<boolean>('/user/editUser', params);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<CustomerListSearch
|
<CustomerListSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
||||||
:search-form="searchForm"
|
@reset="handleReset"></CustomerListSearch>
|
||||||
:search-options="searchOptions"
|
|
||||||
@search="handleSearch"
|
|
||||||
@reset="handleReset"
|
|
||||||
></CustomerListSearch>
|
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<CustomerListTable
|
<CustomerListTable :table-data="tableTree" :columns="tableColumnsOptions" row-key="userId" :tree-props="treeProps"
|
||||||
:table-data="tableTree"
|
:default-sort="{ prop: 'createTime', order: 'descending' }" @expand-change="handleGetSubList">
|
||||||
:columns="tableColumnsOptions"
|
|
||||||
row-key="userId"
|
|
||||||
:tree-props="treeProps"
|
|
||||||
:default-sort="{ prop: 'createTime', order: 'descending' }"
|
|
||||||
@expand-change="handleGetSubList"
|
|
||||||
>
|
|
||||||
<template #marginRatio="{ row }">
|
<template #marginRatio="{ row }">
|
||||||
<el-button
|
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleMarginRatio(row)">
|
||||||
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
|
<el-button v-if="row.role_id === 5" type="primary" size="small" @click="handleCommissionRatio(row)">
|
||||||
v-if="row.role_id === 5"
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="handleCommissionRatio(row)"
|
|
||||||
>
|
|
||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -43,62 +23,97 @@
|
||||||
<el-button link type="primary" size="small" @click="openDetailDrawer(row)" v-if="row.userId">
|
<el-button link type="primary" size="small" @click="openDetailDrawer(row)" v-if="row.userId">
|
||||||
查看详情
|
查看详情
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
<el-button link type="primary" size="small" @click="handleEditCustomer(row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-divider direction="vertical" />
|
||||||
|
<el-button link type="warning" size="small" @click="handleAdjustAmount(row)">
|
||||||
|
调整金额
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</CustomerListTable>
|
</CustomerListTable>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<CustomerListPagination
|
<CustomerListPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
|
||||||
v-model="currentPage"
|
@pagination-change="handlePaginationChange" />
|
||||||
v-model:pageSizeValue="pageSize"
|
|
||||||
:total="total"
|
|
||||||
@pagination-change="handlePaginationChange"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- dialog -->
|
<!-- dialog -->
|
||||||
<CustomerListDialog
|
<CustomerListDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" :fullscreen="dialogFullscreen"
|
||||||
:visible="dialogVisible"
|
:show-footer="dialogType !== 'view'" @confirm="handleSubmit" @cancel="handleCancel" @close="handleClose">
|
||||||
:title="dialogTitle"
|
<CustomerListTable :table-data="marginRatioTree" :columns="marginRatioTableColumnsOptions" row-key="id"
|
||||||
:type="dialogType"
|
v-if="dialogType === 'editMarginRatio'" style="height: 600px">
|
||||||
: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: 600px"
|
|
||||||
>
|
|
||||||
<template #assignedPointDiff="{ row }">
|
<template #assignedPointDiff="{ row }">
|
||||||
<el-form
|
<el-form :model="row" :rules="marginRatioRules(row)" :ref="(el) => setFormRef(el, row.id)">
|
||||||
:model="row"
|
|
||||||
:rules="marginRatioRules(row)"
|
|
||||||
:ref="(el) => setFormRef(el, row.id)"
|
|
||||||
>
|
|
||||||
<el-form-item style="margin-bottom: 0" prop="assignedPointDifference">
|
<el-form-item style="margin-bottom: 0" prop="assignedPointDifference">
|
||||||
<el-input v-model="row.assignedPointDifference" placeholder="请输入点差" />
|
<el-input v-model="row.assignedPointDifference" placeholder="请输入点差" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
</CustomerListTable>
|
</CustomerListTable>
|
||||||
<CustomerListForm
|
<CustomerListForm :form-data="commissionRatioForm" :form-rules="commissionRatioFormRules"
|
||||||
:form-data="commissionRatioForm"
|
:form-items="commissionRatioFormItemOptions" ref="commissionRatioFormRef"
|
||||||
:form-rules="commissionRatioFormRules"
|
v-if="dialogType === 'editCommissionRatio'"></CustomerListForm>
|
||||||
:form-items="commissionRatioFormItemOptions"
|
</CustomerListDialog>
|
||||||
ref="commissionRatioFormRef"
|
|
||||||
v-if="dialogType === 'editCommissionRatio'"
|
<!-- 调整金额弹窗 -->
|
||||||
></CustomerListForm>
|
<CustomerListDialog :visible="adjustAmountVisible" title="调整金额" type="adjust" @confirm="handleAdjustAmountSubmit"
|
||||||
|
@cancel="handleAdjustAmountCancel" @close="handleAdjustAmountClose">
|
||||||
|
<el-form :model="adjustAmountForm" :rules="adjustAmountRules" ref="adjustAmountFormRef" label-width="120px">
|
||||||
|
<el-form-item label="账号名" prop="username">
|
||||||
|
<el-input v-model="adjustAmountForm.username" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="币种" prop="currency">
|
||||||
|
<el-input v-model="adjustAmountForm.currency" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="当前余额" prop="currentBalance">
|
||||||
|
<el-input v-model="adjustAmountForm.currentBalance" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="调整金额" prop="adjustAmount">
|
||||||
|
<el-input v-model="adjustAmountForm.adjustAmount" placeholder="请输入调整金额(可为负数)"
|
||||||
|
@input="handleAdjustAmountInput" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="调整后余额" prop="afterBalance">
|
||||||
|
<el-input v-model="adjustAmountForm.afterBalance" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</CustomerListDialog>
|
||||||
|
|
||||||
|
<!-- 修改客户弹窗 -->
|
||||||
|
<CustomerListDialog :visible="editCustomerVisible" title="修改客户" type="editCustomer"
|
||||||
|
@confirm="handleEditCustomerSubmit" @cancel="handleEditCustomerCancel" @close="handleEditCustomerClose">
|
||||||
|
<el-form :model="editCustomerForm" :rules="editCustomerRules" ref="editCustomerFormRef" label-width="140px">
|
||||||
|
<el-form-item label="手续费模板" prop="feeSettingId">
|
||||||
|
<el-select v-model="editCustomerForm.feeSettingId" placeholder="请选择手续费模板" style="width: 100%">
|
||||||
|
<el-option v-for="item in feeTemplateOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="风控模板" prop="riskControlId">
|
||||||
|
<el-select v-model="editCustomerForm.riskControlId" placeholder="请选择风控模板" style="width: 100%">
|
||||||
|
<el-option v-for="item in riskTemplateOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="客户名称" prop="username">
|
||||||
|
<el-input v-model="editCustomerForm.username" placeholder="请输入客户名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否升级成代理" prop="isLevelUp">
|
||||||
|
<el-radio-group v-model="editCustomerForm.isLevelUp">
|
||||||
|
<el-radio :label="1">是</el-radio>
|
||||||
|
<el-radio :label="2">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择状态" prop="status">
|
||||||
|
<el-radio-group v-model="editCustomerForm.status">
|
||||||
|
<el-radio :label="1">正常</el-radio>
|
||||||
|
<el-radio :label="2">封禁</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
</CustomerListDialog>
|
</CustomerListDialog>
|
||||||
|
|
||||||
<!-- ===================== 【新增】客户详情抽屉 ===================== -->
|
<!-- ===================== 【新增】客户详情抽屉 ===================== -->
|
||||||
<CustomerDetailDrawer
|
<CustomerDetailDrawer v-model:drawer-visible="detailDrawerVisible" :query-id="detailQueryId"
|
||||||
v-model:drawer-visible="detailDrawerVisible"
|
:drawer-title="detailDrawerTitle" />
|
||||||
:query-id="detailQueryId"
|
|
||||||
:drawer-title="detailDrawerTitle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -127,6 +142,11 @@ import {
|
||||||
getSelfVarietyPointDiffConfigApi,
|
getSelfVarietyPointDiffConfigApi,
|
||||||
editCustomerApi,
|
editCustomerApi,
|
||||||
} from '@/api/modules/agent/customerList'
|
} from '@/api/modules/agent/customerList'
|
||||||
|
import { updateCapitalApi, editUserApi } from '@/api/modules/user'
|
||||||
|
import {
|
||||||
|
getFeeTemplateOptionsApi,
|
||||||
|
getRiskTemplateOptionsApi,
|
||||||
|
} from '@/api/modules/account/client'
|
||||||
|
|
||||||
// 公用方法
|
// 公用方法
|
||||||
import { getStorage } from '@/utils/storage'
|
import { getStorage } from '@/utils/storage'
|
||||||
|
|
@ -231,6 +251,60 @@ const commissionRatioFormRules = {
|
||||||
const commissionRatioFormItemOptions = ref(commissionRatioFormItem)
|
const commissionRatioFormItemOptions = ref(commissionRatioFormItem)
|
||||||
const selectId = ref('')
|
const selectId = ref('')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 定义修改客户弹窗数据
|
||||||
|
*/
|
||||||
|
const editCustomerVisible = ref(false)
|
||||||
|
const editCustomerFormRef = ref()
|
||||||
|
const editCustomerUserId = ref<number>(0)
|
||||||
|
const editCustomerForm = ref({
|
||||||
|
feeSettingId: '',
|
||||||
|
riskControlId: '',
|
||||||
|
username: '',
|
||||||
|
isLevelUp: 2,
|
||||||
|
status: 1,
|
||||||
|
})
|
||||||
|
const editCustomerRules = {
|
||||||
|
feeSettingId: [{ required: true, message: '请选择手续费模板', trigger: 'change' }],
|
||||||
|
riskControlId: [{ required: true, message: '请选择风控模板', trigger: 'change' }],
|
||||||
|
isLevelUp: [{ required: true, message: '请选择是否升级成代理', trigger: 'change' }],
|
||||||
|
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
||||||
|
}
|
||||||
|
const feeTemplateOptions = ref<any[]>([])
|
||||||
|
const riskTemplateOptions = ref<any[]>([])
|
||||||
|
const templateOptionsFetched = ref(false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 定义调整金额弹窗数据
|
||||||
|
*/
|
||||||
|
const adjustAmountVisible = ref(false)
|
||||||
|
const adjustAmountFormRef = ref()
|
||||||
|
const adjustUserId = ref<number>(0)
|
||||||
|
const adjustAmountForm = ref({
|
||||||
|
username: '',
|
||||||
|
currency: '',
|
||||||
|
currentBalance: '',
|
||||||
|
adjustAmount: '',
|
||||||
|
afterBalance: '',
|
||||||
|
})
|
||||||
|
const adjustAmountRules = {
|
||||||
|
adjustAmount: [
|
||||||
|
{ required: true, message: '请输入调整金额', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
if (value === '' || value === null || value === undefined) {
|
||||||
|
callback(new Error('请输入调整金额'))
|
||||||
|
} else if (!/^-?\d+(\.\d{1,5})?$/.test(value)) {
|
||||||
|
callback(new Error('请输入有效的金额格式,最多五位小数'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 角色映射方法
|
* @description: 角色映射方法
|
||||||
*/
|
*/
|
||||||
|
|
@ -277,10 +351,10 @@ const getCustomerList = async (id: string) => {
|
||||||
children:
|
children:
|
||||||
item.role_id === 5
|
item.role_id === 5
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
hasChildren: true,
|
hasChildren: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: undefined,
|
: undefined,
|
||||||
}))
|
}))
|
||||||
console.log('tableTree', tableTree.value)
|
console.log('tableTree', tableTree.value)
|
||||||
|
|
@ -399,10 +473,10 @@ const handleGetSubList = async (row: any) => {
|
||||||
children:
|
children:
|
||||||
item.role_id === 5
|
item.role_id === 5
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
hasChildren: true,
|
hasChildren: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: undefined,
|
: undefined,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
@ -478,6 +552,133 @@ const handleClose = () => {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 调整金额相关方法
|
||||||
|
*/
|
||||||
|
// 打开调整金额弹窗
|
||||||
|
const handleAdjustAmount = (row: any) => {
|
||||||
|
adjustAmountVisible.value = true
|
||||||
|
adjustUserId.value = row.userId
|
||||||
|
// 注意:这里需要从原始数据中获取余额,如果row中没有balance字段,可能需要重新获取
|
||||||
|
// 暂时使用默认值,实际使用时需要根据数据结构调整
|
||||||
|
const balance = row.balance || row.wallet_capital?.amount || '0'
|
||||||
|
adjustAmountForm.value = {
|
||||||
|
username: row.accountName,
|
||||||
|
currency: 'USDT', // 默认币种,可根据实际情况调整
|
||||||
|
currentBalance: balance,
|
||||||
|
adjustAmount: '',
|
||||||
|
afterBalance: balance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调整金额输入变化时计算调整后余额
|
||||||
|
const handleAdjustAmountInput = () => {
|
||||||
|
const currentBalance = parseFloat(adjustAmountForm.value.currentBalance) || 0
|
||||||
|
const adjustAmount = parseFloat(adjustAmountForm.value.adjustAmount) || 0
|
||||||
|
const afterBalance = currentBalance + adjustAmount
|
||||||
|
adjustAmountForm.value.afterBalance = afterBalance.toFixed(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交调整金额
|
||||||
|
const handleAdjustAmountSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await adjustAmountFormRef.value?.validate()
|
||||||
|
await updateCapitalApi({
|
||||||
|
target_user_id: adjustUserId.value,
|
||||||
|
amount: adjustAmountForm.value.adjustAmount,
|
||||||
|
})
|
||||||
|
await getCustomerList(userId.value)
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
} catch (err) {
|
||||||
|
console.error('调整金额表单验证失败', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消调整金额
|
||||||
|
const handleAdjustAmountCancel = () => {
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭调整金额弹窗
|
||||||
|
const handleAdjustAmountClose = () => {
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 修改客户相关方法
|
||||||
|
*/
|
||||||
|
// 获取模板选项
|
||||||
|
const getTemplateOptions = async () => {
|
||||||
|
if (templateOptionsFetched.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const [feeTemplateRes, riskTemplateRes] = await Promise.all([
|
||||||
|
getFeeTemplateOptionsApi(),
|
||||||
|
getRiskTemplateOptionsApi(),
|
||||||
|
])
|
||||||
|
|
||||||
|
feeTemplateOptions.value = Object.entries(feeTemplateRes as Record<string, string>).map(
|
||||||
|
([label, value]) => ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
riskTemplateOptions.value = Object.entries(riskTemplateRes as Record<string, string>).map(
|
||||||
|
([label, value]) => ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
templateOptionsFetched.value = true
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取模板选项失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开修改客户弹窗
|
||||||
|
const handleEditCustomer = async (row: any) => {
|
||||||
|
await getTemplateOptions()
|
||||||
|
editCustomerVisible.value = true
|
||||||
|
editCustomerUserId.value = row.userId
|
||||||
|
editCustomerForm.value = {
|
||||||
|
feeSettingId: row.feeSettingId || '',
|
||||||
|
riskControlId: row.riskControlId || '',
|
||||||
|
username: row.accountName || '',
|
||||||
|
isLevelUp: row.isLevelUp || 2,
|
||||||
|
status: row.status === '正常' ? 1 : 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交修改客户
|
||||||
|
const handleEditCustomerSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await editCustomerFormRef.value?.validate()
|
||||||
|
await editUserApi({
|
||||||
|
user_id: editCustomerUserId.value,
|
||||||
|
fee_setting_id: editCustomerForm.value.feeSettingId,
|
||||||
|
risk_control_id: editCustomerForm.value.riskControlId,
|
||||||
|
username: editCustomerForm.value.username,
|
||||||
|
is_levelup: editCustomerForm.value.isLevelUp,
|
||||||
|
status: editCustomerForm.value.status,
|
||||||
|
})
|
||||||
|
await getCustomerList(userId.value)
|
||||||
|
editCustomerVisible.value = false
|
||||||
|
} catch (err) {
|
||||||
|
console.error('修改客户表单验证失败', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消修改客户
|
||||||
|
const handleEditCustomerCancel = () => {
|
||||||
|
editCustomerVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭修改客户弹窗
|
||||||
|
const handleEditCustomerClose = () => {
|
||||||
|
editCustomerVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
@ -485,5 +686,4 @@ const handleClose = () => {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -17,23 +17,23 @@ export const search = [
|
||||||
|
|
||||||
export const tableColumns = [
|
export const tableColumns = [
|
||||||
// 账号名称
|
// 账号名称
|
||||||
{ label: '账号名称', prop: 'accountName'},
|
{ label: '账号名称', prop: 'accountName', },
|
||||||
// 账号id
|
// 账号id
|
||||||
{ prop: 'userId', label: '账号id' },
|
{ prop: 'userId', label: '账号id' },
|
||||||
// 状态
|
// 状态
|
||||||
{ prop: 'status', label: '状态' },
|
{ prop: 'status', label: '状态' },
|
||||||
// 账号角色
|
// 账号角色
|
||||||
{ prop: 'role', label: '账号角色' },
|
{ prop: 'role', label: '账号角色', width: 100 },
|
||||||
// 账号数量
|
// 账号数量
|
||||||
{ prop: 'accountQty', label: '账号数量' },
|
{ prop: 'accountQty', label: '账号数量', width: 100 },
|
||||||
// 点差分配比例
|
// 点差分配比例
|
||||||
{ prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' },
|
{ prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' , minWidth: 140},
|
||||||
// 手续费分成比例
|
// 手续费分成比例
|
||||||
{ prop: 'commissionRatio', label: '手续费分成比例', slotName: 'commissionRatio' },
|
{ prop: 'commissionRatio', label: '手续费分成比例', slotName: 'commissionRatio' , minWidth: 140},
|
||||||
// 注册时间
|
// 注册时间
|
||||||
{ prop: 'createTime', label: '注册时间', sortable: true },
|
{ prop: 'createTime', label: '注册时间', sortable: true , minWidth: 180},
|
||||||
// 操作
|
// 操作
|
||||||
{ label: '操作', slotName: 'action' }
|
{ label: '操作', slotName: 'action', minWidth: 200}
|
||||||
]
|
]
|
||||||
|
|
||||||
// 点差表格配置
|
// 点差表格配置
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
<el-button type="primary" size="small" @click="handleChange(row)" v-anth="'user_editUser'">
|
<el-button type="primary" size="small" @click="handleChange(row)" v-anth="'user_editUser'">
|
||||||
修改
|
修改
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="warning" size="small" @click="handleAdjustAmount(row)">
|
||||||
|
调整金额
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</ClientTable>
|
</ClientTable>
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
|
|
@ -92,6 +95,38 @@
|
||||||
</template>
|
</template>
|
||||||
</ClientForm>
|
</ClientForm>
|
||||||
</ClientDialog>
|
</ClientDialog>
|
||||||
|
|
||||||
|
<!-- 调整金额弹窗 -->
|
||||||
|
<ClientDialog
|
||||||
|
:visible="adjustAmountVisible"
|
||||||
|
title="调整金额"
|
||||||
|
type="adjust"
|
||||||
|
@confirm="handleAdjustAmountSubmit"
|
||||||
|
@cancel="handleAdjustAmountCancel"
|
||||||
|
@close="handleAdjustAmountClose"
|
||||||
|
>
|
||||||
|
<el-form :model="adjustAmountForm" :rules="adjustAmountRules" ref="adjustAmountFormRef" label-width="120px">
|
||||||
|
<el-form-item label="账号名" prop="username">
|
||||||
|
<el-input v-model="adjustAmountForm.username" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="币种" prop="currency">
|
||||||
|
<el-input v-model="adjustAmountForm.currency" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="当前余额" prop="currentBalance">
|
||||||
|
<el-input v-model="adjustAmountForm.currentBalance" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="调整金额" prop="adjustAmount">
|
||||||
|
<el-input
|
||||||
|
v-model="adjustAmountForm.adjustAmount"
|
||||||
|
placeholder="请输入调整金额(可为负数)"
|
||||||
|
@input="handleAdjustAmountInput"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="调整后余额" prop="afterBalance">
|
||||||
|
<el-input v-model="adjustAmountForm.afterBalance" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ClientDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -114,6 +149,7 @@ import {
|
||||||
createClientApi,
|
createClientApi,
|
||||||
editClientApi,
|
editClientApi,
|
||||||
} from '@/api/modules/account/client'
|
} from '@/api/modules/account/client'
|
||||||
|
import { updateCapitalApi } from '@/api/modules/user'
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
import {
|
import {
|
||||||
|
|
@ -154,6 +190,37 @@ const pageSize = ref(10)
|
||||||
const dialogTitle = ref('')
|
const dialogTitle = ref('')
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogType = ref('add')
|
const dialogType = ref('add')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 定义调整金额弹窗数据
|
||||||
|
*/
|
||||||
|
const adjustAmountVisible = ref(false)
|
||||||
|
const adjustAmountFormRef = ref()
|
||||||
|
const adjustUserId = ref<number>(0)
|
||||||
|
const adjustAmountForm = ref({
|
||||||
|
username: '',
|
||||||
|
currency: '',
|
||||||
|
currentBalance: '',
|
||||||
|
adjustAmount: '',
|
||||||
|
afterBalance: '',
|
||||||
|
})
|
||||||
|
const adjustAmountRules = {
|
||||||
|
adjustAmount: [
|
||||||
|
{ required: true, message: '请输入调整金额', trigger: 'blur' },
|
||||||
|
{
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
if (value === '' || value === null || value === undefined) {
|
||||||
|
callback(new Error('请输入调整金额'))
|
||||||
|
} else if (!/^-?\d+(\.\d{1,5})?$/.test(value)) {
|
||||||
|
callback(new Error('请输入有效的金额格式,最多五位小数'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @description 定义dialog中form的数据
|
* @description 定义dialog中form的数据
|
||||||
*/
|
*/
|
||||||
|
|
@ -403,6 +470,55 @@ const handleClose = () => {
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 调整金额相关方法
|
||||||
|
*/
|
||||||
|
// 打开调整金额弹窗
|
||||||
|
const handleAdjustAmount = (row: any) => {
|
||||||
|
adjustAmountVisible.value = true
|
||||||
|
adjustUserId.value = row.id
|
||||||
|
adjustAmountForm.value = {
|
||||||
|
username: row.username,
|
||||||
|
currency: 'USDT', // 默认币种,可根据实际情况调整
|
||||||
|
currentBalance: row.wallet_capital?.amount || '0',
|
||||||
|
adjustAmount: '',
|
||||||
|
afterBalance: row.wallet_capital?.amount || '0',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调整金额输入变化时计算调整后余额
|
||||||
|
const handleAdjustAmountInput = () => {
|
||||||
|
const currentBalance = parseFloat(adjustAmountForm.value.currentBalance) || 0
|
||||||
|
const adjustAmount = parseFloat(adjustAmountForm.value.adjustAmount) || 0
|
||||||
|
const afterBalance = currentBalance + adjustAmount
|
||||||
|
adjustAmountForm.value.afterBalance = afterBalance.toFixed(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交调整金额
|
||||||
|
const handleAdjustAmountSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await adjustAmountFormRef.value?.validate()
|
||||||
|
await updateCapitalApi({
|
||||||
|
target_user_id: adjustUserId.value,
|
||||||
|
amount: adjustAmountForm.value.adjustAmount,
|
||||||
|
})
|
||||||
|
await getClientList()
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
} catch (err) {
|
||||||
|
console.error('调整金额表单验证失败', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消调整金额
|
||||||
|
const handleAdjustAmountCancel = () => {
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭调整金额弹窗
|
||||||
|
const handleAdjustAmountClose = () => {
|
||||||
|
adjustAmountVisible.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,11 @@
|
||||||
:options-map="roleFormOptionsMap" :dialog-type="dialogType">
|
:options-map="roleFormOptionsMap" :dialog-type="dialogType">
|
||||||
<template #permissions="{ formData }">
|
<template #permissions="{ formData }">
|
||||||
<el-tree ref="permissionTreeRef" :data="permissionTreeData" :props="treeProps" show-checkbox node-key="id"
|
<el-tree ref="permissionTreeRef" :data="permissionTreeData" :props="treeProps" show-checkbox node-key="id"
|
||||||
:default-checked-keys="formData.permissions" :default-expand-all="true" class="permission-tree" />
|
:default-expand-all="true" :check-strictly="false"
|
||||||
|
class="permission-tree" />
|
||||||
</template>
|
</template>
|
||||||
</RoleForm>
|
</RoleForm>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div style="flex: auto">
|
<div style="flex: auto">
|
||||||
<el-button @click="handleCancel">取消</el-button>
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
|
|
@ -226,6 +228,39 @@ const transformPermissionsToTree = (permissions: any[]) => {
|
||||||
return Array.from(moduleMap.values()).sort((a, b) => a.id - b.id)
|
return Array.from(moduleMap.values()).sort((a, b) => a.id - b.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 过滤掉父节点ID,只保留子节点ID用于显示选中状态
|
||||||
|
*/
|
||||||
|
const filterParentNodes = (permissionIds: number[], treeData: any[]): number[] => {
|
||||||
|
// 获取所有父节点ID
|
||||||
|
const parentNodeIds = treeData.map(node => node.id)
|
||||||
|
// 过滤掉父节点ID,只保留子节点ID
|
||||||
|
return permissionIds.filter(id => !parentNodeIds.includes(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据选中的子节点计算父节点ID(半选中的父节点)
|
||||||
|
*/
|
||||||
|
const getParentNodeIds = (checkedKeys: number[], treeData: any[]): number[] => {
|
||||||
|
const parentIds: number[] = []
|
||||||
|
|
||||||
|
treeData.forEach(parent => {
|
||||||
|
// 获取该父节点下所有子节点的ID
|
||||||
|
const childIds = parent.children?.map((child: any) => child.id) || []
|
||||||
|
// 检查是否有子节点被选中
|
||||||
|
const hasCheckedChild = childIds.some((id: number) => checkedKeys.includes(id))
|
||||||
|
// 检查是否所有子节点都被选中
|
||||||
|
const allChildrenChecked = childIds.length > 0 && childIds.every((id: number) => checkedKeys.includes(id))
|
||||||
|
|
||||||
|
// 如果有子节点被选中,但不是全部选中,则父节点为半选中状态
|
||||||
|
if (hasCheckedChild && !allChildrenChecked) {
|
||||||
|
parentIds.push(parent.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return parentIds
|
||||||
|
}
|
||||||
|
|
||||||
// 角色权限获取和设置
|
// 角色权限获取和设置
|
||||||
const handlePermission = async (row: any) => {
|
const handlePermission = async (row: any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
|
@ -237,8 +272,18 @@ const handlePermission = async (row: any) => {
|
||||||
const data = await getRolePermissionApi({ id: row.id })
|
const data = await getRolePermissionApi({ id: row.id })
|
||||||
allPermissions.value = data.all_permission_info
|
allPermissions.value = data.all_permission_info
|
||||||
permissionTreeData.value = transformPermissionsToTree(data.all_permission_info)
|
permissionTreeData.value = transformPermissionsToTree(data.all_permission_info)
|
||||||
roleForm.value.permissions = data.permission_ids || []
|
|
||||||
|
// 过滤掉父节点ID,只保留子节点ID
|
||||||
|
const childPermissionIds = filterParentNodes(data.permission_ids || [], permissionTreeData.value)
|
||||||
|
roleForm.value.permissions = childPermissionIds
|
||||||
|
|
||||||
console.log('树形权限数据', permissionTreeData.value)
|
console.log('树形权限数据', permissionTreeData.value)
|
||||||
|
console.log('过滤后的权限ID(仅子节点):', childPermissionIds)
|
||||||
|
|
||||||
|
// 等待DOM更新后,手动设置选中状态
|
||||||
|
await nextTick()
|
||||||
|
// 使用 setCheckedKeys 设置选中状态,只设置子节点
|
||||||
|
permissionTreeRef.value?.setCheckedKeys(childPermissionIds, false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取角色权限失败', err)
|
console.error('获取角色权限失败', err)
|
||||||
}
|
}
|
||||||
|
|
@ -262,14 +307,20 @@ const handleSubmit = async () => {
|
||||||
await editRoleApi(roleForm.value)
|
await editRoleApi(roleForm.value)
|
||||||
await fetchRoleList()
|
await fetchRoleList()
|
||||||
} else {
|
} else {
|
||||||
// 获取Tree组件选中的所有节点(不包括半选节点)
|
// 获取Tree组件选中的所有节点(包括完全选中和半选中的节点)
|
||||||
const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []
|
const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []
|
||||||
|
const halfCheckedKeys = permissionTreeRef.value?.getHalfCheckedKeys() || []
|
||||||
|
|
||||||
|
// 合并完全选中和半选中的节点ID
|
||||||
|
const allSelectedKeys = [...checkedKeys, ...halfCheckedKeys]
|
||||||
|
|
||||||
console.log('设置角色权限', checkedKeys.join(','))
|
console.log('设置角色权限 - 完全选中:', checkedKeys)
|
||||||
|
console.log('设置角色权限 - 半选中:', halfCheckedKeys)
|
||||||
|
console.log('设置角色权限 - 合并后:', allSelectedKeys)
|
||||||
|
|
||||||
await setRolePermissionApi({
|
await setRolePermissionApi({
|
||||||
id: permissionIds.value,
|
id: permissionIds.value,
|
||||||
permission_ids: checkedKeys.join(','),
|
permission_ids: allSelectedKeys.join(','),
|
||||||
})
|
})
|
||||||
await fetchRoleList()
|
await fetchRoleList()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<UserText :user-text="userText" @back="handleBack" />
|
<UserText :user-text="userText" @back="handleBack" />
|
||||||
<UserTabs v-model="activeTab" :hide-tab="hideTab" :tab-list="tabList" />
|
<UserTabs v-model="activeTab" :hide-tab="hideTab" :tab-list="tabList" />
|
||||||
|
|
||||||
<el-form class="user-form" ref="loginFormRef" :model="loginForm" :rules="loginRules">
|
<el-form class="user-form" ref="loginFormRef" :model="loginForm" :rules="loginRules" @submit.prevent="handleLogin">
|
||||||
<Transition name="form-switch" mode="out-in">
|
<Transition name="form-switch" mode="out-in">
|
||||||
<el-form-item v-if="activeTab === 'email'" key="form-email-item" prop="email">
|
<el-form-item v-if="activeTab === 'email'" key="form-email-item" prop="email">
|
||||||
<el-input v-model="loginForm.email" placeholder="请输入邮箱" clearable size="large" />
|
<el-input v-model="loginForm.email" placeholder="请输入邮箱" clearable size="large" />
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
</div>
|
</div>
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-input v-model="loginForm.phone" placeholder="请输入手机号" clearable size="large" />
|
<el-input v-model="loginForm.phone" placeholder="请输入手机号" clearable size="large" @keyup.enter.prevent="handleLogin"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-else-if="activeTab === 'password'" key="form-password-item" prop="password">
|
<el-form-item v-else-if="activeTab === 'password'" key="form-password-item" prop="password">
|
||||||
|
|
@ -137,6 +137,8 @@ function generateTimestampWithRandomNum() {
|
||||||
|
|
||||||
// 登录
|
// 登录
|
||||||
const handleLogin = async () => {
|
const handleLogin = async () => {
|
||||||
|
console.log('触发登录');
|
||||||
|
|
||||||
if (!loginFormRef.value) return
|
if (!loginFormRef.value) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue