commit
792e21ab23
|
|
@ -1,7 +1,7 @@
|
|||
# 开发环境标识(Vite 内置变量,无需修改)
|
||||
NODE_ENV = development
|
||||
|
||||
# 开发环境接口基础地址(192.168.11.183:8085/api)
|
||||
# 开发环境接口基础地址(对应你配置的 http://192.168.11.183:8085/api)
|
||||
VITE_API_BASE_URL = http://192.168.11.183:8085/api
|
||||
|
||||
# 请求超时时间(毫秒)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
NODE_ENV = production
|
||||
|
||||
# 生产环境接口基础地址
|
||||
VITE_API_BASE_URL = https://api.yourdomain.com
|
||||
VITE_API_BASE_URL = http://18.167.120.9:8086/api
|
||||
|
||||
# 请求超时时间(毫秒)
|
||||
VITE_REQUEST_TIMEOUT = 10000
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ coverage
|
|||
|
||||
.eslintcache
|
||||
|
||||
package-lock.json
|
||||
|
||||
# Cypress
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"build:prod": "vite build --mode production",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import axios from 'axios'
|
|||
import type { AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios'
|
||||
import type { ApiResponse } from '@/api/types'
|
||||
import { ElLoading, ElNotification } from 'element-plus'
|
||||
import { getStorage, setStorage } from '@/utils/storage'
|
||||
import { getStorage, setStorage, removeStorage } from '@/utils/storage'
|
||||
import router from '../router'
|
||||
|
||||
// 定义loading实例类型,用于控制loading的显示和关闭
|
||||
let loadingInstance: ReturnType<typeof ElLoading.service> | null = null
|
||||
|
|
@ -14,7 +15,7 @@ const showLoading = () => {
|
|||
if (requestCount === 0 && !loadingInstance) {
|
||||
loadingInstance = ElLoading.service({
|
||||
lock: true, // 锁定屏幕滚动
|
||||
fullscreen: true // 全屏显示
|
||||
fullscreen: true, // 全屏显示
|
||||
})
|
||||
}
|
||||
requestCount++
|
||||
|
|
@ -46,7 +47,7 @@ const service = axios.create({
|
|||
|
||||
// 3. 请求拦截器:直接使用 axios 内置类型
|
||||
const requestInterceptor = (config: InternalAxiosRequestConfig) => {
|
||||
console.log('请求配置', config);
|
||||
console.log('请求配置', config)
|
||||
|
||||
// 显示loading(可通过config配置项控制是否显示,比如某些请求不需要loading)
|
||||
if (config.headers?.showLoading !== false) {
|
||||
|
|
@ -82,9 +83,9 @@ const responseInterceptor = <T = unknown>(response: AxiosResponse<ApiResponse<T>
|
|||
if (response.headers['new_token'] !== undefined) {
|
||||
setStorage('token', response.headers['new_token'] as string)
|
||||
}
|
||||
console.log('响应response', response);
|
||||
console.log('响应response', response)
|
||||
const { data } = response
|
||||
console.log('响应数据data', data);
|
||||
console.log('响应数据data', data)
|
||||
// 判断业务状态码
|
||||
if (data.code == 200 || data.code == 0) {
|
||||
if (config.showMessage !== false) {
|
||||
|
|
@ -97,19 +98,19 @@ const responseInterceptor = <T = unknown>(response: AxiosResponse<ApiResponse<T>
|
|||
}
|
||||
return data.data
|
||||
} else {
|
||||
if (data.code === 1) {
|
||||
// 不弹错误提示,返回带特殊标识的结果
|
||||
// 其他业务失败:弹错误提示并拒绝Promise
|
||||
ElNotification({
|
||||
message: data.msg || '未知的错误!',
|
||||
type: 'error',
|
||||
duration: 2000,
|
||||
customClass: 'global-notification'
|
||||
})
|
||||
const result = {
|
||||
isUserNotExist: true, // 自定义标识,标记“用户不存在”
|
||||
} as T
|
||||
return result
|
||||
switch (data.code) {
|
||||
case 1:
|
||||
if (!data.msg) {
|
||||
data.msg = '未知的错误!'
|
||||
}
|
||||
break
|
||||
case -101:
|
||||
data.msg = 'token错误!'
|
||||
removeStorage('token')
|
||||
router.push({ name: 'Login' })
|
||||
break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// 其他业务失败:弹错误提示并拒绝Promise
|
||||
|
|
@ -117,7 +118,7 @@ const responseInterceptor = <T = unknown>(response: AxiosResponse<ApiResponse<T>
|
|||
message: data.msg || '未知的错误!',
|
||||
type: 'error',
|
||||
duration: 2000,
|
||||
customClass: 'global-notification'
|
||||
customClass: 'global-notification',
|
||||
})
|
||||
return Promise.reject(data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
import { request } from '@/api';
|
||||
|
||||
type SettingFormParams = {
|
||||
key: string
|
||||
value: string
|
||||
description: string
|
||||
}
|
||||
|
||||
type SettingListResponse = SettingFormParams & {
|
||||
id: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设置列表
|
||||
* @returns Promise<MenuListResponse> 设置列表数据
|
||||
*/
|
||||
export async function getSettingApi(): Promise<SettingListResponse[]> {
|
||||
return request.get<SettingListResponse[]>('/setting/getList')
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加设置
|
||||
* @param params
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function createSettingApi(params: SettingFormParams): Promise<void> {
|
||||
return request.post<void>('/setting/add', params)
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑设置
|
||||
* @param params 菜单表单参数(含id)
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
export async function editSettingApi(params: SettingFormParams): Promise<void> {
|
||||
return request.post<void>('/setting/edit', params)
|
||||
}
|
||||
|
||||
|
|
@ -7,15 +7,15 @@ export async function getGroupListApi(): Promise<any> {
|
|||
|
||||
// 创建交易组
|
||||
export async function addGroupApi(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/createGroup', {...params})
|
||||
return request.post<any>('/contractVariety/createGroup', { ...params })
|
||||
}
|
||||
|
||||
//编辑交易组
|
||||
export async function editGroupApi(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/editGroup', {...params})
|
||||
return request.post<any>('/contractVariety/editGroup', { ...params })
|
||||
}
|
||||
|
||||
// 删除交易组
|
||||
export async function deleteGroupApi(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/delGroup', {...params})
|
||||
return request.post<any>('/contractVariety/delGroup', { ...params })
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { request } from '@/api';
|
||||
|
||||
// 获取节假日列表
|
||||
export async function getHolidayList(): Promise<any> {
|
||||
return request.get<any>('/contractVariety/getHolidayList')
|
||||
}
|
||||
|
||||
// 添加节假日
|
||||
export async function addHoliday(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/addHoliday', { ...params })
|
||||
}
|
||||
|
||||
//编辑节假日
|
||||
export async function editHoliday(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/editHoliday', { ...params })
|
||||
}
|
||||
|
||||
// 删除节假日
|
||||
export async function delHoliday(params: any): Promise<any> {
|
||||
return request.post<any>('/contractVariety/delHoliday', { ...params })
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
|
|
@ -38,12 +38,20 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { HomeFilled, List, UserFilled, Platform, BellFilled, GoodsFilled, WarningFilled, Tools } from '@element-plus/icons-vue'
|
||||
import {
|
||||
HomeFilled,
|
||||
List,
|
||||
UserFilled,
|
||||
Platform,
|
||||
BellFilled,
|
||||
GoodsFilled,
|
||||
WarningFilled,
|
||||
Tools,
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
//获取格式化后的菜单列表
|
||||
import { useUserStore } from '@/stores/modules/user'
|
||||
|
||||
|
||||
const route = useRoute()
|
||||
const userStore = useUserStore()
|
||||
const menuList = ref<any[]>([])
|
||||
|
|
@ -66,22 +74,20 @@ const iconMap: Record<string, any> = {
|
|||
BellFilled,
|
||||
GoodsFilled,
|
||||
WarningFilled,
|
||||
Tools
|
||||
Tools,
|
||||
}
|
||||
|
||||
|
||||
// 菜单假数据,具体要根据实际菜单数据进行调整
|
||||
import type { ElMenuItem } from '@/utils/menuFormat';
|
||||
import type { ElMenuItem } from '@/utils/menuFormat'
|
||||
|
||||
// 抽离后的菜单数据(完全匹配模板中的结构和配置)
|
||||
const staticMenuList = ref<ElMenuItem[]>(
|
||||
[
|
||||
const staticMenuList = ref<ElMenuItem[]>([
|
||||
// 首页
|
||||
{
|
||||
id: 1,
|
||||
label: '首页',
|
||||
path: 'dashboard', // 对应 el-menu-item 的 index="dashboard"
|
||||
icon: 'HomeFilled' // 对应 <HomeFilled /> 图标
|
||||
icon: 'HomeFilled', // 对应 <HomeFilled /> 图标
|
||||
},
|
||||
// 模板配置(子菜单)
|
||||
// {
|
||||
|
|
@ -110,33 +116,33 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 31,
|
||||
label: '客户管理',
|
||||
path: '/account/client', // index="client"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
label: '代理管理',
|
||||
path: '/account/agentList', // index="3-2"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 33,
|
||||
label: '做市商管理',
|
||||
path: '/account/market-maker', // index="3-3"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 34,
|
||||
label: '档案管理',
|
||||
path: '/account/archives', // index="3-4"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 35,
|
||||
label: '账号管理',
|
||||
path: '/account/accountDetail', // index="3-5"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
// 交易管理(子菜单)
|
||||
{
|
||||
|
|
@ -149,46 +155,46 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 41,
|
||||
label: '品种',
|
||||
path: '/trade/variety', // index="4-1"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 42,
|
||||
label: '交易组',
|
||||
label: '交易时间',
|
||||
path: '/trade/group', // index="4-2"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 43,
|
||||
label: '持仓统计',
|
||||
path: '/trade/positionStat', // index="4-3"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 44,
|
||||
label: '历史交易',
|
||||
path: '/trade/historyTrade', // index="4-4"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 45,
|
||||
label: '交易软件',
|
||||
path: '/trade/tradeSoftware', // index="4-5"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
// {
|
||||
// id: 43,
|
||||
// label: '交易时间',
|
||||
// path: '/trade/time', // index="4-3"
|
||||
// icon: ''
|
||||
// }
|
||||
]
|
||||
{
|
||||
id: 46,
|
||||
label: '节假日时间',
|
||||
path: '/trade/time', // index="4-3"
|
||||
icon: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 公告管理
|
||||
{
|
||||
id: 5,
|
||||
label: '公告管理',
|
||||
path: '/notice', // index="5"
|
||||
icon: 'BellFilled' // 对应 <BellFilled /> 图标
|
||||
icon: 'BellFilled', // 对应 <BellFilled /> 图标
|
||||
},
|
||||
// 资金管理(子菜单)
|
||||
{
|
||||
|
|
@ -225,19 +231,19 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 64,
|
||||
label: '转账',
|
||||
path: '/funding/transfer', // index="6-4"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 65,
|
||||
label: '转账明细',
|
||||
path: '/funding/transferDetail', // index="6-5"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 66,
|
||||
label: '资金明细',
|
||||
path: '/funding/fundDetail', // index="6-6"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
// {
|
||||
// id: 66,
|
||||
|
|
@ -257,7 +263,7 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
// path: '/funding/depositChannel', // index="6-8"
|
||||
// icon: ''
|
||||
// }
|
||||
]
|
||||
],
|
||||
},
|
||||
// 系统管理(子菜单)
|
||||
{
|
||||
|
|
@ -270,25 +276,30 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 71,
|
||||
label: '菜单管理',
|
||||
path: '/system/menu', // index="6-1"(模板中此处 index 写的是 6-1,保留原配置)
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 72,
|
||||
label: '角色管理',
|
||||
path: '/system/role', // index="6-2"(模板中此处 index 写的是 6-2,保留原配置)
|
||||
icon: ''
|
||||
}
|
||||
]
|
||||
icon: '',
|
||||
},
|
||||
{
|
||||
id: 73,
|
||||
label: '系统设置',
|
||||
path: '/system/setting', // index="6-2"(模板中此处 index 写的是 6-2,保留原配置)
|
||||
icon: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 风控管理
|
||||
{
|
||||
id: 8,
|
||||
label: '风控管理',
|
||||
path: '/risk', // index="8"
|
||||
icon: 'WarningFilled' // 对应 <WarningFilled /> 图标
|
||||
icon: 'WarningFilled', // 对应 <WarningFilled /> 图标
|
||||
},
|
||||
|
||||
|
||||
// 资金管理(子菜单)
|
||||
// {
|
||||
// id: 9,
|
||||
|
|
@ -337,16 +348,16 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 121,
|
||||
label: '跟单记录',
|
||||
path: '/personalized/followRecord', // index="12-1"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
// 带单记录
|
||||
{
|
||||
id: 122,
|
||||
label: '带单记录',
|
||||
path: '/personalized/leadRecord', // index="12-2"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
// 代理管理(子菜单)
|
||||
{
|
||||
|
|
@ -360,23 +371,23 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
id: 132,
|
||||
label: '客户列表',
|
||||
path: '/agent/customerList', // index="13-2"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
//客户交易订单
|
||||
{
|
||||
id: 133,
|
||||
label: '客户交易订单',
|
||||
path: '/agent/customerTradeOrder', // index="13-3"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
//客户资金流水
|
||||
{
|
||||
id: 135,
|
||||
label: '客户资金流水',
|
||||
path: '/agent/customerCapitalFlow', // index="13-5"
|
||||
icon: ''
|
||||
icon: '',
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
// 通知管理(子菜单)
|
||||
{
|
||||
|
|
@ -385,8 +396,7 @@ const staticMenuList = ref<ElMenuItem[]>(
|
|||
path: 'notification', // index="notification"
|
||||
icon: 'NotificationFilled', // 对应 <NotificationFilled /> 图标
|
||||
},
|
||||
]
|
||||
)
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
@ -414,9 +424,8 @@ aside {
|
|||
border: none;
|
||||
|
||||
:deep(.el-menu-item.is-active) {
|
||||
background-color: var(--el-menu-hover-bg-color)
|
||||
background-color: var(--el-menu-hover-bg-color);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -14,39 +14,39 @@ const routes = [
|
|||
path: 'login',
|
||||
name: 'Login',
|
||||
component: () => import('@/views/user/Login.vue'),
|
||||
meta: { isAuthPage: true, title: '登录' }
|
||||
meta: { isAuthPage: true, title: '登录' },
|
||||
},
|
||||
{
|
||||
path: 'register',
|
||||
name: 'Register',
|
||||
component: () => import('@/views/user/Register.vue'),
|
||||
meta: { isAuthPage: true, title: '注册' }
|
||||
meta: { isAuthPage: true, title: '注册' },
|
||||
},
|
||||
{
|
||||
path: 'forgot-password',
|
||||
name: 'ForgotPassword',
|
||||
component: () => import('@/views/user/ForgotPassword.vue'),
|
||||
meta: { isAuthPage: true, title: '忘记密码' }
|
||||
meta: { isAuthPage: true, title: '忘记密码' },
|
||||
},
|
||||
{
|
||||
path: 'change-password',
|
||||
name: 'ChangePassword',
|
||||
component: () => import('@/views/user/ChangePassword.vue'),
|
||||
meta: { requiresAuth: true, title: '修改密码' }
|
||||
meta: { requiresAuth: true, title: '修改密码' },
|
||||
},
|
||||
{
|
||||
path: 'bind-email',
|
||||
name: 'BindEmail',
|
||||
component: () => import('@/views/user/bindEmail.vue'),
|
||||
meta: { requiresAuth: true, title: '绑定邮箱' }
|
||||
meta: { requiresAuth: true, title: '绑定邮箱' },
|
||||
},
|
||||
{
|
||||
path: 'bind-phone',
|
||||
name: 'BindPhone',
|
||||
component: () => import('@/views/user/bindPhone.vue'),
|
||||
meta: { requiresAuth: true, title: '绑定手机号' }
|
||||
}
|
||||
]
|
||||
meta: { requiresAuth: true, title: '绑定手机号' },
|
||||
},
|
||||
],
|
||||
},
|
||||
// 带侧边栏布局的核心业务页面
|
||||
{
|
||||
|
|
@ -62,7 +62,7 @@ const routes = [
|
|||
component: () => import('@/views/dashboard/index.vue'),
|
||||
meta: {
|
||||
title: '首页', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
// 系统管理
|
||||
{
|
||||
|
|
@ -78,7 +78,7 @@ const routes = [
|
|||
component: () => import('@/views/system/menu/index.vue'),
|
||||
meta: {
|
||||
title: '菜单管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
|
|
@ -86,9 +86,17 @@ const routes = [
|
|||
component: () => import('@/views/system/role/index.vue'),
|
||||
meta: {
|
||||
title: '角色管理', // 左侧菜单显示的标题
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
name: 'Setting',
|
||||
component: () => import('@/views/system/setting/index.vue'),
|
||||
meta: {
|
||||
title: '系统设置', // 左侧菜单显示的标题
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
//模板配置
|
||||
{
|
||||
|
|
@ -97,7 +105,7 @@ const routes = [
|
|||
meta: {
|
||||
title: '模板配置', // 左侧菜单显示的标题
|
||||
},
|
||||
children: []
|
||||
children: [],
|
||||
},
|
||||
//账户管理
|
||||
{
|
||||
|
|
@ -113,7 +121,7 @@ const routes = [
|
|||
component: () => import('@/views/account/client/index.vue'),
|
||||
meta: {
|
||||
title: '客户管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'agentList',
|
||||
|
|
@ -121,7 +129,7 @@ const routes = [
|
|||
component: () => import('@/views/account/agentList/index.vue'),
|
||||
meta: {
|
||||
title: '代理管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'market-maker',
|
||||
|
|
@ -129,7 +137,7 @@ const routes = [
|
|||
component: () => import('@/views/account/market-maker/index.vue'),
|
||||
meta: {
|
||||
title: '做市商管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'archives',
|
||||
|
|
@ -137,7 +145,7 @@ const routes = [
|
|||
component: () => import('@/views/account/archives/index.vue'),
|
||||
meta: {
|
||||
title: '档案管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'accountDetail',
|
||||
|
|
@ -145,9 +153,9 @@ const routes = [
|
|||
component: () => import('@/views/account/accountDetail/index.vue'),
|
||||
meta: {
|
||||
title: '账号管理', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
//交易管理
|
||||
{
|
||||
|
|
@ -163,31 +171,31 @@ const routes = [
|
|||
component: () => import('@/views/trade/variety/index.vue'),
|
||||
meta: {
|
||||
title: '品种', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'group',
|
||||
name: 'Group',
|
||||
component: () => import('@/views/trade/group/index.vue'),
|
||||
meta: {
|
||||
title: '交易组', // 左侧菜单显示的标题
|
||||
}
|
||||
title: '交易时间', // 左侧菜单显示的标题
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'time',
|
||||
name: 'Time',
|
||||
component: () => import('@/views/trade/time/index.vue'),
|
||||
meta: {
|
||||
title: '节假日时间', // 左侧菜单显示的标题
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'time',
|
||||
// name: 'Time',
|
||||
// component: () => import('@/views/trade/time/index.vue'),
|
||||
// meta: {
|
||||
// title: '交易时间', // 左侧菜单显示的标题
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: 'positionStat',
|
||||
name: 'PositionStat',
|
||||
component: () => import('@/views/trade/positionStat/index.vue'),
|
||||
meta: {
|
||||
title: '持仓统计', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'historyTrade',
|
||||
|
|
@ -195,7 +203,7 @@ const routes = [
|
|||
component: () => import('@/views/trade/historyTrade/index.vue'),
|
||||
meta: {
|
||||
title: '历史交易', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'tradeSoftware',
|
||||
|
|
@ -203,9 +211,9 @@ const routes = [
|
|||
component: () => import('@/views/trade/tradeSoftware/index.vue'),
|
||||
meta: {
|
||||
title: '交易软件', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
//公告管理
|
||||
{
|
||||
|
|
@ -230,7 +238,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/deposit/index.vue'),
|
||||
meta: {
|
||||
title: '存款审核', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'withdrawal',
|
||||
|
|
@ -238,7 +246,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/withdrawl/index.vue'),
|
||||
meta: {
|
||||
title: '取款审核', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'withdrawalDetail',
|
||||
|
|
@ -246,7 +254,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/withdrawalDetail/index.vue'),
|
||||
meta: {
|
||||
title: '取款明细', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'depositDetail',
|
||||
|
|
@ -254,7 +262,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/depositDetail/index.vue'),
|
||||
meta: {
|
||||
title: '存款明细', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'transfer',
|
||||
|
|
@ -262,7 +270,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/transfer/index.vue'),
|
||||
meta: {
|
||||
title: '转账', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'transferDetail',
|
||||
|
|
@ -270,7 +278,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/transferDetail/index.vue'),
|
||||
meta: {
|
||||
title: '转账明细', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'capitalFlow',
|
||||
|
|
@ -278,7 +286,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/capitalFlow/index.vue'),
|
||||
meta: {
|
||||
title: '资金流水', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'receiverAccount',
|
||||
|
|
@ -286,7 +294,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/receiverAccount/index.vue'),
|
||||
meta: {
|
||||
title: '收款账户列表', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'depositChannel',
|
||||
|
|
@ -294,7 +302,7 @@ const routes = [
|
|||
component: () => import('@/views/funding/depositChannel/index.vue'),
|
||||
meta: {
|
||||
title: '存款渠道列表', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'fundDetail',
|
||||
|
|
@ -302,9 +310,9 @@ const routes = [
|
|||
component: () => import('@/views/funding/fundDetail/index.vue'),
|
||||
meta: {
|
||||
title: '资金明细', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'risk',
|
||||
|
|
@ -329,7 +337,7 @@ const routes = [
|
|||
component: () => import('@/views/personalized/followRecord/index.vue'),
|
||||
meta: {
|
||||
title: '跟单记录', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
// 带单记录
|
||||
{
|
||||
|
|
@ -338,9 +346,9 @@ const routes = [
|
|||
component: () => import('@/views/personalized/leadRecord/index.vue'),
|
||||
meta: {
|
||||
title: '带单记录', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
//代理管理
|
||||
{
|
||||
|
|
@ -357,7 +365,7 @@ const routes = [
|
|||
component: () => import('@/views/agent/customerList/index.vue'),
|
||||
meta: {
|
||||
title: '客户列表', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
//客户详情
|
||||
{
|
||||
|
|
@ -366,7 +374,7 @@ const routes = [
|
|||
component: () => import('@/views/agent/customerDetail/index.vue'),
|
||||
meta: {
|
||||
title: '客户详情', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
//客户交易订单
|
||||
{
|
||||
|
|
@ -375,7 +383,7 @@ const routes = [
|
|||
component: () => import('@/views/agent/customerTradeOrder/index.vue'),
|
||||
meta: {
|
||||
title: '客户交易订单', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
},
|
||||
//客户资金流水
|
||||
{
|
||||
|
|
@ -384,17 +392,17 @@ const routes = [
|
|||
component: () => import('@/views/agent/customerCapitalFlow/index.vue'),
|
||||
meta: {
|
||||
title: '客户资金流水', // 左侧菜单显示的标题
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
redirect: '/user/login' // 404 重定向到登录页,避免循环
|
||||
}
|
||||
];
|
||||
redirect: '/user/login', // 404 重定向到登录页,避免循环
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<div class="system">
|
||||
<!-- 菜单列表头 -->
|
||||
<MenuHeader :title="menuTitle" :buttons="menuHeaderButtons" @click="handleAddMenu" />
|
||||
<!-- 菜单列表表格 -->
|
||||
<MenuTable :table-data="menuTree" :columns="menuTableColumns" row-key="id">
|
||||
<template #action="{ row }">
|
||||
<el-button link type="primary" size="small" @click="handleEditMenu(row)"> 编辑 </el-button>
|
||||
</template>
|
||||
</MenuTable>
|
||||
</div>
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<MenuDialog
|
||||
:visible="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
:type="dialogType"
|
||||
@confirm="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
@close="handleClose"
|
||||
>
|
||||
<MenuForm
|
||||
:form-data="menuForm"
|
||||
:form-rules="menuFormRules"
|
||||
:form-items="menuFormItemOptions"
|
||||
ref="menuFormRef"
|
||||
/>
|
||||
</MenuDialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
// 组件配置
|
||||
import MenuHeader from '@/components/common/Header.vue'
|
||||
import MenuTable from '@/components/common/Table.vue'
|
||||
import MenuDialog from '@/components/common/Dialog.vue'
|
||||
import MenuForm from '@/components/common/Form.vue'
|
||||
import { menuTableColumns, menuFormItemOptions } from './options'
|
||||
import { rules } from './rules'
|
||||
import { getSettingApi, createSettingApi, editSettingApi } from '@/api/modules/system/setting'
|
||||
|
||||
type SettingItem = {
|
||||
id: number
|
||||
key: string
|
||||
value: string
|
||||
description: string
|
||||
}
|
||||
|
||||
// 定义header配置
|
||||
const menuTitle = ref('系统设置')
|
||||
const menuHeaderButtons = [
|
||||
{ label: '新增设置', type: 'primary' as const, icon: Plus, key: 'addMenu' },
|
||||
]
|
||||
|
||||
// 定义表格配置
|
||||
const menuTree = ref<SettingItem[]>([])
|
||||
|
||||
// 定义弹窗配置
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const dialogType = ref('add')
|
||||
|
||||
// 定义菜单表单数据
|
||||
const menuForm = ref({
|
||||
key: '',
|
||||
value: '',
|
||||
description: '',
|
||||
})
|
||||
const menuFormRef = ref<FormInstance>()
|
||||
// 表单验证规则
|
||||
const menuFormRules = rules()
|
||||
|
||||
/**
|
||||
@description: 新增菜单
|
||||
**/
|
||||
const handleAddMenu = () => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '新增菜单'
|
||||
menuFormItemOptions[0]!.disabled = false
|
||||
}
|
||||
|
||||
/**
|
||||
@description: 菜单数据处理
|
||||
**/
|
||||
|
||||
// 获取菜单列表
|
||||
const fetchSettingList = async () => {
|
||||
try {
|
||||
const data = await getSettingApi()
|
||||
menuTree.value = data
|
||||
} catch (err) {
|
||||
console.error('获取菜单列表失败', err)
|
||||
}
|
||||
}
|
||||
// 页面加载时获取菜单列表
|
||||
onMounted(async () => {
|
||||
await fetchSettingList()
|
||||
})
|
||||
|
||||
/**
|
||||
@description: 处理菜单编辑/删除/状态切换
|
||||
**/
|
||||
const handleEditMenu = (row: SettingItem) => {
|
||||
dialogVisible.value = true
|
||||
menuFormItemOptions[0]!.disabled = true
|
||||
dialogTitle.value = '编辑菜单'
|
||||
dialogType.value = 'edit'
|
||||
menuForm.value = {
|
||||
...row
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@description: 处理弹窗提交/取消/关闭事件
|
||||
**/
|
||||
const handleSubmit = async () => {
|
||||
console.log('提交菜单表单')
|
||||
try {
|
||||
await menuFormRef.value?.validate()
|
||||
if (dialogType.value === 'add') {
|
||||
const params = {
|
||||
key: menuForm.value.key,
|
||||
value: menuForm.value.value,
|
||||
description: menuForm.value.description,
|
||||
}
|
||||
await createSettingApi(params)
|
||||
await fetchSettingList()
|
||||
} else {
|
||||
await editSettingApi(menuForm.value)
|
||||
console.log('编辑菜单成功', menuForm.value)
|
||||
await fetchSettingList()
|
||||
}
|
||||
dialogVisible.value = false
|
||||
} catch (err) {
|
||||
console.log('表单验证失败', err)
|
||||
return
|
||||
}
|
||||
}
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
dialogType.value = 'add'
|
||||
menuForm.value = {
|
||||
key: '',
|
||||
value: '',
|
||||
description: '',
|
||||
}
|
||||
}
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
dialogType.value = 'add'
|
||||
menuForm.value = {
|
||||
key: '',
|
||||
value: '',
|
||||
description: '',
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
//定义table配置
|
||||
export const menuTableColumns = [
|
||||
{ prop: 'key', label: 'key', align: 'center' as const },
|
||||
{ prop: 'value', label: 'value', align: 'center' as const },
|
||||
{ prop: 'description', label: '备注', align: 'center' as const },
|
||||
{ label: '操作', slotName: 'action', align: 'center' as const },
|
||||
]
|
||||
|
||||
//定义menuForm配置
|
||||
export const menuFormItemOptions = [
|
||||
{ prop: 'key', label: 'key', type: 'input' as const, placeholder: '请输入key', disabled: false },
|
||||
{ prop: 'value', label: 'value', type: 'input' as const, placeholder: '请选择value' },
|
||||
{
|
||||
prop: 'description',
|
||||
label: 'description',
|
||||
type: 'input' as const,
|
||||
placeholder: '请选择description',
|
||||
},
|
||||
]
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import type { FormRules } from 'element-plus'
|
||||
|
||||
export const rules = (): FormRules => {
|
||||
return {
|
||||
key: [{ required: true, message: '请选择key', trigger: 'blur' }],
|
||||
value: [{ required: true, message: '请选择value', trigger: 'blur' }],
|
||||
description: [{ required: true, message: '请选择备注', trigger: 'blur' }],
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +1,263 @@
|
|||
<template>
|
||||
<div class="trade-group">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleAdd">添加</el-button>
|
||||
<el-form-item label="交易组时间设置">
|
||||
<el-button type="primary" @click="addTableItem">添加</el-button>
|
||||
</el-form-item>
|
||||
<!-- 表格 -->
|
||||
<TradeGroupTable :table-data="tradeGroupTree" :columns="tradeGroupTableColumnsOptions" row-key="id">
|
||||
<template #tradeTime="{ row }">
|
||||
冬:开仓{{ row.winterStartTime }} - 平仓{{ row.winterEndTime }}<br />
|
||||
<hr>
|
||||
夏:开仓{{ row.summerStartTime }} - 平仓{{ row.summerEndTime }}
|
||||
<div class="table-box">
|
||||
<table>
|
||||
<template v-for="(item, index) in tradeGroupTree" :key="item.id">
|
||||
<tr>
|
||||
<td style="width: 50px">顺序</td>
|
||||
<td style="width: 120px" rowspan="2">
|
||||
<el-input style="width: 100px" v-if="item.editStatus" v-model="item.name" />
|
||||
<span v-else>{{ item.name }}</span>
|
||||
</td>
|
||||
<td style="width: 70px">夏令时</td>
|
||||
<td style="width: 60px">
|
||||
<el-input v-if="item.editStatus" v-model="item.x_m" />
|
||||
<span v-else>{{ item.x_m }}</span>
|
||||
</td>
|
||||
<td style="width: 50px">月</td>
|
||||
<td style="width: 60px">
|
||||
<el-input v-if="item.editStatus" v-model="item.x_w" />
|
||||
<span v-else>{{ item.x_w }}</span>
|
||||
</td>
|
||||
<td style="width: 50px">周</td>
|
||||
<td style="width: 60px">
|
||||
<el-input v-if="item.editStatus" v-model="item.x_d" />
|
||||
<span v-else>{{ item.x_d }}</span>
|
||||
</td>
|
||||
<td style="width: 50px">日</td>
|
||||
<td style="width: 90px">交易时间</td>
|
||||
<td class="time-picker-box">
|
||||
<template v-if="item.editStatus">
|
||||
<template v-if="item?.x_time_list">
|
||||
<el-time-picker
|
||||
v-for="(time, timeIndex) in item?.x_time_list"
|
||||
:key="timeIndex"
|
||||
v-model="item.x_time_list[timeIndex]"
|
||||
style="width: 180px; flex: 0 0 auto"
|
||||
format="HH:mm:ss"
|
||||
value-format="HH:mm:ss"
|
||||
:picker-options="{
|
||||
selectableRange: '09:00:00 - 18:00:00',
|
||||
}"
|
||||
is-range
|
||||
/>
|
||||
</template>
|
||||
<template #status="{ row }">
|
||||
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" />
|
||||
<img
|
||||
src="@/assets/images/trade/group/add.png"
|
||||
@click="addTime(index, 'x_time_list')"
|
||||
/>
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<template v-else>
|
||||
<template v-if="item?.x_time_list">
|
||||
<span v-for="(time, timeIndex) in item?.x_time_list" :key="timeIndex">
|
||||
{{ time[0] }} - {{ time[1] }}
|
||||
</span>
|
||||
</template>
|
||||
</TradeGroupTable>
|
||||
</template>
|
||||
</td>
|
||||
<td rowspan="2" style="width: 140px">
|
||||
<el-button type="primary" v-if="!item.editStatus" @click="item.editStatus = true"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button type="danger" v-if="!item.editStatus" @click="deleteGroup(item.id)"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button type="primary" v-if="item.editStatus" @click="submitItem(index)"
|
||||
>确认</el-button
|
||||
>
|
||||
<el-button type="danger" v-if="item.editStatus" @click="item.editStatus = false"
|
||||
>取消</el-button
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>冬令时</td>
|
||||
<td>
|
||||
<el-input v-if="item.editStatus" v-model="item.d_m" />
|
||||
<span v-else>{{ item.d_m }}</span>
|
||||
</td>
|
||||
<td>月</td>
|
||||
<td>
|
||||
<el-input v-if="item.editStatus" v-model="item.d_w" />
|
||||
<span v-else>{{ item.d_w }}</span>
|
||||
</td>
|
||||
<td>周</td>
|
||||
<td>
|
||||
<el-input v-if="item.editStatus" v-model="item.d_d" />
|
||||
<span v-else>{{ item.d_d }}</span>
|
||||
</td>
|
||||
<td>日</td>
|
||||
<td>交易时间</td>
|
||||
<td class="time-picker-box">
|
||||
<template v-if="item.editStatus">
|
||||
<template v-if="item?.d_time_list">
|
||||
<el-time-picker
|
||||
v-for="(time, timeIndex) in item?.d_time_list"
|
||||
:key="timeIndex"
|
||||
v-model="item.d_time_list[timeIndex]"
|
||||
style="width: 180px; flex: 0 0 auto"
|
||||
format="HH:mm:ss"
|
||||
value-format="HH:mm:ss"
|
||||
:picker-options="{
|
||||
selectableRange: '09:00:00 - 18:00:00',
|
||||
}"
|
||||
is-range
|
||||
/>
|
||||
</template>
|
||||
<img
|
||||
src="@/assets/images/trade/group/add.png"
|
||||
@click="addTime(index, 'd_time_list')"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="item?.d_time_list">
|
||||
<span v-for="(time, timeIndex) in item?.d_time_list" :key="timeIndex">
|
||||
{{ time[0] }} - {{ time[1] }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- dialog -->
|
||||
<TradeGroupDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" @confirm="handleSubmit"
|
||||
@cancel="handleCancel" @close="handleClose">
|
||||
<TradeGroupForm :form-data="tradeGroupForm" :form-rules="tradeGroupFormRules"
|
||||
:form-items="dialogFormItemOptions" :options-map="tradeGroupFormOptionsMap" ref="tradeGroupFormRef">
|
||||
</TradeGroupForm>
|
||||
</TradeGroupDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// 组件
|
||||
import TradeGroupTable from '@/components/common/Table.vue'
|
||||
import TradeGroupDialog from '@/components/common/Dialog.vue'
|
||||
import TradeGroupForm from '@/components/common/Form.vue'
|
||||
// 配置以及表单验证
|
||||
import { search, tableColumns, addFormItem, editFormItem } from './options'
|
||||
import { rules } from './rules'
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
// 接口
|
||||
import { getGroupListApi, addGroupApi, editGroupApi, deleteGroupApi } from '@/api/modules/trade/group'
|
||||
import {
|
||||
getGroupListApi,
|
||||
addGroupApi,
|
||||
editGroupApi,
|
||||
deleteGroupApi,
|
||||
} from '@/api/modules/trade/group'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
/**
|
||||
* @description: 定义表格数据
|
||||
*/
|
||||
const tradeGroupTree = ref([])
|
||||
const tradeGroupTableColumnsOptions = ref(tableColumns)
|
||||
const tradeGroupTree = ref<any[]>([])
|
||||
|
||||
/**
|
||||
* @description: 定义弹窗数据
|
||||
*/
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const dialogType = ref('')
|
||||
const addTableItem = () => {
|
||||
tradeGroupTree.value.unshift({
|
||||
name: '',
|
||||
x_m: '',
|
||||
x_w: '',
|
||||
x_d: '',
|
||||
x_time_list: [[]],
|
||||
d_m: '',
|
||||
d_w: '',
|
||||
d_d: '',
|
||||
d_time_list: [[]],
|
||||
editStatus: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 定义弹窗表格数据
|
||||
*/
|
||||
const tradeGroupForm = ref({
|
||||
// 交易组名称
|
||||
tradeGroupName: '',
|
||||
// 交易所ID
|
||||
exchangeId: '',
|
||||
// 状态
|
||||
status: 1,
|
||||
// 冬季交易时间
|
||||
winterTime: [],
|
||||
// 夏季交易时间
|
||||
summerTime: [],
|
||||
// 排序
|
||||
sort: 0,
|
||||
// 主键ID
|
||||
id: '',
|
||||
})
|
||||
const tradeGroupFormRules = ref(rules())
|
||||
const tradeGroupFormRef = ref()
|
||||
const dialogFormItemOptions = computed(() => dialogType.value === 'add' ? addFormItem : editFormItem)
|
||||
const tradeGroupFormOptionsMap = ref({
|
||||
status: [{ label: '开启', value: 1 }, { label: '关闭', value: 2 }],
|
||||
})
|
||||
const addTime = (idx: number, key: string) => {
|
||||
if (tradeGroupTree.value[idx][key].length >= 4) return ElMessage.warning('最多添加4个时间段')
|
||||
tradeGroupTree.value[idx][key].push([])
|
||||
}
|
||||
|
||||
const submitItem = (idx: number) => {
|
||||
const submitObj = {
|
||||
name: tradeGroupTree.value[idx].name,
|
||||
x_m: tradeGroupTree.value[idx].x_m,
|
||||
x_w: tradeGroupTree.value[idx].x_w,
|
||||
x_d: tradeGroupTree.value[idx].x_d,
|
||||
d_m: tradeGroupTree.value[idx].d_m,
|
||||
d_w: tradeGroupTree.value[idx].d_w,
|
||||
d_d: tradeGroupTree.value[idx].d_d,
|
||||
x_start_time1: tradeGroupTree.value[idx].x_time_list[0]?.[0] || null,
|
||||
x_end_time1: tradeGroupTree.value[idx].x_time_list[0]?.[1] || null,
|
||||
x_start_time2: tradeGroupTree.value[idx].x_time_list[1]?.[0] || null,
|
||||
x_end_time2: tradeGroupTree.value[idx].x_time_list[1]?.[1] || null,
|
||||
x_start_time3: tradeGroupTree.value[idx].x_time_list[2]?.[0] || null,
|
||||
x_end_time3: tradeGroupTree.value[idx].x_time_list[2]?.[1] || null,
|
||||
x_start_time4: tradeGroupTree.value[idx].x_time_list[3]?.[0] || null,
|
||||
x_end_time4: tradeGroupTree.value[idx].x_time_list[3]?.[1] || null,
|
||||
d_start_time1: tradeGroupTree.value[idx].d_time_list[0]?.[0] || null,
|
||||
d_end_time1: tradeGroupTree.value[idx].d_time_list[0]?.[1] || null,
|
||||
d_start_time2: tradeGroupTree.value[idx].d_time_list[1]?.[0] || null,
|
||||
d_end_time2: tradeGroupTree.value[idx].d_time_list[1]?.[1] || null,
|
||||
d_start_time3: tradeGroupTree.value[idx].d_time_list[2]?.[0] || null,
|
||||
d_end_time3: tradeGroupTree.value[idx].d_time_list[2]?.[1] || null,
|
||||
d_start_time4: tradeGroupTree.value[idx].d_time_list[3]?.[0] || null,
|
||||
d_end_time4: tradeGroupTree.value[idx].d_time_list[3]?.[1] || null,
|
||||
}
|
||||
if (tradeGroupTree.value[idx].id) {
|
||||
editGroupApi({
|
||||
...submitObj,
|
||||
id: tradeGroupTree.value[idx].id,
|
||||
sort: tradeGroupTree.value[idx].sort,
|
||||
}).then((res) => {
|
||||
getGroupList()
|
||||
})
|
||||
} else {
|
||||
addGroupApi({ ...submitObj }).then((res) => {
|
||||
getGroupList()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const deleteGroup = (id: number) => {
|
||||
ElMessageBox.confirm('确认删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
}).then(() => {
|
||||
deleteGroupApi({ id }).then(() => {
|
||||
getGroupList()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 定义公共数据处理方法
|
||||
*/
|
||||
/**
|
||||
* @description: 定义公共请求数据方法
|
||||
*/
|
||||
const getGroupList = async () => {
|
||||
try {
|
||||
const data = await getGroupListApi()
|
||||
tradeGroupTree.value = data.map((item: any) => ({
|
||||
id: item.id,
|
||||
tradeGroupName: item.name,
|
||||
status: item.status,
|
||||
// 冬季交易时间
|
||||
winterStartTime: dayjs(item.d_start_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
||||
winterEndTime: dayjs(item.d_end_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
||||
// 夏季交易时间
|
||||
summerStartTime: dayjs(item.x_start_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
||||
summerEndTime: dayjs(item.x_end_time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
||||
// 排序
|
||||
sort: item.sort,
|
||||
}))
|
||||
data.forEach((item: any) => {
|
||||
item.editStatus = false
|
||||
item.x_time_list = []
|
||||
if (item.x_start_time1 && item.x_end_time1) {
|
||||
item.x_time_list.push([item.x_start_time1, item.x_end_time1])
|
||||
}
|
||||
if (item.x_start_time2 && item.x_end_time2) {
|
||||
item.x_time_list.push([item.x_start_time2, item.x_end_time2])
|
||||
}
|
||||
if (item.x_start_time3 && item.x_end_time3) {
|
||||
item.x_time_list.push([item.x_start_time3, item.x_end_time3])
|
||||
}
|
||||
if (item.x_start_time4 && item.x_end_time4) {
|
||||
item.x_time_list.push([item.x_start_time4, item.x_end_time4])
|
||||
}
|
||||
|
||||
item.d_time_list = []
|
||||
if (item.d_start_time1 && item.d_end_time1) {
|
||||
item.d_time_list.push([item.d_start_time1, item.d_end_time1])
|
||||
}
|
||||
if (item.d_start_time2 && item.d_end_time2) {
|
||||
item.d_time_list.push([item.d_start_time2, item.d_end_time2])
|
||||
}
|
||||
if (item.d_start_time3 && item.d_end_time3) {
|
||||
item.d_time_list.push([item.d_start_time3, item.d_end_time3])
|
||||
}
|
||||
if (item.d_start_time4 && item.d_end_time4) {
|
||||
item.d_time_list.push([item.d_start_time4, item.d_end_time4])
|
||||
}
|
||||
})
|
||||
console.log('data', data)
|
||||
tradeGroupTree.value = data
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
ElMessage.error(e.msg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -109,99 +266,63 @@ const getGroupList = async () => {
|
|||
onMounted(() => {
|
||||
getGroupList()
|
||||
})
|
||||
|
||||
const handleAdd = () => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '添加交易组'
|
||||
dialogType.value = 'add'
|
||||
tradeGroupForm.value = {
|
||||
tradeGroupName: '',
|
||||
winterTime: [],
|
||||
summerTime: [],
|
||||
status: 1,
|
||||
sort: 0,
|
||||
id: '',
|
||||
} as any
|
||||
}
|
||||
/**
|
||||
* @description: 定义表格方法
|
||||
*/
|
||||
const handleEdit = (row: any) => {
|
||||
tradeGroupForm.value = {
|
||||
tradeGroupName: row.tradeGroupName,
|
||||
winterTime: [dayjs(row.winterStartTime).format('YYYY-MM-DD HH:mm:ss'), dayjs(row.winterEndTime).format('YYYY-MM-DD HH:mm:ss')],
|
||||
summerTime: [dayjs(row.summerStartTime).format('YYYY-MM-DD HH:mm:ss'), dayjs(row.summerEndTime).format('YYYY-MM-DD HH:mm:ss')],
|
||||
status: row.status,
|
||||
sort: row.sort,
|
||||
id: row.id,
|
||||
} as any
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = '编辑交易组'
|
||||
dialogType.value = 'edit'
|
||||
}
|
||||
|
||||
const handleDelete = async (row: any) => {
|
||||
console.log(row)
|
||||
await deleteGroupApi({ id: row.id })
|
||||
getGroupList()
|
||||
}
|
||||
/**
|
||||
* @description: 定义分页方法
|
||||
*/
|
||||
/**
|
||||
* @description: 定义弹窗方法
|
||||
*/
|
||||
const handleSubmit = async () => {
|
||||
await tradeGroupFormRef.value.validate()
|
||||
if (dialogType.value === 'add') {
|
||||
const params = {
|
||||
name: tradeGroupForm.value.tradeGroupName,
|
||||
x_start_time: tradeGroupForm.value.summerTime[0],
|
||||
x_end_time: tradeGroupForm.value.summerTime[1],
|
||||
d_start_time: tradeGroupForm.value.winterTime[0],
|
||||
d_end_time: tradeGroupForm.value.winterTime[1],
|
||||
}
|
||||
await addGroupApi(params)
|
||||
getGroupList()
|
||||
dialogVisible.value = false
|
||||
} else if (dialogType.value === 'edit') {
|
||||
// 处理编辑逻辑
|
||||
const params = {
|
||||
id: tradeGroupForm.value.id,
|
||||
name: tradeGroupForm.value.tradeGroupName,
|
||||
x_start_time: tradeGroupForm.value.summerTime[0],
|
||||
x_end_time: tradeGroupForm.value.summerTime[1],
|
||||
d_start_time: tradeGroupForm.value.winterTime[0],
|
||||
d_end_time: tradeGroupForm.value.winterTime[1],
|
||||
status: tradeGroupForm.value.status,
|
||||
sort: tradeGroupForm.value.sort,
|
||||
}
|
||||
await editGroupApi(params)
|
||||
getGroupList()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
}
|
||||
const handleCancel = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false
|
||||
}
|
||||
/**
|
||||
* @description: 定义弹窗表格方法
|
||||
*/
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.search-container {
|
||||
:deep(.el-form) {
|
||||
.el-form-item {
|
||||
flex: none;
|
||||
/* 给 table 及所有 td 加边框 */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
table-layout: auto; /* 宽度自适应内容 */
|
||||
|
||||
.el-select {
|
||||
width: 160px;
|
||||
.time-picker-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
td {
|
||||
height: 59px;
|
||||
border: 1px solid #dcdfe6;
|
||||
padding: 4px 8px; /* 内边距缩小 */
|
||||
text-align: center;
|
||||
font-size: 12px; /* 文字变小 */
|
||||
white-space: nowrap; /* 文字不换行 */
|
||||
vertical-align: middle; /* 垂直居中 */
|
||||
|
||||
/* 时间选择器容器:两个选择器横排不换行 */
|
||||
:deep(.el-time-picker) {
|
||||
display: inline-block;
|
||||
|
||||
.el-range-editor {
|
||||
width: 100px; /* 缩小时间选择器宽度 */
|
||||
font-size: 12px;
|
||||
}
|
||||
.el-range-input {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* input 输入框也缩小 */
|
||||
:deep(.el-input) {
|
||||
width: 40px;
|
||||
|
||||
.el-input__inner {
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮缩小 */
|
||||
:deep(.el-button) {
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* @description: 搜索配置
|
||||
*/
|
||||
export const search = [
|
||||
{ label: '交易组名称', prop: 'tradeGroupName', type: 'input' as const, placeholder: '请输入交易组名称' },
|
||||
{ label: '状态', prop: 'status', type: 'select' as const, options: [{ label: '全部', value: '0' }, { label: '开启', value: '1' }, { label: '关闭', value: '2' }] },
|
||||
]
|
||||
|
||||
/**
|
||||
* @description: 表格配置
|
||||
*/
|
||||
export const tableColumns = [
|
||||
{ label: '交易组名称', prop: 'tradeGroupName' },
|
||||
//交易所编号
|
||||
{ label: '交易所编号', prop: 'exchangeId' },
|
||||
// 交易时间
|
||||
{ label: '交易时间', slotName: 'tradeTime' },
|
||||
// 交易状态
|
||||
{ label: '交易状态', slotName: 'status' },
|
||||
// 操作
|
||||
{ label: '操作', slotName: 'action' },
|
||||
]
|
||||
|
||||
/**
|
||||
* @description: dialog form配置
|
||||
*/
|
||||
export const addFormItem = [
|
||||
{ label: '交易组名称', prop: 'tradeGroupName', type: 'input' as const, placeholder: '请输入交易组名称' },
|
||||
// { label: '交易所ID', prop: 'exchangeId', type: 'select' as const, options: [] },
|
||||
// { label: '状态', prop: 'status', type: 'select' as const, options: [{ label: '开启', value: '1' }, { label: '关闭', value: '2' }] },
|
||||
{ label: '冬季交易时间', prop: 'winterTime', type: 'date' as const, dateType: 'datetimerange' as const, placeholder: '请选择冬季交易时间', valueFormat: 'YYYY-MM-DD HH:mm:ss', labelWidth: '110px' },
|
||||
{ label: '夏季交易时间', prop: 'summerTime', type: 'date' as const, dateType: 'datetimerange' as const, placeholder: '请选择夏季交易时间', valueFormat: 'YYYY-MM-DD HH:mm:ss' , labelWidth: '110px' },
|
||||
]
|
||||
export const editFormItem = [
|
||||
{ label: '交易组名称', prop: 'tradeGroupName', type: 'input' as const, placeholder: '请输入交易组名称' },
|
||||
{ label: '冬季交易时间', prop: 'winterTime', type: 'date' as const, dateType: 'datetimerange' as const, placeholder: '请选择冬季交易时间', valueFormat: 'YYYY-MM-DD HH:mm:ss' , labelWidth: '110px'},
|
||||
{ label: '夏季交易时间', prop: 'summerTime', type: 'date' as const, dateType: 'datetimerange' as const, placeholder: '请选择夏季交易时间', valueFormat: 'YYYY-MM-DD HH:mm:ss' , labelWidth: '110px'},
|
||||
{ label: '状态', prop: 'status', type: 'radio' as const},
|
||||
{ label: '排序', prop: 'sort', type: 'number' as const, placeholder: '请输入排序' },
|
||||
]
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import type { FormRules } from 'element-plus'
|
||||
export const rules = (): FormRules => {
|
||||
return {
|
||||
tradeGroupName: [
|
||||
{ required: true, message: '请输入交易组名称', trigger: ['blur'] }
|
||||
],
|
||||
winterTime: [
|
||||
{ required: true, message: '请选择冬季交易时间', trigger: ['change'] }
|
||||
],
|
||||
summerTime: [
|
||||
{ required: true, message: '请选择夏季交易时间', trigger: ['change'] }
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,221 @@
|
|||
<template>
|
||||
<div class="trade-time">
|
||||
交易时间
|
||||
<div class="trade-group">
|
||||
<el-form-item label="交易节假日时间设置">
|
||||
<el-button style="margin-left: 18px" type="primary" @click="handleAdd">添加</el-button>
|
||||
<el-button style="margin-left: 18px" type="danger" @click="handleDel">删除</el-button>
|
||||
</el-form-item>
|
||||
<!-- 表格 -->
|
||||
<div class="table-box">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th>休市时间</th>
|
||||
<th>休市市场</th>
|
||||
<th>备注</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in dataList" :key="`${item.id}-${index}`">
|
||||
<td>
|
||||
<el-input v-model="item.name" style="width: 80px" />
|
||||
</td>
|
||||
<td>
|
||||
<el-date-picker
|
||||
v-model="item.datePicker"
|
||||
type="datetimerange"
|
||||
start-placeholder="休市开始时间"
|
||||
end-placeholder="休市结束时间"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
date-format="YYYY-MM-DD HH:mm:ss"
|
||||
time-format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<el-select
|
||||
multiple
|
||||
placeholder="请选择休市市场"
|
||||
style="width: 240px"
|
||||
v-model="item.groupId"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in marketList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
<td><el-input style="width: 250px" v-model="item.description" /></td>
|
||||
<td>
|
||||
<el-button type="primary" v-if="!item.editStatus" @click="item.editStatus = true">编辑</el-button>
|
||||
<el-button type="danger" v-if="!item.editStatus" @click="handleDel(item.id)">删除</el-button>
|
||||
<el-button type="primary" v-if="item.editStatus" @click="submitItem(index)">确认</el-button>
|
||||
<el-button type="danger" v-if="item.editStatus" @click="item.editStatus = false">取消</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getGroupListApi } from '@/api/modules/trade/group'
|
||||
import { getHolidayList, addHoliday, editHoliday, delHoliday } from '@/api/modules/trade/time'
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
|
||||
type DataItem = {
|
||||
id?: number | string
|
||||
name: string
|
||||
start_time?: string
|
||||
end_time?: string
|
||||
datePicker: string[]
|
||||
groupId: number[]
|
||||
description: string
|
||||
editStatus: boolean
|
||||
}
|
||||
|
||||
const dataList = ref<DataItem[]>([])
|
||||
|
||||
const marketList = ref<{ label: string; value: number | string }[]>([])
|
||||
|
||||
const getMarketList = async () => {
|
||||
getGroupListApi().then((res) => {
|
||||
console.log(res)
|
||||
marketList.value = res.map((item: { name: string; id: number }[]) => ({
|
||||
label: item.name,
|
||||
value: item.id + '',
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
const initDate = () => {
|
||||
getHolidayList().then((res) => {
|
||||
dataList.value = res.map((item: any) => ({
|
||||
id: item.id + '',
|
||||
name: item.name,
|
||||
start_time: item.start_time,
|
||||
end_time: item.end_time,
|
||||
datePicker: [item.start_time, item.end_time],
|
||||
groupId: item.group_id,
|
||||
description: item.description,
|
||||
editStatus: false,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dataList.value.unshift({
|
||||
name: '',
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
datePicker: [],
|
||||
groupId: [],
|
||||
description: '',
|
||||
editStatus: true,
|
||||
})
|
||||
}
|
||||
|
||||
const submitItem = (idx: number) => {
|
||||
const submitObj = {
|
||||
name: dataList.value[idx]!.name,
|
||||
start_time: dataList.value[idx]!.datePicker[0],
|
||||
end_time: dataList.value[idx]!.datePicker[1],
|
||||
group_id: dataList.value[idx]!.groupId.join(','),
|
||||
description: dataList.value[idx]!.description,
|
||||
}
|
||||
if (dataList.value[idx]!.id) {
|
||||
editHoliday({id: dataList.value[idx]!.id, ...submitObj}).then(() => {
|
||||
initDate()
|
||||
})
|
||||
} else {
|
||||
addHoliday(submitObj).then(() => {
|
||||
initDate()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleDel = (id: number | string) => {
|
||||
ElMessageBox.confirm('确认删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
}).then(() => {
|
||||
delHoliday({id}).then(() => {
|
||||
initDate()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 页面加载完成需要请求的数据
|
||||
*/
|
||||
onMounted(() => {
|
||||
getMarketList()
|
||||
initDate()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 给 table 及所有 td 加边框 */
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
table-layout: auto;
|
||||
|
||||
/* 宽度自适应内容 */
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
height: 48px;
|
||||
border: 1px solid #dcdfe6;
|
||||
padding: 4px 8px;
|
||||
/* 内边距缩小 */
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
/* 文字变小 */
|
||||
white-space: nowrap;
|
||||
/* 文字不换行 */
|
||||
vertical-align: middle;
|
||||
/* 垂直居中 */
|
||||
|
||||
/* 时间选择器容器:两个选择器横排不换行 */
|
||||
:deep(.el-time-picker) {
|
||||
display: inline-block;
|
||||
|
||||
.el-range-editor {
|
||||
width: 100px;
|
||||
/* 缩小时间选择器宽度 */
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-range-input {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* input 输入框也缩小 */
|
||||
:deep(.el-input) {
|
||||
width: 60px;
|
||||
|
||||
.el-input__inner {
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮缩小 */
|
||||
:deep(.el-button) {
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ export const tableColumns = [
|
|||
{ prop: 'minFlux', label: '最小波动', align: 'center' as const },
|
||||
// 单位
|
||||
{ prop: 'unit', label: '单位', align: 'center' as const },
|
||||
// 所属交易组
|
||||
{ prop: 'tradeGroup', label: '所属交易组', align: 'center' as const },
|
||||
// 交易时间
|
||||
{ prop: 'tradeGroup', label: '交易时间', align: 'center' as const },
|
||||
// 多头库存费
|
||||
{ prop: 'longStockFee', label: '多头库存费', align: 'center' as const },
|
||||
// 空头库存费
|
||||
|
|
@ -50,26 +50,61 @@ export const editDialogFormItem = [
|
|||
{ prop: 'varietyName', label: '名称', type: 'input' as const, placeholder: '请输入名称' },
|
||||
// 编号
|
||||
{ prop: 'varietyCode', label: '编号', type: 'input' as const, placeholder: '请输入编号' },
|
||||
// 所属交易组
|
||||
{ prop: 'tradeGroup', label: '所属交易组', type: 'select' as const, placeholder: '请输入所属交易组' },
|
||||
// 交易时间
|
||||
{
|
||||
prop: 'tradeGroup',
|
||||
label: '交易时间',
|
||||
type: 'select' as const,
|
||||
placeholder: '请选择交易时间',
|
||||
},
|
||||
// 最大点差
|
||||
{ prop: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' },
|
||||
// 最小点差
|
||||
{ prop: 'minPoint', label: '最小点差', type: 'input' as const, placeholder: '请输入最小点差' },
|
||||
// 合约大小
|
||||
{ prop: 'contractSize', label: '合约大小', type: 'input' as const, placeholder: '请输入合约大小' },
|
||||
{
|
||||
prop: 'contractSize',
|
||||
label: '合约大小',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入合约大小',
|
||||
},
|
||||
// 多头库存费
|
||||
{ prop: 'longStockFee', label: '多头库存费', type: 'input' as const, placeholder: '请输入多头库存费' },
|
||||
{
|
||||
prop: 'longStockFee',
|
||||
label: '多头库存费',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入多头库存费',
|
||||
},
|
||||
// 空头库存费
|
||||
{ prop: 'shortStockFee', label: '空头库存费', type: 'input' as const, placeholder: '请输入空头库存费' },
|
||||
{
|
||||
prop: 'shortStockFee',
|
||||
label: '空头库存费',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入空头库存费',
|
||||
},
|
||||
// 预付款对冲
|
||||
{ prop: 'prepaymentHedge', label: '预付款对冲', type: 'input' as const, placeholder: '请输入预付款对冲' },
|
||||
{
|
||||
prop: 'prepaymentHedge',
|
||||
label: '预付款对冲',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入预付款对冲',
|
||||
},
|
||||
// 预付款百分比
|
||||
{ prop: 'prepaymentPercent', label: '预付款百分比', type: 'input' as const, placeholder: '请输入预付款百分比' },
|
||||
{
|
||||
prop: 'prepaymentPercent',
|
||||
label: '预付款百分比',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入预付款百分比',
|
||||
},
|
||||
// 小数位
|
||||
{ prop: 'decimalPlaces', label: '小数位', type: 'input' as const, placeholder: '请输入小数位' },
|
||||
// 点差小数位
|
||||
{ prop: 'pointDecimalPlaces', label: '点差小数位', type: 'input' as const, placeholder: '请输入点差小数位' },
|
||||
{
|
||||
prop: 'pointDecimalPlaces',
|
||||
label: '点差小数位',
|
||||
type: 'input' as const,
|
||||
placeholder: '请输入点差小数位',
|
||||
},
|
||||
// 止盈水平
|
||||
{ prop: 'profitLevel', label: '止盈水平', type: 'input' as const, placeholder: '请输入止盈水平' },
|
||||
// 单位
|
||||
|
|
@ -79,10 +114,9 @@ export const editDialogFormItem = [
|
|||
// 类型
|
||||
{ prop: 'type', label: '类型', type: 'select' as const, placeholder: '请选择类型' },
|
||||
// 上传图片地址
|
||||
{ prop: 'imageUrl', slotName: 'upload', label: '上传图片' ,type: 'upload' as const},
|
||||
{ prop: 'imageUrl', slotName: 'upload', label: '上传图片', type: 'upload' as const },
|
||||
// 上下线状态
|
||||
{ prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const},
|
||||
{ prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const },
|
||||
// 交易状态
|
||||
{ prop: 'tradeStatus', label: '交易状态', type: 'switch' as const},
|
||||
|
||||
{ prop: 'tradeStatus', label: '交易状态', type: 'switch' as const },
|
||||
]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vite'
|
||||
import { loadEnv, defineConfig, ConfigEnv, ViteConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
|
|
@ -11,40 +11,23 @@ import Components from 'unplugin-vue-components/vite'
|
|||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
export default defineConfig(({ mode }: ConfigEnv): ViteConfig => {
|
||||
const isProduction = mode === 'production'
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
return {
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
//自动导入Vue/路由/Pinia等API(无需手动import)
|
||||
// 生产环境移除 devTools 插件(减少产物体积)
|
||||
...(!isProduction ? [vueDevTools()] : []),
|
||||
AutoImport({
|
||||
// 适配Element Plus的自动导入
|
||||
resolvers: [
|
||||
ElementPlusResolver(),
|
||||
],
|
||||
// 指定要自动导入的库
|
||||
imports: [
|
||||
'vue', // 自动导入ref、reactive、watch等Vue API
|
||||
'vue-router', // 自动导入useRoute、useRouter等路由API
|
||||
'pinia', // 自动导入defineStore等Pinia API
|
||||
'@vueuse/core', // 自动导入@vueuse的hooks
|
||||
],
|
||||
// 生成类型声明文件(TypeScript必备,解决类型提示问题)
|
||||
resolvers: [ElementPlusResolver()],
|
||||
imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
|
||||
dts: 'src/auto-imports.d.ts',
|
||||
// 自动生成eslint配置(解决eslint报"未定义变量"的问题)
|
||||
eslintrc: {
|
||||
enabled: true, // 开启后会生成 .eslintrc-auto-import.json
|
||||
},
|
||||
eslintrc: { enabled: true },
|
||||
}),
|
||||
// 2. 自动导入组件(包括Element Plus和本地组件)
|
||||
Components({
|
||||
// 自动解析Element Plus组件
|
||||
resolvers: [
|
||||
ElementPlusResolver(),
|
||||
],
|
||||
// 生成组件类型声明文件
|
||||
resolvers: [ElementPlusResolver()],
|
||||
dts: 'src/components.d.ts',
|
||||
// 指定要自动导入的本地组件目录(src/components下的组件无需手动注册)
|
||||
dirs: ['src/components'],
|
||||
}),
|
||||
],
|
||||
|
|
@ -54,30 +37,60 @@ export default defineConfig(({ mode }) => {
|
|||
},
|
||||
},
|
||||
|
||||
// 构建配置
|
||||
// ====== 增强版生产构建配置 ======
|
||||
build: {
|
||||
// 输出目录
|
||||
outDir: 'dist',
|
||||
// 静态资源目录
|
||||
assetsDir: 'assets',
|
||||
// 生产环境移除console和debugger
|
||||
|
||||
// 生产环境 sourcemap 配置(可选:隐藏源码但保留行映射)
|
||||
sourcemap: isProduction ? 'hidden' : true,
|
||||
|
||||
// chunk 分割策略(优化加载性能)
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
// 将第三方库单独分包
|
||||
'element-plus': ['element-plus', '@element-plus/icons-vue'],
|
||||
vendor: ['vue', 'vue-router', 'pinia'],
|
||||
utils: ['axios', 'dayjs', 'crypto-js', '@vueuse/core'],
|
||||
},
|
||||
// 文件名带 hash(缓存优化)
|
||||
chunkFileNames: 'assets/js/[name]-[hash].js',
|
||||
entryFileNames: 'assets/js/[name]-[hash].js',
|
||||
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
|
||||
},
|
||||
},
|
||||
|
||||
// 压缩配置
|
||||
minify: 'esbuild',
|
||||
esbuild: {
|
||||
drop: mode === 'production' ? ['console', 'debugger'] : [],
|
||||
// 剔除 JS 中的所有注释(包括注释掉的代码)
|
||||
minifyIdentifiers: true, // 压缩变量名
|
||||
minifySyntax: true, // 压缩语法(含剔除普通注释)
|
||||
minifyWhitespace: true, // 剔除空格
|
||||
drop: isProduction ? ['console', 'debugger'] : [],
|
||||
minifyIdentifiers: true,
|
||||
minifySyntax: true,
|
||||
minifyWhitespace: true,
|
||||
},
|
||||
// 可选:进一步压缩打包产物
|
||||
// terserOptions: mode === 'production' ? {
|
||||
// format: {
|
||||
// comments: false, // 彻底剔除所有注释
|
||||
// },
|
||||
// } : {},
|
||||
|
||||
// 大文件警告阈值(默认500KB,可调整)
|
||||
chunkSizeWarningLimit: 1000,
|
||||
},
|
||||
|
||||
// 生产环境不显示错误遮罩
|
||||
define: {
|
||||
__VUE_PROD_DEVTOOLS__: 'false',
|
||||
},
|
||||
|
||||
server: {
|
||||
host: true,
|
||||
port: 9999,
|
||||
https: false,
|
||||
open: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: env.VITE_API_BASE_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue