BUG修复及dashboard页面接口对接

This commit is contained in:
Songsl 2026-04-26 21:05:03 +08:00
parent 44e43d81f3
commit 12dd2268ac
5 changed files with 890 additions and 783 deletions

View File

@ -0,0 +1,12 @@
import { request } from '@/api'
// 获取账户列表
export async function getAllAccount(params: any): Promise<any> {
return await request.get<any>('/user/getAllAccount', params)
}
// 获取用户钱包资金
export async function getWalletCapital(): Promise<any> {
return await request.get<any>('/user/getWalletCapital')
}

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +1,84 @@
<template>
<div class="variety">
<!-- 搜索 -->
<VarietySearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
@reset="handleReset">
<template #button="{ form }">
<el-button type="primary" :disabled="!selectedRow" @click="handleEdit()">
编辑
</el-button>
<el-button type="primary" @click="handleAdd()">
添加
</el-button>
</template>
</VarietySearch>
<!-- 表格 -->
<VarietyTable :table-data="varietyTree" :columns="varietyTableColumnsOptions" row-key="id"
@row-click="handleRowClick">
<template #onlineStatus="{ row }">
<el-switch :model-value="row.onlineStatus === 1" :active-value="true" :inactive-value="false" />
</template>
<template #tradeStatus="{ row }">
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" />
</template>
</VarietyTable>
</div>
<!-- dialog -->
<VarietyDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" @confirm="handleSubmit"
@cancel="handleCancel" @close="handleClose">
<VarietyForm :form-data="varietyForm" :form-rules="varietyFormRules" :form-items="dialogFormItemOptions"
:options-map="varietyFormOptionsMap" :row-gutter="rowGutter" :col-span="colSpan" ref="varietyFormRef">
<template #upload="{ formData }">
<el-upload v-model:file-list="fileList" class="upload-demo" :http-request="handleUpload"
:before-upload="beforeUpload" :limit="1">
<el-button type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png格式 图片大小不能超过20KB
</div>
</template>
<img v-if="dialogType === 'edit'" :src="formData.imageUrl" alt="预览图片"
style="width: 100px; height: 100px;">
</el-upload>
</template>
<template #isDefault="{ formData }">
<el-radio-group v-model="formData.isDefault" v-if="dialogType === 'edit'">
<el-radio :value="1" ></el-radio>
<el-radio :value="2"></el-radio>
</el-radio-group>
</template>
</VarietyForm>
</VarietyDialog>
<!-- dialog表格 -->
<div class="variety">
<!-- 搜索 -->
<VarietySearch
:search-form="searchForm"
:search-options="searchOptions"
@search="handleSearch"
@reset="handleReset"
>
<template #button="{ form }">
<el-button type="primary" :disabled="!selectedRow" @click="handleEdit()"> 编辑 </el-button>
<el-button type="primary" @click="handleAdd()"> 添加 </el-button>
</template>
</VarietySearch>
<!-- 表格 -->
<VarietyTable
:table-data="varietyTree"
:columns="varietyTableColumnsOptions"
row-key="id"
@row-click="handleRowClick"
>
<template #onlineStatus="{ row }">
<el-switch
:model-value="row.onlineStatus === 1"
:active-value="true"
:inactive-value="false"
/>
</template>
<template #tradeStatus="{ row }">
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" />
</template>
</VarietyTable>
</div>
<!-- dialog -->
<VarietyDialog
:visible="dialogVisible"
:title="dialogTitle"
:type="dialogType"
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
>
<VarietyForm
:form-data="varietyForm"
:form-rules="varietyFormRules"
:form-items="dialogFormItemOptions"
:options-map="varietyFormOptionsMap"
:row-gutter="rowGutter"
:col-span="colSpan"
ref="varietyFormRef"
>
<template #upload="{ formData }">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
:http-request="handleUpload"
:before-upload="beforeUpload"
:limit="1"
>
<el-button type="primary">点击上传</el-button>
<template #tip>
<div class="el-upload__tip">jpg/png格式 图片大小不能超过20KB</div>
</template>
<img
v-if="dialogType === 'edit'"
:src="formData.imageUrl"
alt="预览图片"
style="width: 100px; height: 100px"
/>
</el-upload>
</template>
<template #isDefault="{ formData }">
<el-radio-group v-model="formData.isDefault" v-if="dialogType === 'edit'">
<el-radio :value="1"></el-radio>
<el-radio :value="2"></el-radio>
</el-radio-group>
</template>
</VarietyForm>
</VarietyDialog>
<!-- dialog表格 -->
</template>
<script setup lang="ts">
@ -66,7 +93,12 @@ import { search, tableColumns, DialogFormItem } from './options'
import { rules } from './rules'
//
import { getVarietyListApi, getTradeGroupListApi, editVarietyApi, createVarietyApi } from '@/api/modules/trade/variety'
import {
getVarietyListApi,
getTradeGroupListApi,
editVarietyApi,
createVarietyApi,
} from '@/api/modules/trade/variety'
//
import { uploadImageApi } from '@/api/modules/upload'
@ -74,7 +106,7 @@ import { uploadImageApi } from '@/api/modules/upload'
* @description: 定义搜索数据
*/
const searchForm = ref({
varietyName: '',
varietyName: '',
})
const searchOptions = ref(search)
@ -95,79 +127,79 @@ const dialogType = ref('')
* @description: 定义弹窗表单数据
*/
const varietyForm = ref({
//
varietyName: '',
//
varietyCode: '',
// 线
onlineStatus: 1,
//
tradeStatus: 1,
//
minPoint: '',
//
maxPoint: '',
// ()
contractSize: '',
//
minFlux: '',
//
unit: '',
//
longStockFee: '',
//
shortStockFee: '',
//
profitLevel: '',
//
varietyName: '',
//
varietyCode: '',
// 线
onlineStatus: 1,
//
tradeStatus: 1,
//
minPoint: '',
//
maxPoint: '',
// ()
contractSize: '',
//
minFlux: '',
//
unit: '',
//
longStockFee: '',
//
shortStockFee: '',
//
profitLevel: '',
id: '',
groupId: '',
//
prepaymentHedge: '',
//
prepaymentPercent: '',
//
decimalPlaces: '',
//
pointDecimalPlaces: '',
//
type: '',
//
imageUrl: '',
//
feeInventoryTime: '',
//
tradeGroup: '',
//
isDefault: '',
id: '',
groupId: '',
//
prepaymentHedge: '',
//
prepaymentPercent: '',
//
decimalPlaces: '',
//
pointDecimalPlaces: '',
//
type: '',
//
imageUrl: '',
//
feeInventoryTime: '',
//
tradeGroup: '',
//
isDefault: '',
})
const varietyFormRef = ref<any>()
const varietyFormRules = ref(rules())
const dialogFormItemOptions = ref(DialogFormItem)
const varietyFormOptionsMap = ref({
tradeGroup: [],
type: [
{
label: '外汇',
value: 1,
},
{
label: '金属',
value: 2,
},
{
label: '能源',
value: 3,
},
{
label: '指数',
value: 4,
},
{
label: '数字货币',
value: 5,
},
],
group_id: [],
type: [
{
label: '外汇',
value: 1,
},
{
label: '金属',
value: 2,
},
{
label: '能源',
value: 3,
},
{
label: '指数',
value: 4,
},
{
label: '数字货币',
value: 5,
},
],
})
//
const selectedRow = ref<any>(null)
@ -177,11 +209,11 @@ const colSpan = ref(12)
const fileList = ref([])
const typeMap: any = {
1: '外汇',
2: '金属',
3: '能源',
4: '指数',
5: '数字货币',
1: '外汇',
2: '金属',
3: '能源',
4: '指数',
5: '数字货币',
}
/**
@ -190,122 +222,123 @@ const typeMap: any = {
//
const getVarietyList = async () => {
const params = {
name: searchForm.value.varietyName,
}
const data = await getVarietyListApi(params)
console.log('data', data)
//
varietyTree.value = data.map((item: any) => ({
...item,
id: item.id,
varietyName: item.name,
varietyCode: item.code,
onlineStatus: item.online_status,
tradeStatus: item.status,
minPoint: item.point_diff,
maxPoint: item.point_diff_max,
contractSize: item.multiplier,
minFlux: item.undulate_min,
unit: item.unit,
tradeGroup: item.group.name,
longStockFee: item.fee_inventory_long,
shortStockFee: item.fee_inventory_short,
profitLevel: item.stop_loss_level,
type: typeMap[item.type],
image: item.image,
}))
const params = {
name: searchForm.value.varietyName,
}
const data = await getVarietyListApi(params)
console.log('data', data)
//
varietyTree.value = data.map((item: any) => ({
...item,
id: item.id,
varietyName: item.name,
varietyCode: item.code,
onlineStatus: item.online_status,
tradeStatus: item.status,
minPoint: item.point_diff,
maxPoint: item.point_diff_max,
contractSize: item.multiplier,
minFlux: item.undulate_min,
unit: item.unit,
tradeGroup: item.group.name,
longStockFee: item.fee_inventory_long,
shortStockFee: item.fee_inventory_short,
profitLevel: item.stop_loss_level,
type: typeMap[item.type],
image: item.image,
}))
}
//
const getTradeGroupList = async () => {
const data = await getTradeGroupListApi()
varietyFormOptionsMap.value.tradeGroup = data.map((item: any) => ({
label: item.name,
value: item.id,
}))
const data = await getTradeGroupListApi()
varietyFormOptionsMap.value.group_id = data.map((item: any) => ({
label: item.name,
value: item.id,
}))
}
/**
* @description: 页面加载完成需要请求的数据
*/
onMounted(() => {
getVarietyList()
getTradeGroupList()
getVarietyList()
getTradeGroupList()
})
/**
* @description: 定义搜索方法
*/
const handleSearch = async () => {
getVarietyList()
getVarietyList()
}
const handleReset = () => {
searchForm.value = {
varietyName: '',
}
handleSearch()
searchForm.value = {
varietyName: '',
}
handleSearch()
}
const handleEdit = () => {
getTradeGroupList()
const row = selectedRow.value;
varietyForm.value = {
...row,
id: row.id,
groupId: row.group.id,
//
prepaymentHedge: row.bail_hedge,
//
prepaymentPercent: row.bail_percent,
//
decimalPlaces: row.decimal_place,
//
pointDecimalPlaces: row.point_diff_decimal_place,
imageUrl: row.image,
feeInventoryTime: row.fee_inventory_time,
//
isDefault: row.is_default,
} as any
getTradeGroupList()
const row = selectedRow.value
varietyForm.value = {
...row,
id: row.id,
group_id: row.group_id || row.group.id,
//
prepaymentHedge: row.bail_hedge,
//
prepaymentPercent: row.bail_percent,
//
decimalPlaces: row.decimal_place,
//
pointDecimalPlaces: row.point_diff_decimal_place,
imageUrl: row.image,
feeInventoryTime: row.fee_inventory_time,
//
isDefault: row.is_default,
} as any
//
dialogVisible.value = true
dialogTitle.value = '编辑合约品种'
dialogType.value = 'edit'
console.log('varietyForm.value', varietyForm.value)
//
dialogVisible.value = true
dialogTitle.value = '编辑合约品种'
dialogType.value = 'edit'
}
const handleAdd = () => {
dialogVisible.value = true
dialogTitle.value = '添加合约品种'
dialogType.value = 'add'
varietyForm.value = {
varietyName: '',
varietyCode: '',
onlineStatus: 1,
tradeStatus: 1,
minPoint: '',
maxPoint: '',
contractSize: '',
minFlux: '',
unit: '',
longStockFee: '',
shortStockFee: '',
profitLevel: '',
id: '',
groupId: '',
prepaymentHedge: '',
prepaymentPercent: '',
decimalPlaces: '',
pointDecimalPlaces: '',
type: '',
imageUrl: '',
feeInventoryTime: '',
tradeGroup: '',
//
isDefault: '',
}
fileList.value = []
dialogVisible.value = true
dialogTitle.value = '添加合约品种'
dialogType.value = 'add'
varietyForm.value = {
varietyName: '',
varietyCode: '',
onlineStatus: 1,
tradeStatus: 1,
minPoint: '',
maxPoint: '',
contractSize: '',
minFlux: '',
unit: '',
longStockFee: '',
shortStockFee: '',
profitLevel: '',
id: '',
groupId: '',
prepaymentHedge: '',
prepaymentPercent: '',
decimalPlaces: '',
pointDecimalPlaces: '',
type: '',
imageUrl: '',
feeInventoryTime: '',
tradeGroup: '',
//
isDefault: '',
}
fileList.value = []
}
/**
@ -313,92 +346,96 @@ const handleAdd = () => {
*/
//
const handleUpload = async (options: any) => {
const { file } = options
try {
const data = await uploadImageApi(file)
varietyForm.value.imageUrl = data.url
const { file } = options
try {
const data = await uploadImageApi(file)
varietyForm.value.imageUrl = data.url
// el-upload
options.onSuccess(data)
} catch (err) {
console.error('上传失败', err)
}
// el-upload
options.onSuccess(data)
} catch (err) {
console.error('上传失败', err)
}
}
// + 20KB = 20 * 1024
const beforeUpload = (file: File) => {
//
const fileName = file.name.toLowerCase();
const isJpgOrPng = fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png');
//
const fileName = file.name.toLowerCase()
const isJpgOrPng =
fileName.endsWith('.jpg') || fileName.endsWith('.jpeg') || fileName.endsWith('.png')
if (!isJpgOrPng) {
ElMessage.error('上传图片只能是 JPG/PNG 格式,且必须包含后缀名!');
return false;
}
if (!isJpgOrPng) {
ElMessage.error('上传图片只能是 JPG/PNG 格式,且必须包含后缀名!')
return false
}
// MIME
const isTypeValid = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isTypeValid) {
ElMessage.error('图片MIME类型不正确请重新选择!');
return false;
}
// MIME
const isTypeValid = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isTypeValid) {
ElMessage.error('图片MIME类型不正确请重新选择!')
return false
}
// (20KB)
const isSizeValid = file.size / 1024 < 20;
if (!isSizeValid) {
ElMessage.error('图片大小不能超过 20KB!');
return false;
}
// (20KB)
const isSizeValid = file.size / 1024 < 20
if (!isSizeValid) {
ElMessage.error('图片大小不能超过 20KB!')
return false
}
return true;
return true
}
/**
* @description: 定义弹窗方法
*/
const handleSubmit = async () => {
await varietyFormRef.value?.validate()
const params = {
id: varietyForm.value.id,
code: varietyForm.value.varietyCode,
name: varietyForm.value.varietyName,
group_id: varietyForm.value.tradeGroup,
point_diff: varietyForm.value.minPoint,
fee_inventory_short: varietyForm.value.shortStockFee,
status: varietyForm.value.tradeStatus,
bail_hedge: varietyForm.value.prepaymentHedge,
bail_percent: varietyForm.value.prepaymentPercent,
decimal_place: varietyForm.value.decimalPlaces,
stop_loss_level: varietyForm.value.profitLevel,
point_diff_max: varietyForm.value.maxPoint,
fee_inventory_long: varietyForm.value.longStockFee,
point_diff_decimal_place: varietyForm.value.pointDecimalPlaces,
unit: varietyForm.value.unit,
multiplier: varietyForm.value.contractSize,
undulate_min: varietyForm.value.minFlux,
online_status: varietyForm.value.onlineStatus,
type: Number(varietyForm.value.type),
image: varietyForm.value.imageUrl,
fee_inventory_time: varietyForm.value.feeInventoryTime,
}
console.log(params)
await varietyFormRef.value?.validate()
console.log(varietyForm.value)
const params = {
id: varietyForm.value.id,
code: varietyForm.value.varietyCode,
name: varietyForm.value.varietyName,
point_diff: varietyForm.value.minPoint,
fee_inventory_short: varietyForm.value.shortStockFee,
status: varietyForm.value.tradeStatus,
bail_hedge: varietyForm.value.prepaymentHedge,
bail_percent: varietyForm.value.prepaymentPercent,
decimal_place: varietyForm.value.decimalPlaces,
stop_loss_level: varietyForm.value.profitLevel,
point_diff_max: varietyForm.value.maxPoint,
fee_inventory_long: varietyForm.value.longStockFee,
point_diff_decimal_place: varietyForm.value.pointDecimalPlaces,
unit: varietyForm.value.unit,
multiplier: varietyForm.value.contractSize,
undulate_min: varietyForm.value.minFlux,
online_status: varietyForm.value.onlineStatus,
type: Number(varietyForm.value.type),
image: varietyForm.value.imageUrl,
fee_inventory_time: varietyForm.value.feeInventoryTime,
group_id: varietyForm.value.group_id,
}
console.log(params)
if (dialogType.value === 'edit') {
console.log(params)
await editVarietyApi({ ...params, group_id: selectedRow.value.group.id, is_default: varietyForm.value.isDefault })
getVarietyList()
} else {
await createVarietyApi({ ...params })
getVarietyList()
}
dialogVisible.value = false
if (dialogType.value === 'edit') {
console.log(params)
await editVarietyApi({
...params,
is_default: varietyForm.value.isDefault,
})
await getVarietyList()
} else {
await createVarietyApi({ ...params })
await getVarietyList()
}
dialogVisible.value = false
}
const handleCancel = () => {
dialogVisible.value = false
dialogVisible.value = false
}
const handleClose = () => {
dialogVisible.value = false
dialogVisible.value = false
}
/**
@ -406,24 +443,24 @@ const handleClose = () => {
*/
//
const handleRowClick = (row: any) => {
if (!row) {
selectedRow.value = null
return
}
selectedRow.value = row
if (!row) {
selectedRow.value = null
return
}
selectedRow.value = row
}
</script>
<style scoped lang="scss">
.search-container {
:deep(.el-form) {
.el-form-item {
flex: none;
}
:deep(.el-form) {
.el-form-item {
flex: none;
}
}
}
:deep(.el-upload) {
flex-direction: column;
flex-direction: column;
}
</style>

View File

@ -51,7 +51,7 @@ export const DialogFormItem = [
// 编号
{ prop: 'varietyCode', label: '编号', type: 'input' as const, placeholder: '请输入编号' },
// 交易分组
{ prop: 'tradeGroup', label: '交易分组', type: 'select' as const, placeholder: '请选择交易分组' },
{ prop: 'group_id', label: '交易分组', type: 'select' as const, placeholder: '请选择交易分组' },
// 最大点差
{ prop: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' },
// 最小点差
@ -110,7 +110,9 @@ export const DialogFormItem = [
{ prop: 'type', label: '类型', type: 'select' as const, placeholder: '请选择类型' },
// 库存费收取时间
{
prop: 'feeInventoryTime', label: '库存费收取时间', type: 'time' as const,
prop: 'feeInventoryTime',
label: '库存费收取时间',
type: 'time' as const,
valueFormat: 'HH:mm:ss',
isRange: false,
},

View File

@ -38,89 +38,78 @@ const validateMaxFiveDecimals = (fieldName: string) => {
export const rules = (): FormRules => {
return {
// 名称
varietyName: [
{ required: true, message: '请输入名称', trigger: ['blur', 'change'] }
],
varietyName: [{ required: true, message: '请输入名称', trigger: ['blur', 'change'] }],
// 编号
varietyCode: [
{ required: true, message: '请输入编号', trigger: ['blur', 'change'] }
],
varietyCode: [{ required: true, message: '请输入编号', trigger: ['blur', 'change'] }],
// 所属交易时间
tradeTime: [
{ required: true, message: '请选择交易时间', trigger: ['blur', 'change'] }
],
tradeTime: [{ required: true, message: '请选择交易时间', trigger: ['blur', 'change'] }],
// 最大点差
maxPoint: [
{ required: true, message: '请输入最大点差', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('最大点差'), trigger: ['blur', 'change'] }
{ validator: validateMaxFiveDecimals('最大点差'), trigger: ['blur', 'change'] },
],
// 最小点差
minPoint: [
{ required: true, message: '请输入最小点差', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('最小点差')}
{ validator: validateMaxFiveDecimals('最小点差') },
],
// 合约大小
contractSize: [
{ required: true, message: '请输入合约大小', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('合约大小')}
{ validator: validateMaxFiveDecimals('合约大小') },
],
// 多头库存费
longStockFee: [
{ required: true, message: '请输入多头库存费', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('多头库存费')}
{ validator: validateMaxFiveDecimals('多头库存费') },
],
// 空头库存费
shortStockFee: [
{ required: true, message: '请输入空头库存费', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('空头库存费')}
{ validator: validateMaxFiveDecimals('空头库存费') },
],
// 预付款对冲
prepaymentHedge: [
{ required: true, message: '请输入预付款对冲', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('预付款对冲')}
{ validator: validateMaxFiveDecimals('预付款对冲') },
],
// 预付款百分比
prepaymentPercent: [
{ required: true, message: '请输入预付款百分比', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('预付款百分比')}
{ validator: validateMaxFiveDecimals('预付款百分比') },
],
// 小数位
decimalPlaces: [
{ required: true, message: '请输入小数位', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('小数位')}
{ validator: validateMaxFiveDecimals('小数位') },
],
// 点差小数位
pointDecimalPlaces: [
{ required: true, message: '请输入点差小数位', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('点差小数位')}
{ validator: validateMaxFiveDecimals('点差小数位') },
],
// 止盈水平
profitLevel: [
{ required: true, message: '请输入止盈水平', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('止盈水平')}
{ validator: validateMaxFiveDecimals('止盈水平') },
],
// 单位
unit: [
{ required: true, message: '请输入单位', trigger: ['blur', 'change'] }
],
unit: [{ required: true, message: '请输入单位', trigger: ['blur', 'change'] }],
// 最小波动
minFlux: [
{ required: true, message: '请输入最小波动', trigger: ['blur', 'change'] },
{ validator: validateMaxFiveDecimals('最小波动')}
{ validator: validateMaxFiveDecimals('最小波动') },
],
// 类型
type: [
{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }
],
type: [{ required: true, message: '请选择类型', trigger: ['blur', 'change'] }],
// 上传图片
imageUrl: [
{ required: true, message: '请上传图片', trigger: ['blur', 'change'] }
],
imageUrl: [{ required: true, message: '请上传图片', trigger: ['blur', 'change'] }],
// 库存费收取时间
feeInventoryTime: [
{ required: true, message: '请选择库存费收取时间', trigger: ['blur', 'change'] }
{ required: true, message: '请选择库存费收取时间', trigger: ['blur', 'change'] },
],
group_id: [{ required: true, message: '请选择交易分组', trigger: ['blur', 'change'] }],
}
}