This commit is contained in:
parent
43906865b7
commit
e4b4f5ddb9
|
|
@ -78,21 +78,21 @@ const staticMenuList = ref<ElMenuItem[]>(
|
||||||
icon: 'HomeFilled' // 对应 <HomeFilled /> 图标
|
icon: 'HomeFilled' // 对应 <HomeFilled /> 图标
|
||||||
},
|
},
|
||||||
// 模板配置(子菜单)
|
// 模板配置(子菜单)
|
||||||
{
|
// {
|
||||||
id: 2,
|
// id: 2,
|
||||||
label: '模板配置',
|
// label: '模板配置',
|
||||||
path: '2', // 对应 el-sub-menu 的 index="2"
|
// path: '2', // 对应 el-sub-menu 的 index="2"
|
||||||
icon: 'List', // 对应 <List /> 图标
|
// icon: 'List', // 对应 <List /> 图标
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
id: 21,
|
// id: 21,
|
||||||
label: '头寸模板',
|
// label: '头寸模板',
|
||||||
path: '2-1', // 对应 el-menu-item 的 index="2-1"
|
// path: '2-1', // 对应 el-menu-item 的 index="2-1"
|
||||||
icon: ''
|
// icon: ''
|
||||||
// 二级菜单无图标(模板中未设置)
|
// // 二级菜单无图标(模板中未设置)
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
// 账户管理(子菜单)
|
// 账户管理(子菜单)
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
|
|
@ -197,18 +197,18 @@ const staticMenuList = ref<ElMenuItem[]>(
|
||||||
// path: '/funding/flowDetail', // index="6-6"
|
// path: '/funding/flowDetail', // index="6-6"
|
||||||
// icon: ''
|
// icon: ''
|
||||||
// },
|
// },
|
||||||
{
|
// {
|
||||||
id: 67,
|
// id: 67,
|
||||||
label: '收款账户列表',
|
// label: '收款账户列表',
|
||||||
path: '/funding/receiverAccount', // index="6-7"
|
// path: '/funding/receiverAccount', // index="6-7"
|
||||||
icon: ''
|
// icon: ''
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: 68,
|
// id: 68,
|
||||||
label: '存款渠道',
|
// label: '存款渠道',
|
||||||
path: '/funding/depositChannel', // index="6-8"
|
// path: '/funding/depositChannel', // index="6-8"
|
||||||
icon: ''
|
// icon: ''
|
||||||
}
|
// }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 系统管理(子菜单)
|
// 系统管理(子菜单)
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ const routes = [
|
||||||
{
|
{
|
||||||
path: 'menu',
|
path: 'menu',
|
||||||
name: 'Menu',
|
name: 'Menu',
|
||||||
component: () => import('@/views/system/menuManagement/index.vue'),
|
component: () => import('@/views/system/menu/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '菜单管理', // 左侧菜单显示的标题
|
title: '菜单管理', // 左侧菜单显示的标题
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +71,7 @@ const routes = [
|
||||||
{
|
{
|
||||||
path: 'role',
|
path: 'role',
|
||||||
name: 'Role',
|
name: 'Role',
|
||||||
component: () => import('@/views/system/roleManagement/index.vue'),
|
component: () => import('@/views/system/role/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '角色管理', // 左侧菜单显示的标题
|
title: '角色管理', // 左侧菜单显示的标题
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
// src/utils/excel.ts
|
||||||
|
import { ElMessageBox, ElNotification, ElMessage } from 'element-plus'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用 Excel 导出方法(自动拼接时间戳,避免文件重名)
|
||||||
|
* @param options 导出配置项
|
||||||
|
* @returns Promise<void>
|
||||||
|
*/
|
||||||
|
export const exportToExcel = async (options: {
|
||||||
|
/** 表格数据(数组) */
|
||||||
|
tableData: any[]
|
||||||
|
/** 列配置(包含 label: 表头文字, prop: 字段名) */
|
||||||
|
columns: Array<{ label: string; prop: string }>
|
||||||
|
/** 弹窗标题(默认:导出表格) */
|
||||||
|
title?: string
|
||||||
|
/** 默认文件名前缀(默认:导出数据) */
|
||||||
|
defaultFileNamePrefix?: string
|
||||||
|
/** 时间格式化格式(默认:YYYYMMDDHHmmss,避免特殊字符) */
|
||||||
|
timeFormat?: string
|
||||||
|
/** 通知自定义类名(可选) */
|
||||||
|
notificationClass?: string
|
||||||
|
/** 工作表名称(默认:Sheet1) */
|
||||||
|
sheetName?: string
|
||||||
|
}) => {
|
||||||
|
// 解构配置项并设置默认值
|
||||||
|
const {
|
||||||
|
tableData,
|
||||||
|
columns,
|
||||||
|
title = '导出表格',
|
||||||
|
defaultFileNamePrefix = '导出数据',
|
||||||
|
// 优化:默认格式去掉空格和冒号,避免文件名非法
|
||||||
|
timeFormat = 'YYYY-MM-DD',
|
||||||
|
notificationClass = 'global-notification',
|
||||||
|
sheetName = 'Sheet1'
|
||||||
|
} = options
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 校验表格数据
|
||||||
|
if (!tableData || tableData.length === 0) {
|
||||||
|
ElNotification({
|
||||||
|
message: '暂无表格数据可导出!',
|
||||||
|
type: 'error',
|
||||||
|
duration: 2000,
|
||||||
|
customClass: notificationClass
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 弹出输入框让用户输入文件名(兼容不同版本返回值)
|
||||||
|
const rawFileName = await ElMessageBox.prompt(
|
||||||
|
'请输入导出文件名称(会自动附带时间)', // 提示用户会附带时间
|
||||||
|
title,
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputPlaceholder: '例如:转账明细',
|
||||||
|
// 输入框校验:允许空输入(空输入时用默认前缀+时间)
|
||||||
|
inputValidator: (value) => {
|
||||||
|
if (value && !value.trim()) {
|
||||||
|
return '文件名不能仅包含空格!'
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
inputErrorMessage: '文件名不能仅包含空格!'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 核心修复:兼容 string / { value: string } 两种返回格式
|
||||||
|
let fileName = ''
|
||||||
|
if (typeof rawFileName === 'string') {
|
||||||
|
fileName = rawFileName
|
||||||
|
} else if (rawFileName && typeof (rawFileName as { value: string }).value === 'string') {
|
||||||
|
fileName = (rawFileName as { value: string }).value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 处理文件名:强制拼接时间(核心修改点)
|
||||||
|
const timeStr = dayjs().format(timeFormat)
|
||||||
|
// 优先级:用户输入的名称 → 默认前缀;无论哪种都拼接时间
|
||||||
|
const fileNamePrefix = fileName.trim() || defaultFileNamePrefix
|
||||||
|
const finalFileName = `${fileNamePrefix}_${timeStr}`
|
||||||
|
|
||||||
|
// 4. 构建带表头的Excel数据
|
||||||
|
const exportData = tableData.map(item => {
|
||||||
|
const row: Record<string, any> = {}
|
||||||
|
columns.forEach(header => {
|
||||||
|
row[header.label] = item[header.prop] || ''
|
||||||
|
})
|
||||||
|
return row
|
||||||
|
})
|
||||||
|
|
||||||
|
// 5. 创建工作表(包含表头)
|
||||||
|
const ws = XLSX.utils.json_to_sheet(exportData, {
|
||||||
|
header: columns.map(h => h.label), // 指定表头顺序
|
||||||
|
skipHeader: false // 不跳过表头(关键!保证表头显示)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 6. 创建工作簿并添加工作表
|
||||||
|
const wb = XLSX.utils.book_new()
|
||||||
|
XLSX.utils.book_append_sheet(wb, ws, sheetName)
|
||||||
|
|
||||||
|
// 7. 生成Excel二进制数据
|
||||||
|
const wbout = XLSX.write(wb, {
|
||||||
|
bookType: 'xlsx',
|
||||||
|
bookSST: false,
|
||||||
|
type: 'array'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 8. 触发下载(拼接.xlsx后缀)
|
||||||
|
saveAs(
|
||||||
|
new Blob([wbout], { type: 'application/octet-stream' }),
|
||||||
|
`${finalFileName}.xlsx`
|
||||||
|
)
|
||||||
|
|
||||||
|
// 9. 导出成功提示
|
||||||
|
ElNotification({
|
||||||
|
message: `文件「${finalFileName}.xlsx」导出成功!`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 2000,
|
||||||
|
customClass: notificationClass
|
||||||
|
})
|
||||||
|
} catch (e: any) {
|
||||||
|
// 取消导出时不提示错误
|
||||||
|
if (e !== 'cancel') {
|
||||||
|
ElMessage.error('导出失败,请重试!')
|
||||||
|
console.error('Excel 导出失败:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -280,6 +280,16 @@ const handleChange = (row: any) => {
|
||||||
dialogTitle.value = '修改客户'
|
dialogTitle.value = '修改客户'
|
||||||
dialogType.value = 'change'
|
dialogType.value = 'change'
|
||||||
useId.value = row.id
|
useId.value = row.id
|
||||||
|
clientForm.value = {
|
||||||
|
//手续费模板
|
||||||
|
feeTemplate: row.wallet_capital.fee_setting_id,
|
||||||
|
//风控模板
|
||||||
|
riskTemplate: row.wallet_capital.risk_control_id,
|
||||||
|
userName: row.username,
|
||||||
|
status: row.status,
|
||||||
|
isUpgrade: 1,
|
||||||
|
} as any
|
||||||
|
console.log('rowrowrowrowrowrowrowrowrow', clientForm.value)
|
||||||
getOptions()
|
getOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ export const clientAddFormItem = [
|
||||||
export const clientChangeFormItem = [
|
export const clientChangeFormItem = [
|
||||||
{ prop: 'feeTemplate', label: '手续费模板', type: 'select' as const, placeholder: '选择手续费模板' },
|
{ prop: 'feeTemplate', label: '手续费模板', type: 'select' as const, placeholder: '选择手续费模板' },
|
||||||
{ prop: 'riskTemplate', label: '风控模板', type: 'select' as const, placeholder: '选择风控模板' },
|
{ prop: 'riskTemplate', label: '风控模板', type: 'select' as const, placeholder: '选择风控模板' },
|
||||||
{ prop: 'changeName', label: '客户名称', type: 'input' as const, placeholder: '客户名称' },
|
{ prop: 'userName', label: '客户名称', type: 'input' as const, placeholder: '客户名称' },
|
||||||
{ prop: 'isUpgrade', label: '是否升级为代理', type: 'radio' as const, placeholder: '是否升级为代理', labelWidth: '140px' },
|
{ prop: 'isUpgrade', label: '是否升级为代理', type: 'radio' as const, placeholder: '是否升级为代理', labelWidth: '140px' },
|
||||||
{ prop: 'status', label: '选择状态', type: 'radio' as const, placeholder: '请选择状态', labelWidth: '140px' },
|
{ prop: 'status', label: '选择状态', type: 'radio' as const, placeholder: '请选择状态', labelWidth: '140px' },
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bar">
|
<div class="bar">
|
||||||
<el-button type="primary" @click="handleAdd">添加</el-button>
|
<el-button type="primary" @click="handleAdd">添加</el-button>
|
||||||
<el-button type="primary" @click="handleModify">编辑</el-button>
|
<el-button type="primary" @click="handleModify">编辑</el-button>
|
||||||
<el-button type="danger" @click="handleEnable">启用</el-button>
|
<el-button type="primary" @click="handleEnable">启用</el-button>
|
||||||
<el-button type="danger" @click="handleDisable">禁用</el-button>
|
<el-button type="danger" @click="handleDisable">禁用</el-button>
|
||||||
<el-button type="primary" @click="handleExport">导出</el-button>
|
<el-button type="primary" @click="handleExport">导出</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,6 @@
|
||||||
<TransferSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
<TransferSearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
||||||
@reset="handleReset">
|
@reset="handleReset">
|
||||||
<template #button="{ form }">
|
<template #button="{ form }">
|
||||||
<el-button type="primary" @click="handlePass()">
|
|
||||||
通过
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="handleReject()">
|
|
||||||
驳回
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="handleExport()">
|
<el-button type="primary" @click="handleExport()">
|
||||||
导出
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -31,20 +25,19 @@ import TransferTable from '@/components/common/Table.vue'
|
||||||
import TransferPagination from '@/components/common/Pagination.vue'
|
import TransferPagination from '@/components/common/Pagination.vue'
|
||||||
// 配置以及表单验证
|
// 配置以及表单验证
|
||||||
import { search, tableColumns } from './options'
|
import { search, tableColumns } from './options'
|
||||||
import { rules } from './rules'
|
|
||||||
|
|
||||||
// 接口
|
// 接口
|
||||||
import { getTransferDetailListApi } from '@/api/modules/funding/transferDetail'
|
import { getTransferDetailListApi } from '@/api/modules/funding/transferDetail'
|
||||||
|
|
||||||
// 导出表格
|
// 导出表格
|
||||||
import * as XLSX from 'xlsx'
|
import {exportToExcel} from '@/utils/exportToExcel'
|
||||||
import { saveAs } from 'file-saver'
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义搜索数据
|
* @description: 定义搜索数据
|
||||||
*/
|
*/
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
transferAccount: '',
|
transferAccount: '',
|
||||||
level: '',
|
level: '',
|
||||||
|
transferTime: '',
|
||||||
})
|
})
|
||||||
const searchOptions = ref(search)
|
const searchOptions = ref(search)
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,9 +52,6 @@ const tableRef = ref()
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10)
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
/**
|
|
||||||
* @description: 定义公共数据处理方法
|
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义公共请求数据方法
|
* @description: 定义公共请求数据方法
|
||||||
*/
|
*/
|
||||||
|
|
@ -70,9 +60,9 @@ const getTransferDetailList = async () => {
|
||||||
page: currentPage.value,
|
page: currentPage.value,
|
||||||
page_size: pageSize.value,
|
page_size: pageSize.value,
|
||||||
type: '',
|
type: '',
|
||||||
start_time: '2026-02-26 02:25:08',
|
start_time: searchForm.value.transferTime?.[0] || '2026-02-20 0:00:00',
|
||||||
end_time: '2026-03-26 02:25:08',
|
end_time: searchForm.value.transferTime?.[1] || '2026-03-20 23:59:59',
|
||||||
user_name: '',
|
user_name: searchForm.value.transferAccount || '',
|
||||||
order_id: '',
|
order_id: '',
|
||||||
}
|
}
|
||||||
const data: any = await getTransferDetailListApi(params)
|
const data: any = await getTransferDetailListApi(params)
|
||||||
|
|
@ -80,26 +70,20 @@ const getTransferDetailList = async () => {
|
||||||
tableTree.value = data.data.map((item: any) => ({
|
tableTree.value = data.data.map((item: any) => ({
|
||||||
//序号
|
//序号
|
||||||
index: item.id,
|
index: item.id,
|
||||||
|
//订单ID
|
||||||
|
orderId: item.order_id,
|
||||||
// 转出账户
|
// 转出账户
|
||||||
transferAccount: item.user.username,
|
transferAccount: item.user.username,
|
||||||
// 所属代理
|
// 所属代理
|
||||||
agentName: '',
|
agentName: '',
|
||||||
// 转入账号
|
// 转入账号
|
||||||
transferAccountName: item.to_user_id,
|
transferAccountName: item.to,
|
||||||
// 转账类型
|
// 转账类型
|
||||||
transferType: '',
|
transferType: item.type === 1 ? '内部' : '三方',
|
||||||
// 转账金额
|
// 转账金额
|
||||||
transferAmount: item.amount,
|
transferAmount: item.amount,
|
||||||
// 转账币种
|
|
||||||
transferCurrency: '',
|
|
||||||
// 到账金额
|
// 到账金额
|
||||||
arrivalAmount: item.amount,
|
arrivalAmount: item.amount,
|
||||||
// 到账币种
|
|
||||||
arrivalCurrency: '',
|
|
||||||
// 类型
|
|
||||||
type: '',
|
|
||||||
// 状态
|
|
||||||
status: '',
|
|
||||||
|
|
||||||
}))
|
}))
|
||||||
// 分页数据
|
// 分页数据
|
||||||
|
|
@ -120,90 +104,21 @@ const handleSearch = async () => {
|
||||||
getTransferDetailList()
|
getTransferDetailList()
|
||||||
}
|
}
|
||||||
const handleReset = async () => {
|
const handleReset = async () => {
|
||||||
getTransferDetailList()
|
searchForm.value.transferAccount = ''
|
||||||
}
|
searchForm.value.level = ''
|
||||||
const handlePass = async () => {
|
searchForm.value.transferTime = ''
|
||||||
getTransferDetailList()
|
|
||||||
}
|
|
||||||
const handleReject = async () => {
|
|
||||||
getTransferDetailList()
|
getTransferDetailList()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @description: 导出表格(带表头+自定义文件名)
|
* @description: 导出表格(带表头+自定义文件名)
|
||||||
*/
|
*/
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
try {
|
await exportToExcel({
|
||||||
// 1. 弹出输入框让用户输入文件名
|
tableData: tableTree.value,
|
||||||
const fileName = await ElMessageBox.prompt(
|
columns: tableColumnsOptions.value,
|
||||||
'请输入导出文件名称', // 弹窗提示语
|
title: '导出转账详情',
|
||||||
'导出表格', // 弹窗标题
|
defaultFileNamePrefix: '转账详情',
|
||||||
{
|
})
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
inputComponent: ElInput,
|
|
||||||
// 默认文件名(带时间戳)
|
|
||||||
inputValue: `转账明细_${new Date().getTime()}`,
|
|
||||||
// 输入框校验
|
|
||||||
inputValidator: (value) => {
|
|
||||||
if (!value.trim()) {
|
|
||||||
return '文件名不能为空!'
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
inputErrorMessage: '文件名不能为空!'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 2. 校验文件名(兜底处理)
|
|
||||||
const finalFileName = fileName.trim() || `转账明细_${new Date().getTime()}`
|
|
||||||
|
|
||||||
// 3. 校验表格数据
|
|
||||||
if (tableTree.value.length === 0) {
|
|
||||||
ElMessage.warning('暂无表格数据可导出!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 构建带表头的Excel数据
|
|
||||||
// 4.1 处理数据:将prop映射为中文表头
|
|
||||||
const exportData = tableTree.value.map(item => {
|
|
||||||
const row: Record<string, any> = {}
|
|
||||||
tableColumnsOptions.value.forEach(header => {
|
|
||||||
row[header.label] = item[header.prop] || ''
|
|
||||||
})
|
|
||||||
return row
|
|
||||||
})
|
|
||||||
|
|
||||||
// 4.2 创建工作表(包含表头)
|
|
||||||
const ws = XLSX.utils.json_to_sheet(exportData, {
|
|
||||||
header: tableColumnsOptions.value.map(h => h.label), // 指定表头顺序
|
|
||||||
skipHeader: false // 不跳过表头(关键!保证表头显示)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 4.3 创建工作簿并添加工作表
|
|
||||||
const wb = XLSX.utils.book_new()
|
|
||||||
XLSX.utils.book_append_sheet(wb, ws, '转账明细')
|
|
||||||
|
|
||||||
// 5. 生成Excel二进制数据
|
|
||||||
const wbout = XLSX.write(wb, {
|
|
||||||
bookType: 'xlsx',
|
|
||||||
bookSST: false,
|
|
||||||
type: 'array'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 6. 触发下载(拼接.xlsx后缀)
|
|
||||||
saveAs(
|
|
||||||
new Blob([wbout], { type: 'application/octet-stream' }),
|
|
||||||
`${finalFileName}.xlsx`
|
|
||||||
)
|
|
||||||
|
|
||||||
ElMessage.success(`文件「${finalFileName}.xlsx」导出成功!`)
|
|
||||||
} catch (e: any) {
|
|
||||||
// 取消导出时不提示错误
|
|
||||||
if (e !== 'cancel') {
|
|
||||||
ElMessage.error('导出失败,请重试!')
|
|
||||||
console.error('导出表格失败:', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -213,3 +128,17 @@ const handlePaginationChange = async () => {
|
||||||
getTransferDetailList()
|
getTransferDetailList()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.search-container {
|
||||||
|
:deep(.el-form) {
|
||||||
|
.el-form-item {
|
||||||
|
flex: none;
|
||||||
|
|
||||||
|
.el-select {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,27 @@ export const search = [
|
||||||
},
|
},
|
||||||
//级别
|
//级别
|
||||||
{
|
{
|
||||||
label: '级别',
|
label: '转账类型',
|
||||||
prop: 'level',
|
prop: 'level',
|
||||||
type: 'select' as const,
|
type: 'select' as const,
|
||||||
placeholder: '请选择级别',
|
placeholder: '请选择转账类型',
|
||||||
|
options: [
|
||||||
|
{ label: '客户', value: '1' },
|
||||||
|
{ label: '三方', value: '2' },
|
||||||
|
]
|
||||||
},
|
},
|
||||||
//全部
|
//选择时间
|
||||||
{
|
{
|
||||||
label: '级别',
|
label: '时间',
|
||||||
prop: 'level',
|
prop: 'transferTime',
|
||||||
type: 'select' as const,
|
type: 'date' as const,
|
||||||
placeholder: '全部',
|
dateType: 'datetimerange' as const,
|
||||||
}
|
placeholder: '请选择转账时间',
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
startPlaceholder: '开始时间',
|
||||||
|
endPlaceholder: '结束时间',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// 表格配置
|
// 表格配置
|
||||||
|
|
@ -39,14 +48,6 @@ export const tableColumns = [
|
||||||
{ label: '转账类型', prop: 'transferType' },
|
{ label: '转账类型', prop: 'transferType' },
|
||||||
//转账金额
|
//转账金额
|
||||||
{ label: '转账金额', prop: 'transferAmount' },
|
{ label: '转账金额', prop: 'transferAmount' },
|
||||||
//转账币种
|
|
||||||
{ label: '转账币种', prop: 'transferCurrency' },
|
|
||||||
// 到账金额
|
// 到账金额
|
||||||
{ label: '到账金额', prop: 'arrivalAmount' },
|
{ label: '到账金额', prop: 'arrivalAmount' },
|
||||||
//到账币种
|
|
||||||
{ label: '到账币种', prop: 'arrivalCurrency' },
|
|
||||||
//类型
|
|
||||||
{ label: '类型', prop: 'type' },
|
|
||||||
//状态
|
|
||||||
{ label: '状态', slotName: 'status' },
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@
|
||||||
<NoticePagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
|
<NoticePagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
|
||||||
@pagination-change="handlePaginationChange" />
|
@pagination-change="handlePaginationChange" />
|
||||||
<!-- dialog -->
|
<!-- dialog -->
|
||||||
<NoticeDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" :show-footer="dialogType !== 'view'" @confirm="handleSubmit"
|
<NoticeDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType"
|
||||||
@cancel="handleCancel" @close="handleClose">
|
:show-footer="dialogType !== 'view'" @confirm="handleSubmit" @cancel="handleCancel" @close="handleClose">
|
||||||
<NoticeForm :form-data="noticeForm" :form-rules="noticeRules" :form-items="noticeFormItem"
|
<NoticeForm :form-data="noticeForm" :form-rules="noticeRules" :form-items="noticeFormItem"
|
||||||
:options-map="noticeFormOptionsMap" ref="noticeFormRef" v-if="dialogType !== 'view'">
|
:options-map="noticeFormOptionsMap" ref="noticeFormRef" v-if="dialogType !== 'view'">
|
||||||
<template #noticeContent="{ formData }">
|
<template #noticeContent="{ formData }">
|
||||||
|
|
@ -156,8 +156,6 @@ const dialogType = ref('')
|
||||||
const noticeForm = ref({
|
const noticeForm = ref({
|
||||||
noticeName: '',
|
noticeName: '',
|
||||||
noticeContent: '',
|
noticeContent: '',
|
||||||
publishStartTime: '',
|
|
||||||
publishEndTime: '',
|
|
||||||
status: 1,
|
status: 1,
|
||||||
id: 0,
|
id: 0,
|
||||||
})
|
})
|
||||||
|
|
@ -166,8 +164,8 @@ const noticeRules = ref(rules())
|
||||||
const noticeFormItem = ref(formItem)
|
const noticeFormItem = ref(formItem)
|
||||||
const noticeFormOptionsMap = ref({
|
const noticeFormOptionsMap = ref({
|
||||||
status: [
|
status: [
|
||||||
{ label: '发布', value: 2 },
|
|
||||||
{ label: '草稿', value: 1 },
|
{ label: '草稿', value: 1 },
|
||||||
|
{ label: '发布', value: 2 },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -226,6 +224,12 @@ const handleCreate = () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = '新建公告'
|
dialogTitle.value = '新建公告'
|
||||||
dialogType.value = 'create'
|
dialogType.value = 'create'
|
||||||
|
noticeForm.value = {
|
||||||
|
noticeName: '',
|
||||||
|
noticeContent: '',
|
||||||
|
status: 1,
|
||||||
|
id: 0,
|
||||||
|
} as any
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -259,12 +263,10 @@ const handleEdit = (row: any) => {
|
||||||
dialogType.value = 'edit'
|
dialogType.value = 'edit'
|
||||||
noticeForm.value = {
|
noticeForm.value = {
|
||||||
noticeName: row.noticeName,
|
noticeName: row.noticeName,
|
||||||
noticeContent: row.noticeContent,
|
|
||||||
publishStartTime: row.startDateTime,
|
|
||||||
publishEndTime: row.endDateTime,
|
|
||||||
status: row.status,
|
status: row.status,
|
||||||
id: row.id,
|
id: row.id,
|
||||||
}
|
} as any
|
||||||
|
valueHtml.value = row.noticeContent
|
||||||
}
|
}
|
||||||
// 删除公告
|
// 删除公告
|
||||||
const handleDelete = async (row: any) => {
|
const handleDelete = async (row: any) => {
|
||||||
|
|
@ -298,7 +300,7 @@ const handleSubmit = async () => {
|
||||||
await createNoticeApi(params)
|
await createNoticeApi(params)
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
getNoticeList()
|
getNoticeList()
|
||||||
}else {
|
} else {
|
||||||
noticeForm.value.noticeContent = valueHtml.value
|
noticeForm.value.noticeContent = valueHtml.value
|
||||||
const params = {
|
const params = {
|
||||||
id: noticeForm.value.id,
|
id: noticeForm.value.id,
|
||||||
|
|
@ -357,8 +359,9 @@ const handleCreated = (editor: any) => {
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-content {
|
.view-content {
|
||||||
h2{
|
h2 {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,37 @@
|
||||||
import type { FormRules } from 'element-plus'
|
import type { FormRules } from 'element-plus'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用的五位小数校验函数(支持自定义提示文案)
|
* 数字校验函数:必须为数字 + 小数位不超过5位
|
||||||
* @param fieldName 字段名称(用于拼接提示文案)
|
* @param fieldName 字段名称(用于错误提示)
|
||||||
* @returns 校验器函数
|
* @returns 校验规则函数
|
||||||
*/
|
*/
|
||||||
const validateMaxFiveDecimals = (fieldName: string) => {
|
const validateMaxFiveDecimals = (fieldName: string) => {
|
||||||
return (rule: any, value: any, callback: any) => {
|
return (rule: any, value: any, callback: any) => {
|
||||||
if (value !== undefined && value !== null && value !== '') {
|
// 1. 空值处理:undefined/null/空字符串直接通过(如需必填可单独加required规则)
|
||||||
const decimalPart = value.toString().split('.')[1]
|
if (value === undefined || value === null || value === '') {
|
||||||
if (decimalPart && decimalPart.length > 5) {
|
return callback()
|
||||||
callback(new Error(`${fieldName}小数位不能超过5位`))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 先校验是否为有效数字(覆盖字符串数字、纯数字、负数等场景)
|
||||||
|
const num = Number(value)
|
||||||
|
if (isNaN(num)) {
|
||||||
|
return callback(new Error(`${fieldName}必须输入有效数字`))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 校验小数位是否超过5位
|
||||||
|
const valueStr = value.toString()
|
||||||
|
// 处理科学计数法(如 1e5)的情况,转为普通数字字符串
|
||||||
|
if (valueStr.includes('e') || valueStr.includes('E')) {
|
||||||
|
return callback(new Error(`${fieldName}不支持科学计数法格式,请输入普通数字`))
|
||||||
|
}
|
||||||
|
|
||||||
|
const decimalPart = valueStr.split('.')[1]
|
||||||
|
if (decimalPart && decimalPart.length > 5) {
|
||||||
|
return callback(new Error(`${fieldName}小数位不能超过5位`))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 所有校验通过
|
||||||
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -24,15 +39,15 @@ export const rules = (): FormRules => {
|
||||||
return {
|
return {
|
||||||
// 名称
|
// 名称
|
||||||
varietyName: [
|
varietyName: [
|
||||||
{ required: true, message: '请输入名称', trigger: ['blur'] }
|
{ required: true, message: '请输入名称', trigger: ['blur', 'change'] }
|
||||||
],
|
],
|
||||||
// 编号
|
// 编号
|
||||||
varietyCode: [
|
varietyCode: [
|
||||||
{ required: true, message: '请输入编号', trigger: ['blur'] }
|
{ required: true, message: '请输入编号', trigger: ['blur', 'change'] }
|
||||||
],
|
],
|
||||||
// 所属交易组
|
// 所属交易组
|
||||||
tradeGroup: [
|
tradeGroup: [
|
||||||
{ required: true, message: '请输入所属交易组', trigger: ['blur'] }
|
{ required: true, message: '请输入所属交易组', trigger: ['blur', 'change'] }
|
||||||
],
|
],
|
||||||
// 最大点差
|
// 最大点差
|
||||||
maxPoint: [
|
maxPoint: [
|
||||||
|
|
@ -42,49 +57,58 @@ export const rules = (): FormRules => {
|
||||||
// 最小点差
|
// 最小点差
|
||||||
minPoint: [
|
minPoint: [
|
||||||
{ required: true, message: '请输入最小点差', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入最小点差', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('最小点差'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('最小点差')}
|
||||||
],
|
],
|
||||||
// 合约大小
|
// 合约大小
|
||||||
contractSize: [
|
contractSize: [
|
||||||
{ required: true, message: '请输入合约大小', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入合约大小', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('合约大小'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('合约大小')}
|
||||||
],
|
],
|
||||||
// 多头库存费
|
// 多头库存费
|
||||||
longStockFee: [
|
longStockFee: [
|
||||||
{ required: true, message: '请输入多头库存费', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入多头库存费', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('多头库存费'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('多头库存费')}
|
||||||
],
|
],
|
||||||
// 空头库存费
|
// 空头库存费
|
||||||
shortStockFee: [
|
shortStockFee: [
|
||||||
{ required: true, message: '请输入空头库存费', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入空头库存费', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('空头库存费'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('空头库存费')}
|
||||||
],
|
],
|
||||||
// 预付款对冲
|
// 预付款对冲
|
||||||
prepaymentHedge: [
|
prepaymentHedge: [
|
||||||
{ required: true, message: '请输入预付款对冲', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入预付款对冲', trigger: ['blur', 'change'] },
|
||||||
|
|
||||||
{ validator: validateMaxFiveDecimals('预付款对冲'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('预付款对冲')}
|
||||||
],
|
],
|
||||||
// 预付款百分比
|
// 预付款百分比
|
||||||
prepaymentPercent: [
|
prepaymentPercent: [
|
||||||
{ required: true, message: '请输入预付款百分比', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入预付款百分比', trigger: ['blur', 'change'] },
|
||||||
|
|
||||||
{ validator: validateMaxFiveDecimals('预付款百分比'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('预付款百分比')}
|
||||||
],
|
],
|
||||||
// 小数位
|
// 小数位
|
||||||
decimalPlaces: [
|
decimalPlaces: [
|
||||||
{ required: true, message: '请输入小数位', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入小数位', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('小数位'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('小数位')}
|
||||||
],
|
],
|
||||||
// 点差小数位
|
// 点差小数位
|
||||||
pointDecimalPlaces: [
|
pointDecimalPlaces: [
|
||||||
{ required: true, message: '请输入点差小数位', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入点差小数位', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('点差小数位'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('点差小数位')}
|
||||||
],
|
],
|
||||||
// 止盈水平
|
// 止盈水平
|
||||||
profitLevel: [
|
profitLevel: [
|
||||||
{ required: true, message: '请输入止盈水平', trigger: ['blur', 'change'] },
|
{ required: true, message: '请输入止盈水平', trigger: ['blur', 'change'] },
|
||||||
{ validator: validateMaxFiveDecimals('止盈水平'), trigger: ['blur', 'change'] }
|
{ validator: validateMaxFiveDecimals('止盈水平')}
|
||||||
]
|
],
|
||||||
|
// 单位
|
||||||
|
unit: [
|
||||||
|
{ required: true, message: '请输入单位', trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 最小波动
|
||||||
|
minFlux: [
|
||||||
|
{ required: true, message: '请输入最小波动', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('最小波动')}
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue