处理金额

This commit is contained in:
2026-05-21 13:07:04 +08:00
parent 3a23a85077
commit f0aa2625e9
23 changed files with 358 additions and 303 deletions

View File

@ -12,7 +12,12 @@
v-bind="$attrs" v-bind="$attrs"
@row-click="handleRowClick" @row-click="handleRowClick"
@row-contextmenu="handleRowContextmenu" @row-contextmenu="handleRowContextmenu"
@selection-change="handleSelectionChange"
@current-change="handleCurrentChange"
> >
<!-- 勾选列 -->
<el-table-column v-if="showSelection" type="selection" width="55" align="center" />
<!-- 动态表头列 --> <!-- 动态表头列 -->
<template v-for="(column, index) in columns" :key="index"> <template v-for="(column, index) in columns" :key="index">
<el-table-column <el-table-column
@ -29,7 +34,11 @@
:width="column.width" :width="column.width"
:align="column.align || 'left'" :align="column.align || 'left'"
:sortable="column.sortable" :sortable="column.sortable"
/> >
<template v-if="column.isNumber" #default="{ row }">
<span>{{ formatDecimalTruncate(row[column.prop]) }}</span>
</template>
</el-table-column>
<!-- 具名插槽列 --> <!-- 具名插槽列 -->
<el-table-column <el-table-column
@ -50,6 +59,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import type { TableInstance } from 'element-plus' import type { TableInstance } from 'element-plus'
import { formatDecimalTruncate } from '@/utils/formatDecimal'
// //
interface TableColumn { interface TableColumn {
@ -60,6 +70,7 @@ interface TableColumn {
align?: 'left' | 'center' | 'right' align?: 'left' | 'center' | 'right'
slotName?: string // slotName?: string //
sortable?: boolean // sortable?: boolean //
isNumber?: boolean //
} }
// //
@ -73,20 +84,38 @@ interface Props {
border?: boolean // border?: boolean //
highlightCurrentRow?: boolean // highlightCurrentRow?: boolean //
loading?: boolean // loading?: boolean //
showSelection?: boolean //
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
border: true, border: true,
highlightCurrentRow: true, highlightCurrentRow: true,
loading: false, loading: false,
showSelection: false,
}) })
// //
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'row-click', row: any): void // (e: 'row-click', row: any): void //
(e: 'row-contextmenu', row: any, column: any, event: MouseEvent): void (e: 'row-contextmenu', row: any, column: any, event: MouseEvent): void
(e: 'selection-change', rows: any[]): void //
(e: 'current-change', row: any): void //
}>() }>()
//
const handleSelectionChange = (rows: any[]) => {
emit('selection-change', rows)
}
//
const handleCurrentChange = (row: any) => {
// null Vue
if (row === null || row === undefined) {
return
}
emit('current-change', row)
}
const tableRef = ref<TableInstance>() const tableRef = ref<TableInstance>()
// //
@ -103,7 +132,7 @@ const handleRowClick = (row: any) => {
if (selectedRow.value && selectedRow.value === row) { if (selectedRow.value && selectedRow.value === row) {
// //
selectedRow.value = null selectedRow.value = null
tableRef.value?.setCurrentRow() // [^14^] tableRef.value?.setCurrentRow(null) // null
} else { } else {
// //
selectedRow.value = row selectedRow.value = row
@ -127,16 +156,29 @@ watch(
() => { () => {
// //
selectedRow.value = null selectedRow.value = null
tableRef.value?.setCurrentRow() // [^14^] tableRef.value?.setCurrentRow(null)
}, },
{ deep: true }, // { deep: true }, //
) )
// loading
watch(
() => props.loading,
(newVal) => {
// loading
console.log('Table loading status changed:', newVal)
},
{ flush: 'sync' }, // 使 sync
)
// //
defineExpose({ defineExpose({
clearCurrentRow: () => { clearCurrentRow: () => {
selectedRow.value = null selectedRow.value = null
tableRef.value?.setCurrentRow() tableRef.value?.setCurrentRow(null)
},
setCurrentRow: (row: any) => {
tableRef.value?.setCurrentRow(row)
}, },
}) })
</script> </script>

View File

@ -0,0 +1,46 @@
/**
* @description:
*/
/**
* @description:
* @param value
* @param decimals 2
* @returns
*/
export function formatDecimalTruncate(value: string | number | null | undefined, decimals: number = 2): string | number {
// 处理空值
if (value === null || value === undefined || value === '') {
return value ?? ''
}
// 转换为字符串检查原始格式
const originalStr = String(value)
// 转换为数字检查是否有效
const num = Number(value)
// 如果不是有效数字,返回原值
if (isNaN(num)) {
return value
}
// 分割整数和小数部分
const dotIndex = originalStr.indexOf('.')
// 如果没有小数点,添加小数位后返回
if (dotIndex === -1) {
return `${originalStr}.${'0'.repeat(decimals)}`
}
const integerPart = originalStr.substring(0, dotIndex)
const decimalPart = originalStr.substring(dotIndex + 1)
// 截取到指定小数位(不四舍五入)
const truncatedDecimal = decimalPart.substring(0, decimals)
// 补齐小数位到指定位数
const paddedDecimal = truncatedDecimal.padEnd(decimals, '0')
return `${integerPart}.${paddedDecimal}`
}

View File

@ -62,9 +62,9 @@ export const tableColumns = [
//资金流向 //资金流向
// { prop: 'fundDirection', label: '资金流向' }, // { prop: 'fundDirection', label: '资金流向' },
//原有金额 //原有金额
{ prop: 'amount', label: '变动金额' }, { prop: 'amount', label: '变动金额', isNumber: true },
//余额变动 //余额变动
{ prop: 'balance', label: '变动后余额' }, { prop: 'balance', label: '变动后余额' , isNumber: true},
//现有余额 //现有余额
// { prop: 'currentBalance', label: '现有余额' }, // { prop: 'currentBalance', label: '现有余额' },
//状态 //状态

View File

@ -6,6 +6,6 @@ export const rechangeTableColumns = [
label: '支持货币', label: '支持货币',
align: 'center' as const align: 'center' as const
}, },
{ prop: 'channel_fee', label: '渠道费用', align: 'center' as const }, { prop: 'channel_fee', label: '渠道费用', align: 'center' as const , isNumber: true },
{ label: '操作', slotName: 'action', align: 'center' as const, width: 120 }, { label: '操作', slotName: 'action', align: 'center' as const, width: 120 },
] ]

View File

@ -4,7 +4,7 @@ export const tableColumns = [
//存款渠道名称 //存款渠道名称
{ label: '渠道名称', prop: 'name' }, { label: '渠道名称', prop: 'name' },
//存款渠道费用 //存款渠道费用
{ label: '渠道费用', prop: 'channel_fee' }, { label: '渠道费用', prop: 'channel_fee', isNumber: true },
//存款渠道类型 //存款渠道类型
{ label: '入金货币', prop: 'currency.symbol' }, { label: '入金货币', prop: 'currency.symbol' },
// 接口地址 // 接口地址

View File

@ -19,36 +19,16 @@
</template> </template>
</RechangeSearch> </RechangeSearch>
<!-- 列表区域改为真实接口数据仍保留勾选列供后续审核动作使用 --> <!-- 列表区域使用公共 Table 组件 -->
<div class="table-wrapper"> <Table
<el-table ref="tableRef"
ref="tableRef" :table-data="tableData"
v-loading="loading" :columns="tableColumns"
:data="tableData" row-key="id"
border :loading="loading"
height="100%" :show-selection="true"
row-key="id" @selection-change="handleSelectionChange"
@selection-change="handleSelectionChange" />
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" width="70" align="center">
<template #default="scope">
{{ (currentPage - 1) * pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column
v-for="column in tableColumns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
:min-width="column.width"
:align="column.align || 'center'"
show-overflow-tooltip
/>
</el-table>
</div>
<!-- 分页区域使用接口返回的 total / current_page / per_page --> <!-- 分页区域使用接口返回的 total / current_page / per_page -->
<RechangePagination <RechangePagination
@ -68,6 +48,7 @@ defineOptions({
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import RechangeSearch from '@/components/common/Search.vue' import RechangeSearch from '@/components/common/Search.vue'
import Table from '@/components/common/Table.vue'
import { usePageLoading } from '@/composables/useLoading' import { usePageLoading } from '@/composables/useLoading'
import RechangePagination from '@/components/common/Pagination.vue' import RechangePagination from '@/components/common/Pagination.vue'
import { exportToExcel } from '@/utils/exportToExcel' import { exportToExcel } from '@/utils/exportToExcel'

View File

@ -39,12 +39,12 @@ export const rechangeCheckSearch = [
// 表格列配置:返回数据与 `rechargeOrder` 一致,因此按同一份结构展示。 // 表格列配置:返回数据与 `rechargeOrder` 一致,因此按同一份结构展示。
export const rechangeCheckTableColumns = [ export const rechangeCheckTableColumns = [
{ prop: 'orderNo', label: '订单号', align: 'center' as const, width: 220 }, { prop: 'orderNo', label: '订单号', align: 'center' as const, width: 220 },
{ prop: 'userName', label: '用户名', align: 'center' as const, width: 160 }, { prop: 'userName', label: '用户名', align: 'center' as const },
{ prop: 'currency', label: '充值币种', align: 'center' as const, width: 120 }, { prop: 'currency', label: '充值币种', align: 'center' as const, width: 120 },
{ prop: 'amount', label: '充值金额', align: 'center' as const, width: 120 }, { prop: 'amount', label: '充值金额', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'realCurrency', label: '实际币种', align: 'center' as const, width: 120 }, { prop: 'realCurrency', label: '实际币种', align: 'center' as const, width: 120 },
{ prop: 'realAmount', label: '实际金额', align: 'center' as const, width: 120 }, { prop: 'realAmount', label: '实际金额', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'rate', label: '汇率', align: 'center' as const, width: 100 }, { prop: 'rate', label: '汇率', align: 'center' as const, width: 100 },
{ prop: 'statusText', label: '状态', align: 'center' as const, width: 100 }, { prop: 'statusText', label: '状态', align: 'center' as const, width: 100 },
{ prop: 'rechangeTime', label: '充值时间', align: 'center' as const, width: 180 }, { prop: 'rechangeTime', label: '充值时间', align: 'center' as const },
] ]

View File

@ -5,7 +5,7 @@ export const tableColumns = [
// 渠道名称 // 渠道名称
{ label: '渠道名称', prop: 'name' }, { label: '渠道名称', prop: 'name' },
// 渠道费用 // 渠道费用
{ label: '渠道费用', prop: 'channel_fee' }, { label: '渠道费用', prop: 'channel_fee', isNumber: true },
{ {
label: '出金货币', label: '出金货币',
prop: 'currency.symbol', prop: 'currency.symbol',

View File

@ -4,7 +4,7 @@ export const tableColumns = [
//渠道名称 //渠道名称
{ label: '渠道名称', prop: 'name' }, { label: '渠道名称', prop: 'name' },
//渠道费用 //渠道费用
{ label: '渠道费用', prop: 'channel_fee' }, { label: '渠道费用', prop: 'channel_fee', isNumber: true },
//货币类型 //货币类型
// { label: '入金货币', prop: 'currency.name' }, // { label: '入金货币', prop: 'currency.name' },
// 接口地址 // 接口地址

View File

@ -4,29 +4,20 @@
<WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset"> <WithdrawSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch" @reset="handleReset">
<template #button> <template #button>
<el-button type="success" :loading="approveLoading" @click="handleApprove">通过</el-button> <el-button type="success" :loading="approveLoading" @click="handleApprove">通过</el-button>
<el-button type="danger" plain :loading="rejectLoading" @click="handleReject">驳回</el-button> <el-button type="danger" plain :loading="rejectLoading" @click="handleReject">驳回</el-button>
</template> </template>
</WithdrawSearch> </WithdrawSearch>
<!-- 列表区域当前使用页面内表格避免改动公共 Table 组件 --> <!-- 列表区域使用公共 Table 组件 -->
<div class="table-wrapper"> <Table
<el-table v-loading="loading" :data="tableData" border height="100%" row-key="id" ref="tableRef"
@selection-change="handleSelectionChange"> :table-data="tableData"
<!-- 勾选列用于后续审核通过/驳回 --> :columns="tableColumns"
<el-table-column type="selection" width="55" align="center" /> row-key="id"
:loading="loading"
<!-- 序号列根据当前分页动态计算 --> :show-selection="true"
<el-table-column label="序号" width="70" align="center"> @selection-change="handleSelectionChange"
<template #default="scope"> />
{{ (currentPage - 1) * pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<!-- 业务字段列通过配置项统一渲染 -->
<el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label"
:width="column.width" :align="column.align || 'center'" show-overflow-tooltip />
</el-table>
</div>
<!-- 分页区域复用项目内分页组件 --> <!-- 分页区域复用项目内分页组件 -->
<WithdrawPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total" <WithdrawPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
@ -43,6 +34,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import WithdrawSearch from '@/components/common/Search.vue' import WithdrawSearch from '@/components/common/Search.vue'
import Table from '@/components/common/Table.vue'
import { usePageLoading } from '@/composables/useLoading' import { usePageLoading } from '@/composables/useLoading'
import WithdrawPagination from '@/components/common/Pagination.vue' import WithdrawPagination from '@/components/common/Pagination.vue'
import { withdrawCheckSearch, withdrawCheckTableColumns } from './options' import { withdrawCheckSearch, withdrawCheckTableColumns } from './options'

View File

@ -25,18 +25,18 @@ export const withdrawCheckSearch = [
// 表格列配置 // 表格列配置
export const withdrawCheckTableColumns = [ export const withdrawCheckTableColumns = [
{ prop: 'trade_id', label: '订单号', align: 'center' as const, width: 200 }, { prop: 'trade_id', label: '订单号', align: 'center' as const, width: 200 },
{ prop: 'user_name', label: '账户持有人', align: 'center' as const, width: 120 }, { prop: 'user_name', label: '账户持有人', align: 'center' as const},
{ prop: 'withdraw_currency_symbol', label: '取款币种', align: 'center' as const, width: 100 }, { prop: 'withdraw_currency_symbol', label: '取款币种', align: 'center' as const, width: 100 },
{ prop: 'withdraw_amount', label: '取款金额', align: 'center' as const, width: 120 }, { prop: 'withdraw_amount', label: '取款金额', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'real_currency_symbol', label: '到账币种', align: 'center' as const, width: 100 }, { prop: 'real_currency_symbol', label: '到账币种', align: 'center' as const, width: 100 },
{ prop: 'real_amount', label: '到账金额', align: 'center' as const, width: 120 }, { prop: 'real_amount', label: '到账金额', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'rate', label: '汇率', align: 'center' as const, width: 100 }, { prop: 'rate', label: '汇率', align: 'center' as const, width: 100 },
{ prop: 'channel_name', label: '渠道', align: 'center' as const, width: 140 }, { prop: 'channel_name', label: '渠道', align: 'center' as const, width: 140 },
{ prop: 'withdraw_service_fee', label: '服务费', align: 'center' as const, width: 100 }, { prop: 'withdraw_service_fee', label: '服务费', align: 'center' as const, width: 100, isNumber: true },
{ prop: 'withdraw_head_fee', label: '总部手续费', align: 'center' as const, width: 120 }, { prop: 'withdraw_head_fee', label: '总部手续费', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'withdraw_fee_handle', label: '代理手续费', align: 'center' as const, width: 120 }, { prop: 'withdraw_fee_handle', label: '代理手续费', align: 'center' as const, width: 120, isNumber: true },
{ prop: 'withdraw_point_diff', label: '点差', align: 'center' as const, width: 100 }, { prop: 'withdraw_point_diff', label: '点差', align: 'center' as const, width: 100, isNumber: true },
{ prop: 'withdraw_risk_fee', label: '风控费', align: 'center' as const, width: 100 }, { prop: 'withdraw_risk_fee', label: '风控费', align: 'center' as const, isNumber: true },
{ prop: 'withdraw_address', label: '提现地址', align: 'center' as const, width: 180 }, { prop: 'withdraw_address', label: '提现地址', align: 'center' as const},
{ prop: 'created_at', label: '申请时间', align: 'center' as const, width: 180 } { prop: 'created_at', label: '申请时间', align: 'center' as const}
] ]

View File

@ -2,59 +2,23 @@
<div class="mould-fee table_form-container"> <div class="mould-fee table_form-container">
<header> <header>
<div class="header-actions"> <div class="header-actions">
<el-button type="primary" @click="addFee" v-auth="'feeHandl_createFeeSetting'" <el-button type="primary" @click="addFee" v-auth="'feeHandl_createFeeSetting'">添加模板</el-button>
>添加模板</el-button <el-button type="primary" @click="editFee" v-auth="'feeHandl_editFeeSetting'">编辑模板</el-button>
> <el-button type="primary" @click="changeStatus(1)" v-auth="'feeHandl_editFeeSetting'">启用模板</el-button>
<el-button type="primary" @click="editFee" v-auth="'feeHandl_editFeeSetting'" <el-button type="danger" @click="changeStatus(2)" v-auth="'feeHandl_editFeeSetting'">禁用模板</el-button>
>编辑模板</el-button <el-button type="primary" @click="editFeeDetail" v-auth="'feeHandl_setFeeSettingDetail'">编辑模板详情</el-button>
>
<el-button type="primary" @click="changeStatus(1)" v-auth="'feeHandl_editFeeSetting'"
>启用模板</el-button
>
<el-button type="danger" @click="changeStatus(2)" v-auth="'feeHandl_editFeeSetting'"
>禁用模板</el-button
>
<el-button type="primary" @click="editFeeDetail" v-auth="'feeHandl_setFeeSettingDetail'"
>编辑模板详情</el-button
>
</div> </div>
</header> </header>
<div class="table-container"> <div class="table-container">
<div class="table-container-left"> <div class="table-container-left">
<el-table <Table ref="singleTableRef" :table-data="tableData" :columns="tableColumns" row-key="id" :loading="loading"
ref="singleTableRef" :highlight-current-row="true" @current-change="handleCurrentChange" />
height="100%"
:data="tableData"
highlight-current-row
border
@current-change="handleCurrentChange"
:loading="loading"
>
<el-table-column type="index" width="55" />
<el-table-column
v-for="column in tableColumns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
/>
</el-table>
</div> </div>
<div class="table-container-right"> <div class="table-container-right">
<el-table height="100%" :data="tableDataDetail" :loading="loading"> <Table row-key="id" :table-data="tableDataDetail" :columns="tableColumnsDetail" :loading="detailLoading" />
<el-table-column
v-for="column in tableColumnsDetail"
:key="column.prop"
:prop="column.prop"
:label="column.label"
/>
</el-table>
</div> </div>
</div> </div>
<el-dialog <el-dialog v-model="dialogVisible" :title="dialogTitleType === 1 ? '添加手续费模板' : '编辑手续费模板'" width="500">
v-model="dialogVisible"
:title="dialogTitleType === 1 ? '添加手续费模板' : '编辑手续费模板'"
width="500"
>
<Form :formItems="formItems" :formRules="formRules" :formData="formData" /> <Form :formItems="formItems" :formRules="formRules" :formData="formData" />
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -68,12 +32,7 @@
<template v-for="column in tableColumnsDetail" :key="column.prop"> <template v-for="column in tableColumnsDetail" :key="column.prop">
<el-table-column v-if="column.prop === 'fee'" :prop="column.prop" :label="column.label"> <el-table-column v-if="column.prop === 'fee'" :prop="column.prop" :label="column.label">
<template #default="scope"> <template #default="scope">
<el-input-number <el-input-number :min="0" :max="999999999" :controls="false" v-model="scope.row.fee" />
:min="0"
:max="999999999"
:controls="false"
v-model="scope.row.fee"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-else :prop="column.prop" :label="column.label" /> <el-table-column v-else :prop="column.prop" :label="column.label" />
@ -94,10 +53,9 @@
defineOptions({ defineOptions({
name: 'HandleFee' name: 'HandleFee'
}) })
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { usePageLoading } from '@/composables/useLoading' import { usePageLoading } from '@/composables/useLoading'
const { loading, startLoading, stopLoading } = usePageLoading()
import { import {
getFeeSettingList, getFeeSettingList,
getFeeSettingDetail, getFeeSettingDetail,
@ -106,18 +64,40 @@ import {
setFeeSettingDetail, setFeeSettingDetail,
} from '@/api/modules/mould/handleFee.ts' } from '@/api/modules/mould/handleFee.ts'
import Form from '@/components/common/Form.vue' import Form from '@/components/common/Form.vue'
import Table from '@/components/common/Table.vue'
import { formDataList, formRulesList } from './option.ts' import { formDataList, formRulesList } from './option.ts'
//
const dialogVisible = ref(false) const dialogVisible = ref(false)
const dialogTitleType = ref(1) const dialogTitleType = ref(1)
//
const formData = ref({ const formData = ref({
name: '', name: '',
status: 1, status: 1,
type: 2, type: 2,
description: '', description: '',
}) })
const formItems = ref(formDataList) const formItems = formDataList
const formRules = ref(formRulesList) const formRules = formRulesList
//
const detaildialogVisible = ref(false)
//
const { loading, startLoading, stopLoading } = usePageLoading()
const detailLoading = ref(false)
//
const tableData = ref<any[]>([])
const tableColumns = [
{ prop: 'name', label: '名称' },
{ prop: 'type', label: '状态' },
]
const currentRow = ref<Record<string, any>>({})
const singleTableRef = ref()
//
const resetFormData = () => { const resetFormData = () => {
formData.value = { formData.value = {
name: '', name: '',
@ -127,61 +107,72 @@ const resetFormData = () => {
} }
} }
const tableData = ref([]) //
const tableColumns = ref([ const setCurrent = (row: any) => {
{ prop: 'name', label: '名称' }, singleTableRef.value?.setCurrentRow(row)
{ prop: 'type', label: '状态' },
])
const currentRow = ref({})
const singleTableRef = ref()
const setCurrent = (row) => {
singleTableRef.value.setCurrentRow(row)
}
const handleCurrentChange = (row: any) => {
currentRow.value = row
getItemDetail(row.id)
} }
const tableDataDetail = ref([]) //
const tableColumnsDetail = ref([ const handleCurrentChange = (row: any) => {
currentRow.value = row
fetchItemDetail(row.id)
}
//
const tableDataDetail = ref<any[]>([])
const tableColumnsDetail = [
{ prop: 'name', label: '品种' }, { prop: 'name', label: '品种' },
{ prop: 'code', label: '编号' }, { prop: 'code', label: '编号' },
{ prop: 'fee', label: '开仓手续费' }, { prop: 'fee', label: '开仓手续费' },
]) ]
//
const getTableData = async () => { const getTableData = async () => {
startLoading() startLoading()
try { try {
const res = await getFeeSettingList() const res = await getFeeSettingList()
const savedId = currentRow.value?.id tableData.value = Array.isArray(res) ? res : []
tableData.value = res handleTableDataAfterLoad()
console.log(res)
if (res && res.length > 0) {
const targetRow = savedId ? res.find((item: any) => item.id === savedId) : null
if (targetRow) {
setCurrent(targetRow)
handleCurrentChange(targetRow)
} else {
setCurrent(res[0])
handleCurrentChange(res[0])
}
}
} finally { } finally {
stopLoading() stopLoading()
} }
} }
const getItemDetail = async (id: number) => { //
const res = await getFeeSettingDetail({ id }) const handleTableDataAfterLoad = () => {
tableDataDetail.value = res const savedId = currentRow.value?.id
if (tableData.value.length === 0) {
tableDataDetail.value = []
return
}
const targetRow = savedId ? tableData.value.find((item) => item.id === savedId) : null
const rowToSelect = targetRow || tableData.value[0]
setCurrent(rowToSelect)
handleCurrentChange(rowToSelect)
} }
//
const fetchItemDetail = async (id: number) => {
detailLoading.value = true
try {
const res = await getFeeSettingDetail({ id })
tableDataDetail.value = res || []
} finally {
detailLoading.value = false
}
}
//
const addFee = () => { const addFee = () => {
dialogVisible.value = true dialogVisible.value = true
dialogTitleType.value = 1 dialogTitleType.value = 1
resetFormData() resetFormData()
} }
//
const editFee = () => { const editFee = () => {
dialogVisible.value = true dialogVisible.value = true
dialogTitleType.value = 2 dialogTitleType.value = 2
@ -193,6 +184,7 @@ const editFee = () => {
} }
} }
//
const changeStatus = (status: number) => { const changeStatus = (status: number) => {
dialogTitleType.value = 2 dialogTitleType.value = 2
formData.value = { formData.value = {
@ -205,8 +197,8 @@ const changeStatus = (status: number) => {
submit() submit()
} }
//
const submit = async () => { const submit = async () => {
console.log(formData.value)
if (dialogTitleType.value === 1) { if (dialogTitleType.value === 1) {
await createFeeSetting(formData.value) await createFeeSetting(formData.value)
} else { } else {
@ -217,21 +209,24 @@ const submit = async () => {
getTableData() getTableData()
} }
const detaildialogVisible = ref(false) //
const editFeeDetail = () => { const editFeeDetail = () => {
detaildialogVisible.value = true detaildialogVisible.value = true
console.log(tableDataDetail.value)
} }
//
const submitDetail = async () => { const submitDetail = async () => {
let contents_json = {} const contentsJson: Record<string, any> = {}
tableDataDetail.value.forEach((item) => { tableDataDetail.value.forEach((item) => {
contents_json[item.variety_id] = item.fee contentsJson[item.variety_id] = item.fee
}) })
await setFeeSettingDetail({ await setFeeSettingDetail({
id: currentRow.value.id, id: currentRow.value.id,
contents_json: JSON.stringify(contents_json), contents_json: JSON.stringify(contentsJson),
}) })
detaildialogVisible.value = false detaildialogVisible.value = false
getTableData() getTableData()
} }
@ -246,19 +241,23 @@ onMounted(() => {
// height: 100%; // height: 100%;
// overflow: hidden; // overflow: hidden;
} }
header { header {
margin-bottom: 8px; margin-bottom: 8px;
} }
.table-container { .table-container {
display: flex; display: flex;
column-gap: 20px; column-gap: 20px;
height: calc(100% - 40px); height: calc(100% - 40px);
.table-container-left { .table-container-left {
width: 300px; width: 300px;
height: 100%; height: 100%;
flex: 0 0 auto; flex: 0 0 auto;
overflow: hidden; overflow: hidden;
} }
.table-container-right { .table-container-right {
flex: 1; flex: 1;
height: 100%; height: 100%;
@ -266,3 +265,4 @@ header {
} }
} }
</style> </style>

View File

@ -2,71 +2,31 @@
<div class="risk table_form-container"> <div class="risk table_form-container">
<div class="bar"> <div class="bar">
<span>风控管理</span> <span>风控管理</span>
<el-button type="primary" @click="handleAddRisk" v-auth="'riskControl_createRiskControl'" <el-button type="primary" @click="handleAddRisk" v-auth="'riskControl_createRiskControl'">添加</el-button>
>添加</el-button <el-button type="primary" @click="handleModifyRisk" v-auth="'riskControl_editRiskControlSetting'">修改</el-button>
> <el-button type="danger" @click="handleChangeStatus(2)"
<el-button v-auth="'riskControl_editRiskControlSetting'">停用</el-button>
type="primary" <el-button type="primary" @click="handleChangeStatus(1)"
@click="handleModifyRisk" v-auth="'riskControl_editRiskControlSetting'">启用</el-button>
v-auth="'riskControl_editRiskControlSetting'"
>修改</el-button
>
<el-button
type="danger"
@click="handleChangeStatus(2)"
v-auth="'riskControl_editRiskControlSetting'"
>停用</el-button
>
<el-button
type="primary"
@click="handleChangeStatus(1)"
v-auth="'riskControl_editRiskControlSetting'"
>启用</el-button
>
</div> </div>
<!-- 表格 --> <!-- 表格 -->
<div class="risk-table-content"> <div class="risk-table-content">
<RiskTableSwitch <RiskTableSwitch :columns="tableColumnsSwitch" :table-data="tableTreeSwitch" class="table-switch"
:columns="tableColumnsSwitch" @row-click="handleRowClick" row-key="id" highlight-current-row :current-row-key="selectedRowId"
:table-data="tableTreeSwitch" :loading="loading">
class="table-switch"
@row-click="handleRowClick"
row-key="id"
highlight-current-row
:current-row-key="selectedRowId"
:loading="loading"
>
<template #status="{ row }"> <template #status="{ row }">
<span>{{ row.status === 1 ? '启用' : '停用' }}</span> <span>{{ row.status === 1 ? '启用' : '停用' }}</span>
</template> </template>
</RiskTableSwitch> </RiskTableSwitch>
<RiskTableContent <RiskTableContent :columns="tableColumnsContent" :table-data="currentContent" class="table-content" row-key="id"
:columns="tableColumnsContent" :loading="detailLoading">
:table-data="currentContent"
class="table-content"
row-key="id"
:loading="loading"
>
</RiskTableContent> </RiskTableContent>
</div> </div>
<!-- dialog --> <!-- dialog -->
<RiskDialog <RiskDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" @confirm="handleSubmit"
:visible="dialogVisible" @cancel="handleCancel" @close="handleClose">
:title="dialogTitle" <RiskForm :form-data="dialogForm" :form-rules="riskRules" :form-items="RiskFormItems"
:type="dialogType" :options-map="riskFormOptionsMap" :row-gutter="rowGutter" :col-span="colSpan" ref="riskFormRef" />
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
>
<RiskForm
:form-data="dialogForm"
:form-rules="riskRules"
:form-items="RiskFormItems"
:options-map="riskFormOptionsMap"
:row-gutter="rowGutter"
:col-span="colSpan"
ref="riskFormRef"
/>
</RiskDialog> </RiskDialog>
</div> </div>
</template> </template>
@ -137,6 +97,8 @@ const dialogForm = ref({
}) })
const riskRules = ref(rules()) const riskRules = ref(rules())
const riskFormRef = ref() const riskFormRef = ref()
const detailLoading = ref(false)
const RiskFormItems = ref(formItem) const RiskFormItems = ref(formItem)
const riskFormOptionsMap = ref({ const riskFormOptionsMap = ref({
@ -170,41 +132,41 @@ const colSpan = ref(12)
* @description: 定义请求数据方法 * @description: 定义请求数据方法
*/ */
const getRiskList = async () => { const getRiskList = async () => {
startLoading() startLoading()
const data: any = await getRiskListApi() const data: any = await getRiskListApi()
stopLoading() stopLoading()
// //
riskOriginData.value = data riskOriginData.value = data
// //
tableTreeSwitch.value = data.map((item: any) => ({ tableTreeSwitch.value = data.map((item: any) => ({
id: item.id, id: item.id,
name: item.name, name: item.name,
status: item.status, status: item.status,
})) }))
tableTreeContent.value = data.map((item: any) => ({ tableTreeContent.value = data.map((item: any) => ({
id: item.id, id: item.id,
isDefault: item.is_default, isDefault: item.is_default,
// //
maxOpenPosition: item.max_opening_quantity_per_transaction, maxOpenPosition: item.max_opening_quantity_per_transaction,
// //
maxPositionPerSymbol: item.max_holding_quantity_per_variety, maxPositionPerSymbol: item.max_holding_quantity_per_variety,
// //
maxTotalPosition: item.max_holding_quantity_per_transaction, maxTotalPosition: item.max_holding_quantity_per_transaction,
// //
strongCloseRatio: item.strong_to_average_ratio, strongCloseRatio: item.strong_to_average_ratio,
// //
maxWithdrawalAmount: item.max_withdrawal_amount_per_transaction, maxWithdrawalAmount: item.max_withdrawal_amount_per_transaction,
// //
isWithdrawalAllowed: item.withdraw_status === 1 ? '是' : '否', isWithdrawalAllowed: item.withdraw_status === 1 ? '是' : '否',
// //
withdrawalTimeSetting: item.withdraw_time, withdrawalTimeSetting: item.withdraw_time,
// //
isWithdrawalAuditRequired: item.withdraw_is_check === 1 ? '是' : '否', isWithdrawalAuditRequired: item.withdraw_is_check === 1 ? '是' : '否',
// //
buildCloseTime: item.open_close_time, buildCloseTime: item.open_close_time,
// //
minWithdrawalAmount: item.min_withdrawal_amount_per_transaction, minWithdrawalAmount: item.min_withdrawal_amount_per_transaction,
// //
slippage: item.slippage, slippage: item.slippage,
// //
minDepositAmount: item.min_recharge_amount_per_transaction, minDepositAmount: item.min_recharge_amount_per_transaction,
@ -272,7 +234,7 @@ const handleModifyRisk = () => {
} as any } as any
} }
const handleChangeStatus = async (status) => { const handleChangeStatus = async (status:any) => {
dialogTitle.value = '停用' dialogTitle.value = '停用'
dialogType.value = 'status' dialogType.value = 'status'
await editRiskApi({ ...selectedRow.value, status: status }) await editRiskApi({ ...selectedRow.value, status: status })
@ -283,6 +245,7 @@ const handleChangeStatus = async (status) => {
* @description: 定义表格方法 * @description: 定义表格方法
*/ */
const handleRowClick = (row: any) => { const handleRowClick = (row: any) => {
detailLoading.value = true
// //
const originRow = riskOriginData.value.find((item) => item.id === row.id) const originRow = riskOriginData.value.find((item) => item.id === row.id)
if (originRow) { if (originRow) {
@ -292,7 +255,7 @@ const handleRowClick = (row: any) => {
} }
selectedRowId.value = row.id selectedRowId.value = row.id
// //
const targetItem = tableTreeContent.value.find((item: any) => item.id === row.id) const targetItem:any = tableTreeContent.value.find((item: any) => item.id === row.id)
const fields = [ const fields = [
{ text: '单笔开仓最大数量' + targetItem.maxOpenPosition }, { text: '单笔开仓最大数量' + targetItem.maxOpenPosition },
@ -312,6 +275,8 @@ const handleRowClick = (row: any) => {
if (targetItem) { if (targetItem) {
currentContent.value = fields currentContent.value = fields
} }
detailLoading.value = false
} }
/** /**

View File

@ -17,6 +17,7 @@
<PositionStatTable <PositionStatTable
:table-data="orderPositionStore.positionOrderList" :table-data="orderPositionStore.positionOrderList"
:columns="tableColumnsOptions" :columns="tableColumnsOptions"
:loading="loading"
row-key="id" row-key="id"
/> />
</div> </div>
@ -35,6 +36,10 @@ import { search, tableColumns } from './options'
import { useTransactionStore } from '@/stores/modules/transaction.ts' import { useTransactionStore } from '@/stores/modules/transaction.ts'
import { useOrderPositionStore } from '@/stores/modules/orderPosition.ts' import { useOrderPositionStore } from '@/stores/modules/orderPosition.ts'
import { usePageLoading } from '@/composables/useLoading'
// loading
const { loading, startLoading, stopLoading } = usePageLoading()
// //
import { exportToExcel } from '@/utils/exportToExcel' import { exportToExcel } from '@/utils/exportToExcel'
@ -57,7 +62,9 @@ const tableColumnsOptions = ref(tableColumns)
* @description: 定义搜索方法 * @description: 定义搜索方法
*/ */
const handleSearch = async () => { const handleSearch = async () => {
startLoading()
const data = await checkAccountIdIsSonForUser({ account_id: searchForm.value.account_id }) const data = await checkAccountIdIsSonForUser({ account_id: searchForm.value.account_id })
stopLoading()
if (!data.flag) { if (!data.flag) {
return ElMessage.warning('请输入下级ID') return ElMessage.warning('请输入下级ID')
} }

View File

@ -14,9 +14,9 @@ export const tableColumns = [
// 操作类型 // 操作类型
{ prop: 'tradeType', label: '操作类型' }, { prop: 'tradeType', label: '操作类型' },
// 金额 // 金额
{ prop: 'amount', label: '金额' }, { prop: 'amount', label: '金额', isNumber: true },
// 交易数量 // 交易数量
{ prop: 'tradeQty', label: '交易数量' }, { prop: 'tradeQty', label: '交易数量'},
// 交易时间 // 交易时间
{ prop: 'tradeTime', label: '交易时间' }, { prop: 'tradeTime', label: '交易时间' },
// 浮动盈亏 // 浮动盈亏

View File

@ -51,7 +51,7 @@ export const search = [
export const tableColumns = [ export const tableColumns = [
{ prop: 'orderNo', label: '订单号', align: 'center' as const }, { prop: 'orderNo', label: '订单号', align: 'center' as const },
{ prop: 'currency', label: '充值币种', align: 'center' as const }, { prop: 'currency', label: '充值币种', align: 'center' as const },
{ prop: 'amount', label: '金额', align: 'center' as const }, { prop: 'amount', label: '金额', align: 'center' as const, isNumber: true },
{ prop: 'statusText', label: '状态', align: 'center' as const }, { prop: 'statusText', label: '状态', align: 'center' as const },
{ prop: 'rechangeTime', label: '充值时间', align: 'center' as const }, { prop: 'rechangeTime', label: '充值时间', align: 'center' as const },
{ prop: 'rechangeAccount', label: '充值账号', align: 'center' as const }, { prop: 'rechangeAccount', label: '充值账号', align: 'center' as const },

View File

@ -31,7 +31,7 @@ export const search = [
export const tableColumns = [ export const tableColumns = [
{ prop: 'orderNo', label: '订单号', align: 'center' as const }, { prop: 'orderNo', label: '订单号', align: 'center' as const },
{ prop: 'currency', label: '提现币种', align: 'center' as const }, { prop: 'currency', label: '提现币种', align: 'center' as const },
{ prop: 'amount', label: '金额', align: 'center' as const }, { prop: 'amount', label: '金额', align: 'center' as const, isNumber: true },
{ prop: 'statusText', label: '状态', align: 'center' as const }, { prop: 'statusText', label: '状态', align: 'center' as const },
{ prop: 'withdrawTime', label: '提现时间', align: 'center' as const }, { prop: 'withdrawTime', label: '提现时间', align: 'center' as const },
{ prop: 'withdrawAccount', label: '提现账号', align: 'center' as const }, { prop: 'withdrawAccount', label: '提现账号', align: 'center' as const },

View File

@ -38,7 +38,7 @@ export const tableColumns = [
{ prop: 'role', label: '账号角色' }, { prop: 'role', label: '账号角色' },
// 账号数量 // 账号数量
{ prop: 'accountQty', label: '账号数量' }, { prop: 'accountQty', label: '账号数量' },
{ prop: 'wallet_capital.amount', label: '资金', align: 'center' as const }, { prop: 'wallet_capital.amount', label: '资金', align: 'center' as const, isNumber: true },
// 点差分配比例 // 点差分配比例
{ prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' }, { prop: 'marginRatio', label: '点差分配比例', slotName: 'marginRatio' },
// 手续费分成比例 // 手续费分成比例

View File

@ -25,34 +25,35 @@ export const marketTableColumns = [
//基本账户 //基本账户
{ label: '基本账户', prop: 'basicAccount', align: 'center' as const, width: '200px' }, { label: '基本账户', prop: 'basicAccount', align: 'center' as const, width: '200px' },
//保证金 //保证金
{ label: '保证金', prop: 'margin', align: 'center' as const, width: '200px' }, { label: '保证金', prop: 'margin', align: 'center' as const, width: '200px', isNumber: true },
//停止接单保证金 //停止接单保证金
{ label: '停止接单保证金', prop: 'stopOrderMargin', align: 'center' as const, width: '200px' }, { label: '停止接单保证金', prop: 'stopOrderMargin', align: 'center' as const, width: '200px', isNumber: true },
//持仓转移保证金 //持仓转移保证金
{ {
label: '持仓转移保证金', label: '持仓转移保证金',
prop: 'positionTransferMargin', prop: 'positionTransferMargin',
align: 'center' as const, align: 'center' as const,
width: '200px', width: '200px',
isNumber: true,
}, },
//头寸比率 //头寸比率
{ label: '头寸比率', prop: 'positionRatio', align: 'center' as const, width: '150px' }, { label: '头寸比率', prop: 'positionRatio', align: 'center' as const, width: '150px', isNumber: true },
//点差返佣 //点差返佣
{ label: '点差返佣', prop: 'pointSpreadCommission', align: 'center' as const, width: '200px' }, { label: '点差返佣', prop: 'pointSpreadCommission', align: 'center' as const, width: '200px', isNumber: true },
//点差 //点差
{ label: '点差', slotName: 'pointSpread', align: 'center' as const, width: '150px' }, { label: '点差', slotName: 'pointSpread', align: 'center' as const, width: '150px' },
//手续费比例 //手续费比例
{ label: '手续费比例', prop: 'commissionRatio', align: 'center' as const, width: '150px' }, { label: '手续费比例', prop: 'commissionRatio', align: 'center' as const, width: '150px', isNumber: true },
//手续费返佣 //手续费返佣
{ label: '手续费返佣', prop: 'commissionReturn', align: 'center' as const, width: '150px' }, { label: '手续费返佣', prop: 'commissionReturn', align: 'center' as const, width: '150px', isNumber: true },
//浮动盈亏 //浮动盈亏
{ label: '浮动盈亏', prop: 'floatProfitLoss', align: 'center' as const, width: '100px' }, { label: '浮动盈亏', prop: 'floatProfitLoss', align: 'center' as const, width: '100px', isNumber: true },
//平仓盈亏 //平仓盈亏
{ label: '平仓盈亏', prop: 'closeProfitLoss', align: 'center' as const, width: '150px' }, { label: '平仓盈亏', prop: 'closeProfitLoss', align: 'center' as const, width: '150px', isNumber: true },
//风险金 //风险金
{ label: '风险金', prop: 'riskMargin', align: 'center' as const, width: '150px' }, { label: '风险金', prop: 'riskMargin', align: 'center' as const, width: '150px', isNumber: true },
//服务费 //服务费
{ label: '服务费', prop: 'serviceFee', align: 'center' as const, width: '150px' }, { label: '服务费', prop: 'serviceFee', align: 'center' as const, width: '150px', isNumber: true },
] ]
//做市商添加配置 //做市商添加配置

View File

@ -54,7 +54,7 @@ export const clientTableColumns = [
{ prop: 'username', label: '用户名', align: 'center' as const }, { prop: 'username', label: '用户名', align: 'center' as const },
{ prop: 'createdTime', label: '注册时间', align: 'center' as const }, { prop: 'createdTime', label: '注册时间', align: 'center' as const },
{ prop: 'agentUsername', label: '所属代理', align: 'center' as const }, { prop: 'agentUsername', label: '所属代理', align: 'center' as const },
{ prop: 'wallet_capital.amount', label: '资金', align: 'center' as const }, { prop: 'wallet_capital.amount', label: '资金', align: 'center' as const, isNumber: true },
{ label: '状态', slotName: 'status', 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 },
] ]

View File

@ -33,9 +33,9 @@ export const tableColumns = [
// 交易分组 // 交易分组
{ prop: 'tradeGroup', label: '交易分组', align: 'center' as const }, { prop: 'tradeGroup', label: '交易分组', align: 'center' as const },
// 多头库存费 // 多头库存费
{ prop: 'longStockFee', label: '多头库存费', align: 'center' as const }, { prop: 'longStockFee', label: '多头库存费', align: 'center' as const, isNumber: true },
// 空头库存费 // 空头库存费
{ prop: 'shortStockFee', label: '空头库存费', align: 'center' as const }, { prop: 'shortStockFee', label: '空头库存费', align: 'center' as const, isNumber: true },
// 类型 // 类型
{ prop: 'type', label: '类型', align: 'center' as const }, { prop: 'type', label: '类型', align: 'center' as const },
// 止盈水平 // 止盈水平

View File

@ -52,7 +52,7 @@
</el-form-item> </el-form-item>
</Transition> </Transition>
<el-form-item class="form-submit"> <el-form-item class="form-submit">
<el-button type="primary" @click="handleLogin">登录</el-button> <el-button type="primary" @click="handleLogin" :loading="activeTab === 'password' && buttonLoading">登录</el-button>
</el-form-item> </el-form-item>
<router-link to="/user/register" class="to-register">没有账号去注册</router-link> <router-link to="/user/register" class="to-register">没有账号去注册</router-link>
</el-form> </el-form>
@ -74,6 +74,7 @@ import UserTabs from './components/Tabs.vue'
///store/ ///store/
import { useUserStore } from '@/stores/modules/user' import { useUserStore } from '@/stores/modules/user'
import { useButtonLoading } from '@/composables/useLoading'
import { setStorage, getStorage } from '@/utils/storage' import { setStorage, getStorage } from '@/utils/storage'
import { md5Encrypt } from '@/utils/crypto' import { md5Encrypt } from '@/utils/crypto'
@ -83,6 +84,9 @@ import { passwordRules, emailRules, phoneRules, codeRules } from './config/rules
const router = useRouter() const router = useRouter()
// loading
const { buttonLoading, startButtonLoading, stopButtonLoading } = useButtonLoading()
//userText //userText
const userText = ref({ const userText = ref({
backText: '', backText: '',
@ -179,19 +183,26 @@ const handleLogin = async () => {
else if (currentTab === 'password') { else if (currentTab === 'password') {
// + // +
await loginFormRef.value.validateField(['password', 'code']) await loginFormRef.value.validateField(['password', 'code'])
// device_no1 // loading
const deviceNo = generateTimestampWithRandomNum() startButtonLoading()
// try {
const loginParams = { // device_no1
email: loginForm.value.email, const deviceNo = generateTimestampWithRandomNum()
mobile: loginForm.value.countryCode + loginForm.value.phone, //
login_type: getStorage('loginType', 'session') === 'email' ? 1 : 2, const loginParams = {
code: loginForm.value.code, email: loginForm.value.email,
password: loginForm.value.password, mobile: loginForm.value.countryCode + loginForm.value.phone,
device_no: deviceNo, login_type: getStorage('loginType', 'session') === 'email' ? 1 : 2,
code: loginForm.value.code,
password: loginForm.value.password,
device_no: deviceNo,
}
await userStore.login(loginParams)
setStorage('device_no', deviceNo)
} finally {
// loading
stopButtonLoading()
} }
await userStore.login(loginParams)
setStorage('device_no', deviceNo)
} }
} catch (error) { } catch (error) {
console.error('表单校验失败:', error) console.error('表单校验失败:', error)

View File

@ -94,7 +94,7 @@
> >
</el-form-item> </el-form-item>
<el-form-item class="form-submit"> <el-form-item class="form-submit">
<el-button type="primary" class="form-btn" @click="handleRegister">注册</el-button> <el-button type="primary" class="form-btn" @click="handleRegister" :loading="buttonLoading">注册</el-button>
</el-form-item> </el-form-item>
<router-link to="/user/login" class="to-login">已有账号立即登录</router-link> <router-link to="/user/login" class="to-login">已有账号立即登录</router-link>
</el-form> </el-form>
@ -118,6 +118,7 @@ import UserCaptcha from './components/Captcha.vue'
import { useUserStore } from '@/stores/modules/user' import { useUserStore } from '@/stores/modules/user'
import { md5Encrypt } from '@/utils/crypto' import { md5Encrypt } from '@/utils/crypto'
import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha' import { sendCaptcha, initCaptchaState, clearCaptchaTimer } from '@/utils/sendCaptcha'
import { useButtonLoading } from '@/composables/useLoading'
// //
import { countryOptions } from '@/views/user/config/mock' import { countryOptions } from '@/views/user/config/mock'
@ -128,6 +129,9 @@ import { useRoute } from 'vue-router'
const userStore = useUserStore() const userStore = useUserStore()
const route = useRoute() const route = useRoute()
// loading
const { buttonLoading, startButtonLoading, stopButtonLoading } = useButtonLoading()
// UserText // UserText
const userText = ref({ const userText = ref({
backText: '', backText: '',
@ -215,19 +219,25 @@ const handleRegister = async () => {
try { try {
// //
await registerFormRef.value.validate() await registerFormRef.value.validate()
// loading
startButtonLoading()
try {
//
const registerParams = {
email: registerForm.value.email,
mobile: registerForm.value.countryCode + registerForm.value.phone,
reg_type: activeTab.value === 'email' ? 1 : 2,
invite_code: registerForm.value.inviteCode,
code: registerForm.value.code,
password: registerForm.value.password,
}
// //
const registerParams = { await userStore.register(registerParams)
email: registerForm.value.email, } finally {
mobile: registerForm.value.countryCode + registerForm.value.phone, // loading
reg_type: activeTab.value === 'email' ? 1 : 2, stopButtonLoading()
invite_code: registerForm.value.inviteCode,
code: registerForm.value.code,
password: registerForm.value.password,
} }
//
await userStore.register(registerParams)
} catch (error) { } catch (error) {
console.error('表单校验失败:', error) console.error('表单校验失败:', error)
} }
@ -239,7 +249,7 @@ onUnmounted(() => {
}) })
onMounted(() => { onMounted(() => {
registerForm.value.inviteCode = route.query.invite_code registerForm.value.inviteCode = route.query.invite_code || ''
}) })
</script> </script>