This commit is contained in:
parent
59fd39341b
commit
bb9134f78d
|
|
@ -4,6 +4,10 @@ import { request } from '@/api';
|
||||||
export async function getVarietyListApi(params: any): Promise<any> {
|
export async function getVarietyListApi(params: any): Promise<any> {
|
||||||
return request.get<any>('/contractVariety/getList', {...params})
|
return request.get<any>('/contractVariety/getList', {...params})
|
||||||
}
|
}
|
||||||
|
//获取交易组列表
|
||||||
|
export async function getTradeGroupListApi(): Promise<any> {
|
||||||
|
return request.get<any>('/contractVariety/getGroupList')
|
||||||
|
}
|
||||||
|
|
||||||
//创建合约品种
|
//创建合约品种
|
||||||
export async function createVarietyApi(params: any): Promise<any> {
|
export async function createVarietyApi(params: any): Promise<any> {
|
||||||
|
|
@ -11,6 +15,6 @@ export async function createVarietyApi(params: any): Promise<any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//编辑合约品种
|
//编辑合约品种
|
||||||
export async function updateVarietyApi(params: any): Promise<any> {
|
export async function editVarietyApi(params: any): Promise<any> {
|
||||||
return request.post<any>('/contractVariety/editVariety', {...params})
|
return request.post<any>('/contractVariety/editVariety', {...params})
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog :model-value="visible" :title="title" :width="width" :destroy-on-close="destroyOnClose"
|
<el-dialog :model-value="visible" :title="title" :width="width" :destroy-on-close="destroyOnClose"
|
||||||
|
:fullscreen="fullscreen"
|
||||||
@close="handleClose" v-bind="$attrs">
|
@close="handleClose" v-bind="$attrs">
|
||||||
<!-- 对话框内容插槽 -->
|
<!-- 对话框内容插槽 -->
|
||||||
<slot />
|
<slot />
|
||||||
|
|
@ -22,6 +23,7 @@ interface Props {
|
||||||
destroyOnClose?: boolean
|
destroyOnClose?: boolean
|
||||||
type?: string
|
type?: string
|
||||||
showFooter?: boolean
|
showFooter?: boolean
|
||||||
|
fullscreen?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
|
|
@ -32,9 +34,10 @@ interface Emits {
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
width: '600px',
|
width: '750px',
|
||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
showFooter: true,
|
showFooter: true,
|
||||||
|
fullscreen: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<Emits>()
|
const emit = defineEmits<Emits>()
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,60 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-bind="$attrs">
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-bind="$attrs">
|
||||||
<!-- 动态表单项 -->
|
<!-- 动态表单项 -->
|
||||||
<template v-for="(item, index) in formItems" :key="index">
|
<el-row :gutter="props.rowGutter || 0">
|
||||||
<el-form-item :label="item.label" :prop="item.prop" :required="item.required" label-position="left" :label-width="item.labelWidth || '100px'" :class="item.class">
|
<template v-for="(item, index) in formItems" :key="index">
|
||||||
<!-- 输入框 -->
|
<el-col :span="props.colSpan || 24">
|
||||||
<el-input v-if="item.type === 'input'" v-model="formData[item.prop]" :placeholder="item.placeholder"
|
<el-form-item :label="item.label" :prop="item.prop" :required="item.required" label-position="left"
|
||||||
:disabled="item.disabled" clearable />
|
:label-width="item.labelWidth || '100px'" :class="item.class">
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<el-input v-if="item.type === 'input'" v-model="formData[item.prop]"
|
||||||
|
:placeholder="item.placeholder" :disabled="item.disabled" clearable />
|
||||||
|
|
||||||
<!-- 下拉选择框 -->
|
<!-- 下拉选择框 -->
|
||||||
<el-select v-else-if="item.type === 'select'" v-model="formData[item.prop]"
|
<el-select v-else-if="item.type === 'select'" v-model="formData[item.prop]"
|
||||||
:placeholder="item.placeholder" :disabled="item.disabled" clearable style="width: 100%" @change="handleItemChange(item.prop, formData[item.prop])">
|
:placeholder="item.placeholder" :disabled="item.disabled" clearable style="width: 100%"
|
||||||
<el-option v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
@change="handleItemChange(item.prop, formData[item.prop])">
|
||||||
:label="option.label" :value="option.value">
|
<el-option v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
||||||
<template v-if="option.icon" #label>
|
:label="option.label" :value="option.value">
|
||||||
<span style="display: flex; align-items: center; gap: 8px;">
|
<template v-if="option.icon" #label>
|
||||||
<el-icon v-if="option.icon">
|
<span style="display: flex; align-items: center; gap: 8px;">
|
||||||
<component :is="option.icon" />
|
<el-icon v-if="option.icon">
|
||||||
</el-icon>
|
<component :is="option.icon" />
|
||||||
<span>{{ option.label }}</span>
|
</el-icon>
|
||||||
</span>
|
<span>{{ option.label }}</span>
|
||||||
</template>
|
</span>
|
||||||
</el-option>
|
</template>
|
||||||
</el-select>
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
<!-- 数字输入框 -->
|
<!-- 数字输入框 -->
|
||||||
<el-input-number v-else-if="item.type === 'number'" v-model="formData[item.prop]" :min="item.min"
|
<el-input-number v-else-if="item.type === 'number'" v-model="formData[item.prop]"
|
||||||
:max="item.max" :placeholder="item.placeholder" :disabled="item.disabled" style="width: 100%" />
|
:min="item.min" :max="item.max" :placeholder="item.placeholder" :disabled="item.disabled"
|
||||||
|
style="width: 100%" />
|
||||||
|
|
||||||
<!-- 单选框组 -->
|
<!-- 单选框组 -->
|
||||||
<el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.prop]">
|
<el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.prop]">
|
||||||
<el-radio v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
<el-radio v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
||||||
:value="option.value">
|
:value="option.value">
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
|
||||||
<!-- 复选框组 -->
|
<!-- 复选框组 -->
|
||||||
<el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.prop]">
|
<el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.prop]">
|
||||||
<el-checkbox v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
<el-checkbox v-for="option in props.optionsMap?.[item.prop] || []" :key="option.value"
|
||||||
:value="option.value">
|
:value="option.value">
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
<el-switch v-else-if="item.type === 'switch'" v-model="formData[item.prop]" />
|
<el-switch v-else-if="item.type === 'switch'" v-model="formData[item.prop]" :active-value="1"
|
||||||
<!-- 自定义插槽 -->
|
:inactive-value="2" />
|
||||||
<slot v-else :name="item.slotName" :formData="formData" />
|
<!-- 自定义插槽 -->
|
||||||
</el-form-item>
|
<slot v-else :name="item.slotName" :formData="formData" />
|
||||||
</template>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -67,6 +75,7 @@ interface FormItem {
|
||||||
labelPosition?: 'left' | 'right'
|
labelPosition?: 'left' | 'right'
|
||||||
labelWidth?: string
|
labelWidth?: string
|
||||||
class?: string
|
class?: string
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
@ -78,6 +87,8 @@ interface Props {
|
||||||
value: string | number
|
value: string | number
|
||||||
icon?: Component
|
icon?: Component
|
||||||
}>>
|
}>>
|
||||||
|
rowGutter?: number // 新增:全局栅格间距(默认0)
|
||||||
|
colSpan?: number // 新增:全局表单项列宽(默认24)
|
||||||
}
|
}
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
@ -85,7 +96,7 @@ const props = defineProps<Props>()
|
||||||
const emit = defineEmits(['form-item-change'])
|
const emit = defineEmits(['form-item-change'])
|
||||||
|
|
||||||
const handleItemChange = (field: string, value: any) => {
|
const handleItemChange = (field: string, value: any) => {
|
||||||
emit('form-item-change', field, value)
|
emit('form-item-change', field, value)
|
||||||
}
|
}
|
||||||
// 暴露表单验证方法
|
// 暴露表单验证方法
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
||||||
|
|
@ -24,24 +24,7 @@
|
||||||
:start-placeholder="item.startPlaceholder || '开始日期'"
|
:start-placeholder="item.startPlaceholder || '开始日期'"
|
||||||
:end-placeholder="item.endPlaceholder || '结束日期'"
|
:end-placeholder="item.endPlaceholder || '结束日期'"
|
||||||
:value-format="item.valueFormat || 'YYYY-MM-DD'" :clearable="item.clearable ?? true"
|
:value-format="item.valueFormat || 'YYYY-MM-DD'" :clearable="item.clearable ?? true"
|
||||||
:disabled-date="item.disabledDate" :locale="'zhCn'"
|
:disabled-date="item.disabledDate" :locale="'zhCn'" />
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 单选框组 -->
|
|
||||||
<el-radio-group v-else-if="item.type === 'radio'" v-model="searchForm[item.prop]"
|
|
||||||
:disabled="item.disabled">
|
|
||||||
<el-radio v-for="option in item.options" :key="option.value" :label="option.value">
|
|
||||||
{{ option.label }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
|
|
||||||
<!-- 复选框组 -->
|
|
||||||
<el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="searchForm[item.prop]"
|
|
||||||
:disabled="item.disabled">
|
|
||||||
<el-checkbox v-for="option in item.options" :key="option.value" :label="option.value">
|
|
||||||
{{ option.label }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 自定义插槽项 -->
|
<!-- 自定义插槽项 -->
|
||||||
|
|
@ -69,13 +52,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Search } from '@element-plus/icons-vue'
|
|
||||||
|
|
||||||
// 定义配置项类型
|
// 定义配置项类型
|
||||||
interface SearchOption {
|
interface SearchOption {
|
||||||
prop: string; // 绑定的表单字段名
|
prop: string; // 绑定的表单字段名
|
||||||
label: string; // 标签文本
|
label: string; // 标签文本
|
||||||
type: 'input' | 'select' | 'date' | 'radio' | 'checkbox'; // 表单类型
|
type: 'input' | 'select' | 'date'; // 表单类型
|
||||||
slot?: boolean; // 是否为自定义插槽项
|
slot?: boolean; // 是否为自定义插槽项
|
||||||
placeholder?: string; // 占位符
|
placeholder?: string; // 占位符
|
||||||
clearable?: boolean; // 是否显示清空按钮
|
clearable?: boolean; // 是否显示清空按钮
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ const handleRowClick = (row: any) => {
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.table-container {
|
.table-container {
|
||||||
|
max-width: calc(100vw - 200px);
|
||||||
max-height: calc(100vh - 180px);
|
max-height: calc(100vh - 180px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -368,4 +368,8 @@ const handleClose = () => {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss">
|
||||||
|
.table-container{
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
@cancel="handleCancel" @close="handleClose">
|
@cancel="handleCancel" @close="handleClose">
|
||||||
<ClientForm :form-data="clientForm" :form-rules="clientFormRules" :form-items="clientFormOptions"
|
<ClientForm :form-data="clientForm" :form-rules="clientFormRules" :form-items="clientFormOptions"
|
||||||
:options-map="clientFormOptionsMap" ref="clientFormRef">
|
:options-map="clientFormOptionsMap" ref="clientFormRef">
|
||||||
<template #phoneOrEmail="{ formData }">
|
<template #phoneOrEmail="{ formData }" style="margin-left: 0;">
|
||||||
<div class="phone-email">
|
<div class="phone-email">
|
||||||
<div class="tab-btn">
|
<div class="tab-btn">
|
||||||
<el-button :type="activeTab === 'email' ? 'primary' : 'default'" size="small"
|
<el-button :type="activeTab === 'email' ? 'primary' : 'default'" size="small"
|
||||||
|
|
@ -338,6 +338,10 @@ const handleClose = () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
:deep(.el-form-item__content) {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.phone-email {
|
.phone-email {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
@ -366,7 +370,7 @@ const handleClose = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 110px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -554,6 +554,9 @@ const handleClose = async () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
:deep(.el-form-item__content){
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
.market {
|
.market {
|
||||||
.search-container {
|
.search-container {
|
||||||
:deep(.el-form) {
|
:deep(.el-form) {
|
||||||
|
|
@ -592,9 +595,12 @@ const handleClose = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-select {
|
.el-select {
|
||||||
width: 110px;
|
width: 120px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.table-container{
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<VarietySearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
<VarietySearch :search-form="searchForm" :search-options="searchOptions" @search="handleSearch"
|
||||||
@reset="handleReset">
|
@reset="handleReset">
|
||||||
<template #button="{ form }">
|
<template #button="{ form }">
|
||||||
<el-button type="primary" @click="handleEdit()">
|
<el-button type="primary" :disabled="!selectedRow" @click="handleEdit()">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" @click="handleAdd()">
|
<el-button type="primary" @click="handleAdd()">
|
||||||
|
|
@ -12,25 +12,24 @@
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</VarietySearch>
|
</VarietySearch>
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<VarietyTable :table-data="varietyTree" :columns="varietyTableColumnsOptions" row-key="id">
|
<VarietyTable :table-data="varietyTree" :columns="varietyTableColumnsOptions" row-key="id"
|
||||||
|
@row-click="handleRowClick">
|
||||||
<template #onlineStatus="{ row }">
|
<template #onlineStatus="{ row }">
|
||||||
<el-switch :model-value="row.onlineStatus === 1" :active-value="true" :inactive-value="false" />
|
<el-switch :model-value="row.onlineStatus === 1" :active-value="true" :inactive-value="false" />
|
||||||
</template>
|
</template>
|
||||||
<template #tradeStatus="{ row }">
|
<template #tradeStatus="{ row }">
|
||||||
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" />
|
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</VarietyTable>
|
</VarietyTable>
|
||||||
<!-- 分页 -->
|
|
||||||
<VarietyPagination v-model="currentPage" v-model:pageSizeValue="pageSize" :total="total"
|
|
||||||
@pagination-change="handlePaginationChange" />
|
|
||||||
</div>
|
</div>
|
||||||
<!-- dialog -->
|
<!-- dialog -->
|
||||||
<VarietyDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" :fullscreen="dialogFullscreen" :width="dialogWidth"
|
<VarietyDialog :visible="dialogVisible" :title="dialogTitle" :type="dialogType" @confirm="handleSubmit"
|
||||||
@confirm="handleSubmit" @cancel="handleCancel" @close="handleClose">
|
@cancel="handleCancel" @close="handleClose">
|
||||||
<VarietyForm :form-data="varietyForm" :form-rules="varietyFormRules" :form-items="dialogFormItemOptions"
|
<VarietyForm :form-data="varietyForm" :form-rules="varietyFormRules" :form-items="dialogFormItemOptions"
|
||||||
:options-map="varietyFormOptionsMap" ref="varietyFormRef" inline></VarietyForm>
|
:options-map="varietyFormOptionsMap" :row-gutter="rowGutter" :col-span="colSpan" ref="varietyFormRef">
|
||||||
|
</VarietyForm>
|
||||||
</VarietyDialog>
|
</VarietyDialog>
|
||||||
<!-- dialog表格 -->
|
<!-- dialog表格 -->
|
||||||
|
|
||||||
|
|
@ -40,17 +39,15 @@
|
||||||
// 组件
|
// 组件
|
||||||
import VarietySearch from '@/components/common/Search.vue'
|
import VarietySearch from '@/components/common/Search.vue'
|
||||||
import VarietyTable from '@/components/common/Table.vue'
|
import VarietyTable from '@/components/common/Table.vue'
|
||||||
import VarietyPagination from '@/components/common/Pagination.vue'
|
|
||||||
import VarietyDialog from '@/components/common/Dialog.vue'
|
import VarietyDialog from '@/components/common/Dialog.vue'
|
||||||
import VarietyForm from '@/components/common/Form.vue'
|
import VarietyForm from '@/components/common/Form.vue'
|
||||||
|
|
||||||
// 配置以及表单验证
|
// 配置以及表单验证
|
||||||
import { search, tableColumns, editDialogFormItem } from './options'
|
import { search, tableColumns, editDialogFormItem } from './options'
|
||||||
import { rules } from './rules'
|
import { rules } from './rules'
|
||||||
|
|
||||||
// 接口
|
// 接口
|
||||||
import { getVarietyListApi } from '@/api/modules/trade/variety'
|
import { getVarietyListApi, getTradeGroupListApi, editVarietyApi, createVarietyApi } from '@/api/modules/trade/variety'
|
||||||
|
|
||||||
// 公用方法
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义搜索数据
|
* @description: 定义搜索数据
|
||||||
|
|
@ -66,99 +63,119 @@ const searchOptions = ref(search)
|
||||||
const varietyTree = ref([])
|
const varietyTree = ref([])
|
||||||
const varietyTableColumnsOptions = ref(tableColumns)
|
const varietyTableColumnsOptions = ref(tableColumns)
|
||||||
|
|
||||||
/**
|
|
||||||
* @description: 定义分页数据
|
|
||||||
*/
|
|
||||||
const currentPage = ref(1)
|
|
||||||
const pageSize = ref(10)
|
|
||||||
const total = ref(0)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义弹窗数据
|
* @description: 定义弹窗数据
|
||||||
*/
|
*/
|
||||||
const dialogWidth = ref('700px')
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogTitle = ref('')
|
const dialogTitle = ref('')
|
||||||
const dialogType = ref('')
|
const dialogType = ref('')
|
||||||
const dialogFullscreen = ref(false)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义弹窗表格数据
|
* @description: 定义弹窗表单数据
|
||||||
*/
|
*/
|
||||||
const varietyForm = ref({
|
const varietyForm = ref({
|
||||||
|
// 品种名称
|
||||||
varietyName: '',
|
varietyName: '',
|
||||||
|
// 品种代码
|
||||||
varietyCode: '',
|
varietyCode: '',
|
||||||
|
// 线上状态
|
||||||
onlineStatus: 1,
|
onlineStatus: 1,
|
||||||
status: 1,
|
// 交易状态
|
||||||
currency: '',
|
tradeStatus: 1,
|
||||||
minPoint: 0,
|
// 最小点差
|
||||||
maxPoint: 0,
|
minPoint: '',
|
||||||
contractSize: 0,
|
// 最大点差
|
||||||
minFlux: 0,
|
maxPoint: '',
|
||||||
|
// 合约大小(乘数)
|
||||||
|
contractSize: '',
|
||||||
|
// 最小波动
|
||||||
|
minFlux: '',
|
||||||
|
// 单位
|
||||||
unit: '',
|
unit: '',
|
||||||
|
// 交易组
|
||||||
tradeGroup: '',
|
tradeGroup: '',
|
||||||
longStockFee: 0,
|
// 多头库存费
|
||||||
shortStockFee: 0,
|
longStockFee: '',
|
||||||
profitLevel: 0,
|
// 空头库存费
|
||||||
|
shortStockFee: '',
|
||||||
|
// 止盈水平
|
||||||
|
profitLevel: '',
|
||||||
|
|
||||||
|
id: '',
|
||||||
|
groupId: '',
|
||||||
|
// 预付款对冲
|
||||||
|
prepaymentHedge: '',
|
||||||
|
// 预付款对冲比例
|
||||||
|
prepaymentPercent: '',
|
||||||
|
// 小数位
|
||||||
|
decimalPlaces: '',
|
||||||
|
// 点差小数位
|
||||||
|
pointDecimalPlaces: '',
|
||||||
})
|
})
|
||||||
const varietyFormRules = ref(rules)
|
const varietyFormRef = ref<any>()
|
||||||
const dialogFormItemOptions = computed(() => dialogType.value === 'edit' ? editDialogFormItem : [])
|
const varietyFormRules = ref(rules())
|
||||||
|
const dialogFormItemOptions = ref(editDialogFormItem)
|
||||||
const varietyFormOptionsMap = ref({
|
const varietyFormOptionsMap = ref({
|
||||||
currency: [],
|
|
||||||
tradeGroup: [],
|
tradeGroup: [],
|
||||||
})
|
})
|
||||||
|
// 选中行
|
||||||
/**
|
const selectedRow = ref<any>(null)
|
||||||
* @description: 定义公共数据处理方法
|
const rowGutter = ref(20)
|
||||||
*/
|
const colSpan = ref(12)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义公共请求数据方法
|
* @description: 定义公共请求数据方法
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//获取品种列表
|
//获取品种列表
|
||||||
const getVarietyList = async () => {
|
const getVarietyList = async () => {
|
||||||
const params = {
|
const params = {
|
||||||
page: currentPage.value,
|
name: searchForm.value.varietyName,
|
||||||
page_size: pageSize.value,
|
|
||||||
user_name: searchForm.value.varietyName,
|
|
||||||
}
|
}
|
||||||
const data = await getVarietyListApi(params)
|
const data = await getVarietyListApi(params)
|
||||||
//表格数据
|
console.log('data', data)
|
||||||
|
//格式化表格数据
|
||||||
varietyTree.value = data.map((item: any) => ({
|
varietyTree.value = data.map((item: any) => ({
|
||||||
...item,
|
...item,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
varietyName: item.name,
|
varietyName: item.name,
|
||||||
varietyCode: item.code,
|
varietyCode: item.code,
|
||||||
onlineStatus: item.online_status,
|
onlineStatus: item.online_status,
|
||||||
// tradeStatus: item.status,
|
tradeStatus: item.status,
|
||||||
currency: 'currency',
|
|
||||||
minPoint: item.point_diff,
|
minPoint: item.point_diff,
|
||||||
maxPoint: item.point_diff_max,
|
maxPoint: item.point_diff_max,
|
||||||
contractSize: 'contractSize',
|
contractSize: item.multiplier,
|
||||||
minFlux: item.undulate_min,
|
minFlux: item.undulate_min,
|
||||||
unit: item.unit,
|
unit: item.unit,
|
||||||
tradeGroup: item.group.name,
|
tradeGroup: item.group.name,
|
||||||
longStockFee: item.fee_inventory_long,
|
longStockFee: item.fee_inventory_long,
|
||||||
shortStockFee: item.fee_inventory_short,
|
shortStockFee: item.fee_inventory_short,
|
||||||
profitLevel: item.stop_loss_level
|
profitLevel: item.stop_loss_level,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
//分页数据
|
|
||||||
total.value = data.total
|
|
||||||
currentPage.value = data.current_page
|
|
||||||
pageSize.value = Number(data.per_page)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//获取交易组列表
|
||||||
|
const getTradeGroupList = async () => {
|
||||||
|
const data = await getTradeGroupListApi()
|
||||||
|
varietyFormOptionsMap.value.tradeGroup = data.map((item: any) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 页面加载完成需要请求的数据
|
* @description: 页面加载完成需要请求的数据
|
||||||
*/
|
*/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getVarietyList()
|
getVarietyList()
|
||||||
|
getTradeGroupList()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义搜索方法
|
* @description: 定义搜索方法
|
||||||
*/
|
*/
|
||||||
const handleSearch = async () => {
|
const handleSearch = async () => {
|
||||||
|
getVarietyList()
|
||||||
}
|
}
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
searchForm.value = {
|
searchForm.value = {
|
||||||
|
|
@ -166,31 +183,95 @@ const handleReset = () => {
|
||||||
}
|
}
|
||||||
handleSearch()
|
handleSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('varietyForm.value)', varietyForm.value)
|
||||||
|
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,
|
||||||
|
} as any
|
||||||
|
//数据赋值完成后执行弹窗操作
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '编辑合约品种'
|
||||||
|
dialogType.value = 'edit'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = '添加合约品种'
|
dialogTitle.value = '添加合约品种'
|
||||||
dialogType.value = 'add'
|
dialogType.value = 'add'
|
||||||
}
|
varietyForm.value = {
|
||||||
const handleEdit = () => {
|
varietyName: '',
|
||||||
dialogVisible.value = true
|
varietyCode: '',
|
||||||
dialogTitle.value = '编辑合约品种'
|
onlineStatus: 1,
|
||||||
dialogType.value = 'edit'
|
tradeStatus: 1,
|
||||||
|
minPoint: '',
|
||||||
|
maxPoint: '',
|
||||||
|
contractSize: '',
|
||||||
|
minFlux: '',
|
||||||
|
unit: '',
|
||||||
|
tradeGroup: '',
|
||||||
|
longStockFee: '',
|
||||||
|
shortStockFee: '',
|
||||||
|
profitLevel: '',
|
||||||
|
|
||||||
|
id: '',
|
||||||
|
groupId: '',
|
||||||
|
prepaymentHedge: '',
|
||||||
|
prepaymentPercent: '',
|
||||||
|
decimalPlaces: '',
|
||||||
|
pointDecimalPlaces: '',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @description: 定义表格方法
|
* @description: 定义表格方法
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* @description: 定义分页方法
|
|
||||||
*/
|
|
||||||
const handlePaginationChange = async (page: { currentPage: number, pageSize: number }) => {
|
|
||||||
currentPage.value = page.currentPage
|
|
||||||
pageSize.value = page.pageSize
|
|
||||||
await getVarietyList()
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @description: 定义弹窗方法
|
* @description: 定义弹窗方法
|
||||||
*/
|
*/
|
||||||
const handleSubmit = async () => {
|
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.groupId,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
if (dialogType.value === 'edit') {
|
||||||
|
console.log(params)
|
||||||
|
await editVarietyApi(params)
|
||||||
|
getVarietyList()
|
||||||
|
} else {
|
||||||
|
await createVarietyApi({...params, group_id: varietyForm.value.tradeGroup})
|
||||||
|
getVarietyList()
|
||||||
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
|
@ -203,6 +284,14 @@ const handleClose = () => {
|
||||||
/**
|
/**
|
||||||
* @description: 定义弹窗表格方法
|
* @description: 定义弹窗表格方法
|
||||||
*/
|
*/
|
||||||
|
// 点击行事件
|
||||||
|
const handleRowClick = (row: any) => {
|
||||||
|
if (!row) {
|
||||||
|
selectedRow.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedRow.value = row
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ export const tableColumns = [
|
||||||
{ slotName: 'onlineStatus', label: '上下线状态', align: 'center' as const },
|
{ slotName: 'onlineStatus', label: '上下线状态', align: 'center' as const },
|
||||||
// 交易状态
|
// 交易状态
|
||||||
{ slotName: 'tradeStatus', label: '交易状态', align: 'center' as const },
|
{ slotName: 'tradeStatus', label: '交易状态', align: 'center' as const },
|
||||||
// 币种
|
|
||||||
{ prop: 'currency', label: '币种', align: 'center' as const },
|
|
||||||
// 最小点差
|
// 最小点差
|
||||||
{ prop: 'minPoint', label: '最小点差', align: 'center' as const },
|
{ prop: 'minPoint', label: '最小点差', align: 'center' as const },
|
||||||
// 最大点差
|
// 最大点差
|
||||||
|
|
@ -50,29 +48,35 @@ export const editDialogFormItem = [
|
||||||
{ prop: 'varietyName', label: '名称', type: 'input' as const, placeholder: '请输入名称' },
|
{ prop: 'varietyName', label: '名称', type: 'input' as const, placeholder: '请输入名称' },
|
||||||
// 编号
|
// 编号
|
||||||
{ prop: 'varietyCode', label: '编号', type: 'input' as const, placeholder: '请输入编号' },
|
{ prop: 'varietyCode', label: '编号', type: 'input' as const, placeholder: '请输入编号' },
|
||||||
// 上下线状态
|
// 所属交易组
|
||||||
{ prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const, class: 'online-status-switch' },
|
{ prop: 'tradeGroup', label: '所属交易组', type: 'select' as const, placeholder: '请输入所属交易组' },
|
||||||
// 交易状态
|
// 最大点差
|
||||||
{ prop: 'tradeStatus', label: '交易状态', type: 'switch' as const, class: 'trade-status-switch' },
|
{ prop: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' },
|
||||||
// 币种
|
|
||||||
{ prop: 'currency', label: '币种', type: 'input' as const, placeholder: '请输入币种' },
|
|
||||||
// 最小点差
|
// 最小点差
|
||||||
{ prop: 'minPoint', label: '最小点差', type: 'input' as const, placeholder: '请输入最小点差' },
|
{ prop: 'minPoint', label: '最小点差', type: 'input' as const, placeholder: '请输入最小点差' },
|
||||||
// 最大点差
|
|
||||||
{ prop: 'maxPoint', label: '最大点差', type: 'input' as const, placeholder: '请输入最大点差' },
|
|
||||||
// 合约大小
|
// 合约大小
|
||||||
{ prop: 'contractSize', label: '合约大小', type: 'input' as const, placeholder: '请输入合约大小' },
|
{ prop: 'contractSize', label: '合约大小', type: 'input' as const, placeholder: '请输入合约大小' },
|
||||||
// 最小波动
|
|
||||||
{ prop: 'minFlux', label: '最小波动', type: 'input' as const, placeholder: '请输入最小波动' },
|
|
||||||
// 单位
|
|
||||||
{ prop: 'unit', label: '单位', type: 'input' as const, placeholder: '请输入单位' },
|
|
||||||
// 所属交易组
|
|
||||||
{ prop: 'tradeGroup', 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: '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: 'profitLevel', label: '止盈水平', type: 'input' as const, placeholder: '请输入止盈水平' },
|
||||||
|
// 单位
|
||||||
]
|
{ prop: 'unit', label: '单位', type: 'input' as const, placeholder: '请输入单位' },
|
||||||
|
// 最小波动
|
||||||
|
{ prop: 'minFlux', label: '最小波动', type: 'input' as const, placeholder: '请输入最小波动' },
|
||||||
|
// 上下线状态
|
||||||
|
{ prop: 'onlineStatus', label: '上下线状态', type: 'switch' as const},
|
||||||
|
// 交易状态
|
||||||
|
{ prop: 'tradeStatus', label: '交易状态', type: 'switch' as const},
|
||||||
|
|
||||||
|
]
|
||||||
|
|
@ -1,8 +1,90 @@
|
||||||
import type { FormRules } from 'element-plus'
|
import type { FormRules } from 'element-plus'
|
||||||
export const rules = (): FormRules => {
|
|
||||||
return {
|
/**
|
||||||
name: [
|
* 通用的五位小数校验函数(支持自定义提示文案)
|
||||||
{ required: true, message: '请输入名称', trigger: ['blur'] }
|
* @param fieldName 字段名称(用于拼接提示文案)
|
||||||
],
|
* @returns 校验器函数
|
||||||
|
*/
|
||||||
|
const validateMaxFiveDecimals = (fieldName: string) => {
|
||||||
|
return (rule: any, value: any, callback: any) => {
|
||||||
|
if (value !== undefined && value !== null && value !== '') {
|
||||||
|
const decimalPart = value.toString().split('.')[1]
|
||||||
|
if (decimalPart && decimalPart.length > 5) {
|
||||||
|
callback(new Error(`${fieldName}小数位不能超过5位`))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const rules = (): FormRules => {
|
||||||
|
return {
|
||||||
|
// 名称
|
||||||
|
varietyName: [
|
||||||
|
{ required: true, message: '请输入名称', trigger: ['blur'] }
|
||||||
|
],
|
||||||
|
// 编号
|
||||||
|
varietyCode: [
|
||||||
|
{ required: true, message: '请输入编号', trigger: ['blur'] }
|
||||||
|
],
|
||||||
|
// 所属交易组
|
||||||
|
tradeGroup: [
|
||||||
|
{ required: true, message: '请输入所属交易组', trigger: ['blur'] }
|
||||||
|
],
|
||||||
|
// 最大点差
|
||||||
|
maxPoint: [
|
||||||
|
{ required: true, message: '请输入最大点差', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('最大点差'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 最小点差
|
||||||
|
minPoint: [
|
||||||
|
{ required: true, message: '请输入最小点差', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('最小点差'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 合约大小
|
||||||
|
contractSize: [
|
||||||
|
{ required: true, message: '请输入合约大小', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('合约大小'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 多头库存费
|
||||||
|
longStockFee: [
|
||||||
|
{ required: true, message: '请输入多头库存费', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('多头库存费'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 空头库存费
|
||||||
|
shortStockFee: [
|
||||||
|
{ required: true, message: '请输入空头库存费', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('空头库存费'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 预付款对冲
|
||||||
|
prepaymentHedge: [
|
||||||
|
{ required: true, message: '请输入预付款对冲', trigger: ['blur', 'change'] },
|
||||||
|
|
||||||
|
{ validator: validateMaxFiveDecimals('预付款对冲'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 预付款百分比
|
||||||
|
prepaymentPercent: [
|
||||||
|
{ required: true, message: '请输入预付款百分比', trigger: ['blur', 'change'] },
|
||||||
|
|
||||||
|
{ validator: validateMaxFiveDecimals('预付款百分比'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 小数位
|
||||||
|
decimalPlaces: [
|
||||||
|
{ required: true, message: '请输入小数位', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('小数位'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 点差小数位
|
||||||
|
pointDecimalPlaces: [
|
||||||
|
{ required: true, message: '请输入点差小数位', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('点差小数位'), trigger: ['blur', 'change'] }
|
||||||
|
],
|
||||||
|
// 止盈水平
|
||||||
|
profitLevel: [
|
||||||
|
{ required: true, message: '请输入止盈水平', trigger: ['blur', 'change'] },
|
||||||
|
{ validator: validateMaxFiveDecimals('止盈水平'), trigger: ['blur', 'change'] }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue