diff --git a/.env.development b/.env.development index 0b4293a..15baf53 100644 --- a/.env.development +++ b/.env.development @@ -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 # 请求超时时间(毫秒) diff --git a/.env.production b/.env.production index a7e34c6..be8666d 100644 --- a/.env.production +++ b/.env.production @@ -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 diff --git a/.gitignore b/.gitignore index 4c565fe..eaf18b1 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,8 @@ coverage .eslintcache +package-lock.json + # Cypress /cypress/videos/ /cypress/screenshots/ diff --git a/package.json b/package.json index f9379ec..270f50c 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/api/index.ts b/src/api/index.ts index 4db0a07..7355a6d 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -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 | 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 = (response: AxiosResponse 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 = (response: AxiosResponse } 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 = (response: AxiosResponse message: data.msg || '未知的错误!', type: 'error', duration: 2000, - customClass: 'global-notification' + customClass: 'global-notification', }) return Promise.reject(data) } diff --git a/src/api/modules/system/setting.ts b/src/api/modules/system/setting.ts new file mode 100644 index 0000000..18ddc2e --- /dev/null +++ b/src/api/modules/system/setting.ts @@ -0,0 +1,38 @@ +import { request } from '@/api'; + +type SettingFormParams = { + key: string + value: string + description: string +} + +type SettingListResponse = SettingFormParams & { + id: number +} + +/** + * 获取设置列表 + * @returns Promise 设置列表数据 + */ +export async function getSettingApi(): Promise { + return request.get('/setting/getList') +} + +/** + * 添加设置 + * @param params + * @returns Promise + */ +export async function createSettingApi(params: SettingFormParams): Promise { + return request.post('/setting/add', params) +} + +/** + * 编辑设置 + * @param params 菜单表单参数(含id) + * @returns Promise + */ +export async function editSettingApi(params: SettingFormParams): Promise { + return request.post('/setting/edit', params) +} + diff --git a/src/api/modules/trade/group.ts b/src/api/modules/trade/group.ts index 31734b1..1258d12 100644 --- a/src/api/modules/trade/group.ts +++ b/src/api/modules/trade/group.ts @@ -7,15 +7,15 @@ export async function getGroupListApi(): Promise { // 创建交易组 export async function addGroupApi(params: any): Promise { - return request.post('/contractVariety/createGroup', {...params}) + return request.post('/contractVariety/createGroup', { ...params }) } //编辑交易组 export async function editGroupApi(params: any): Promise { - return request.post('/contractVariety/editGroup', {...params}) + return request.post('/contractVariety/editGroup', { ...params }) } // 删除交易组 export async function deleteGroupApi(params: any): Promise { - return request.post('/contractVariety/delGroup', {...params}) -} \ No newline at end of file + return request.post('/contractVariety/delGroup', { ...params }) +} diff --git a/src/api/modules/trade/time.ts b/src/api/modules/trade/time.ts new file mode 100644 index 0000000..60bd72d --- /dev/null +++ b/src/api/modules/trade/time.ts @@ -0,0 +1,21 @@ +import { request } from '@/api'; + +// 获取节假日列表 +export async function getHolidayList(): Promise { + return request.get('/contractVariety/getHolidayList') +} + +// 添加节假日 +export async function addHoliday(params: any): Promise { + return request.post('/contractVariety/addHoliday', { ...params }) +} + +//编辑节假日 +export async function editHoliday(params: any): Promise { + return request.post('/contractVariety/editHoliday', { ...params }) +} + +// 删除节假日 +export async function delHoliday(params: any): Promise { + return request.post('/contractVariety/delHoliday', { ...params }) +} diff --git a/src/assets/images/trade/group/add.png b/src/assets/images/trade/group/add.png new file mode 100644 index 0000000..d9f91c9 Binary files /dev/null and b/src/assets/images/trade/group/add.png differ diff --git a/src/components/layout/Sidebar.vue b/src/components/layout/Sidebar.vue index f3cc575..6106b2a 100644 --- a/src/components/layout/Sidebar.vue +++ b/src/components/layout/Sidebar.vue @@ -1,11 +1,11 @@ - - + + + + + + + + + + + + diff --git a/src/router/index.ts b/src/router/index.ts index 7bb3dbb..0e1edcf 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -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(), @@ -429,4 +437,4 @@ router.afterEach((to) => { } }); -export default router; \ No newline at end of file +export default router; diff --git a/src/views/system/setting/index.vue b/src/views/system/setting/index.vue new file mode 100644 index 0000000..2220b28 --- /dev/null +++ b/src/views/system/setting/index.vue @@ -0,0 +1,156 @@ + + diff --git a/src/views/system/setting/options.ts b/src/views/system/setting/options.ts new file mode 100644 index 0000000..db2aa6c --- /dev/null +++ b/src/views/system/setting/options.ts @@ -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', + }, +] diff --git a/src/views/system/setting/rules.ts b/src/views/system/setting/rules.ts new file mode 100644 index 0000000..6ea979a --- /dev/null +++ b/src/views/system/setting/rules.ts @@ -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' }], + } +} diff --git a/src/views/trade/group/index.vue b/src/views/trade/group/index.vue index 2dec88a..06d278c 100644 --- a/src/views/trade/group/index.vue +++ b/src/views/trade/group/index.vue @@ -1,207 +1,328 @@ diff --git a/src/views/trade/group/options.ts b/src/views/trade/group/options.ts deleted file mode 100644 index c51c064..0000000 --- a/src/views/trade/group/options.ts +++ /dev/null @@ -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: '请输入排序' }, -] \ No newline at end of file diff --git a/src/views/trade/group/rules.ts b/src/views/trade/group/rules.ts deleted file mode 100644 index d97152b..0000000 --- a/src/views/trade/group/rules.ts +++ /dev/null @@ -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'] } - ], - } -} \ No newline at end of file diff --git a/src/views/trade/time/index.vue b/src/views/trade/time/index.vue index 4601a2e..aa2b10a 100644 --- a/src/views/trade/time/index.vue +++ b/src/views/trade/time/index.vue @@ -1,5 +1,221 @@ + + + + diff --git a/src/views/trade/variety/options.ts b/src/views/trade/variety/options.ts index 035e42b..9d75b76 100644 --- a/src/views/trade/variety/options.ts +++ b/src/views/trade/variety/options.ts @@ -10,79 +10,113 @@ export const search = [ * @description: 表格配置 */ export const tableColumns = [ - // id - { prop: 'id', label: 'ID', align: 'center' as const }, - // 名称 - { prop: 'varietyName', label: '名称', align: 'center' as const }, - // 编号 - { prop: 'varietyCode', label: '编号', align: 'center' as const }, - //上下线状态 - { slotName: 'onlineStatus', label: '上下线状态', align: 'center' as const }, - // 交易状态 - { slotName: 'tradeStatus', label: '交易状态', align: 'center' as const }, - // 最小点差 - { prop: 'minPoint', label: '最小点差', align: 'center' as const }, - // 最大点差 - { prop: 'maxPoint', label: '最大点差', align: 'center' as const }, - // 合约大小 - { prop: 'contractSize', label: '合约大小', align: 'center' as const }, - // 最小波动 - { prop: 'minFlux', label: '最小波动', align: 'center' as const }, - // 单位 - { prop: 'unit', label: '单位', align: 'center' as const }, - // 所属交易组 - { prop: 'tradeGroup', label: '所属交易组', align: 'center' as const }, - // 多头库存费 - { prop: 'longStockFee', label: '多头库存费', align: 'center' as const }, - // 空头库存费 - { prop: 'shortStockFee', label: '空头库存费', align: 'center' as const }, - // 类型 - { prop: 'type', label: '类型', align: 'center' as const }, - // 止盈水平 - { prop: 'profitLevel', label: '止盈水平', align: 'center' as const }, + // id + { prop: 'id', label: 'ID', align: 'center' as const }, + // 名称 + { prop: 'varietyName', label: '名称', align: 'center' as const }, + // 编号 + { prop: 'varietyCode', label: '编号', align: 'center' as const }, + //上下线状态 + { slotName: 'onlineStatus', label: '上下线状态', align: 'center' as const }, + // 交易状态 + { slotName: 'tradeStatus', label: '交易状态', align: 'center' as const }, + // 最小点差 + { prop: 'minPoint', label: '最小点差', align: 'center' as const }, + // 最大点差 + { prop: 'maxPoint', label: '最大点差', align: 'center' as const }, + // 合约大小 + { prop: 'contractSize', label: '合约大小', align: 'center' as const }, + // 最小波动 + { prop: 'minFlux', label: '最小波动', align: 'center' as const }, + // 单位 + { prop: 'unit', label: '单位', align: 'center' as const }, + // 交易时间 + { prop: 'tradeGroup', label: '交易时间', align: 'center' as const }, + // 多头库存费 + { prop: 'longStockFee', label: '多头库存费', align: 'center' as const }, + // 空头库存费 + { prop: 'shortStockFee', label: '空头库存费', align: 'center' as const }, + // 类型 + { prop: 'type', label: '类型', align: 'center' as const }, + // 止盈水平 + { prop: 'profitLevel', label: '止盈水平', align: 'center' as const }, ] /** * @description: dialog表单配置 */ 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: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' }, - // 最小点差 - { prop: 'minPoint', label: '最小点差', type: 'input' as const, placeholder: '请输入最小点差' }, - // 合约大小 - { prop: 'contractSize', label: '合约大小', type: 'input' as const, placeholder: '请输入合约大小' }, - // 多头库存费 - { prop: 'longStockFee', label: '多头库存费', type: 'input' as const, placeholder: '请输入多头库存费' }, - // 空头库存费 - { prop: 'shortStockFee', label: '空头库存费', type: 'input' as const, placeholder: '请输入空头库存费' }, - // 预付款对冲 - { prop: 'prepaymentHedge', 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: 'profitLevel', label: '止盈水平', type: 'input' as const, placeholder: '请输入止盈水平' }, - // 单位 - { prop: 'unit', label: '单位', type: 'input' as const, placeholder: '请输入单位' }, - // 最小波动 - { prop: 'minFlux', label: '最小波动', type: 'input' as const, placeholder: '请输入最小波动' }, - // 类型 - { prop: 'type', label: '类型', type: 'select' as const, placeholder: '请选择类型' }, - // 上传图片地址 - { prop: 'imageUrl', slotName: 'upload', label: '上传图片' ,type: 'upload' as const}, - // 上下线状态 - { prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const}, - // 交易状态 - { prop: 'tradeStatus', label: '交易状态', type: 'switch' as const}, - -] \ No newline at end of file + // 名称 + { 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: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' }, + // 最小点差 + { prop: 'minPoint', label: '最小点差', type: 'input' as const, placeholder: '请输入最小点差' }, + // 合约大小 + { + prop: 'contractSize', + label: '合约大小', + type: 'input' as const, + placeholder: '请输入合约大小', + }, + // 多头库存费 + { + prop: 'longStockFee', + label: '多头库存费', + type: 'input' as const, + placeholder: '请输入多头库存费', + }, + // 空头库存费 + { + prop: 'shortStockFee', + label: '空头库存费', + type: 'input' as const, + placeholder: '请输入空头库存费', + }, + // 预付款对冲 + { + prop: 'prepaymentHedge', + 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: 'profitLevel', label: '止盈水平', type: 'input' as const, placeholder: '请输入止盈水平' }, + // 单位 + { prop: 'unit', label: '单位', type: 'input' as const, placeholder: '请输入单位' }, + // 最小波动 + { prop: 'minFlux', label: '最小波动', type: 'input' as const, placeholder: '请输入最小波动' }, + // 类型 + { prop: 'type', label: '类型', type: 'select' as const, placeholder: '请选择类型' }, + // 上传图片地址 + { prop: 'imageUrl', slotName: 'upload', label: '上传图片', type: 'upload' as const }, + // 上下线状态 + { prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const }, + // 交易状态 + { prop: 'tradeStatus', label: '交易状态', type: 'switch' as const }, +] diff --git a/vite.config.ts b/vite.config.ts index 4673c7b..e8c97d2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -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/, ''), + }, + }, }, } })