li.shaoyi 3 anos atrás
pai
commit
e1abf03c94

+ 37 - 0
src/components/base/tab-component/index.less

@@ -0,0 +1,37 @@
+.app-tab-component {
+    display       : flex;
+    flex-direction: column;
+    overflow      : hidden;
+
+    &.left {
+        flex-direction : row;
+        flex-flow      : row-reverse;
+        justify-content: left;
+
+        .tab {
+            flex-direction: column;
+        }
+    }
+
+    &.right {
+        flex-direction: row;
+
+        .tab {
+            flex-direction: column;
+        }
+    }
+
+    &.top {
+        flex-flow: column-reverse;
+    }
+
+    .tab {
+        display      : flex;
+        margin-bottom: 10px;
+
+        &-item {
+            margin-right: 10px;
+            cursor      : pointer;
+        }
+    }
+}

+ 36 - 0
src/components/base/tab-component/index.vue

@@ -0,0 +1,36 @@
+<template>
+    <div :class="['app-tab-component', direction]" v-if="dynamicComponents.length">
+        <ul class="tab">
+            <template v-for="(item, index) in dynamicComponents" :key="index">
+                <li class="tab-item" @click="componentChange(index)">
+                    <slot :name="item.code" :item="item" :index="index">{{ item.title }}</slot>
+                </li>
+            </template>
+        </ul>
+        <div class="app-tab-component__container">
+            <component :is="currentTabComponent.component" :name="currentTabComponent.code" v-bind="options"
+                v-if="currentTabComponent" />
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { PropType } from 'vue'
+import { useDynamicComponent } from '@/hooks/component'
+
+const props = defineProps({
+    code: String,
+    options: Object,
+    // 组件内容方向
+    direction: {
+        type: String as PropType<'left' | 'right' | 'top' | 'bottom'>,
+        default: 'top',
+    },
+})
+
+const { dynamicComponents, currentTabComponent, componentChange } = useDynamicComponent(props.code);
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 2 - 1
src/components/base/tab/index.less

@@ -1,6 +1,7 @@
 .app-tab {
     &__list {
-        display: flex;
+        display  : flex;
+        flex-wrap: wrap;
 
         &-item {
             display        : flex;

+ 43 - 0
src/constants/enum/chart.ts

@@ -0,0 +1,43 @@
+import { EnumType } from './index'
+
+/**
+ * 图表周期类型
+ */
+export enum ChartCycleType {
+    time = -1, // 分时
+    minutes = 1, // 1分钟
+    minutes5 = 2, // 5分钟
+    minutes30 = 3, // 30分钟
+    minutes60 = 4, // 60分钟
+    hours2 = 120, // 2小时
+    Hours4 = 240, // 4小时
+    days = 11, // 日线
+}
+
+/**
+ * 图表指标类型
+ */
+export enum ChartSeriesType {
+    MACD,
+    VOL,
+    KDJ,
+    CCI,
+}
+
+export const chartCycleTypeList: EnumType[] = [
+    { label: '分时', value: ChartCycleType.time },
+    { label: '1分钟', value: ChartCycleType.minutes },
+    { label: '5分钟', value: ChartCycleType.minutes5 },
+    { label: '30分钟', value: ChartCycleType.minutes30 },
+    { label: '60分钟', value: ChartCycleType.minutes60 },
+    { label: '2小时', value: ChartCycleType.hours2 },
+    { label: '4小时', value: ChartCycleType.Hours4 },
+    { label: '日线', value: ChartCycleType.days },
+]
+
+export const chartSeriesTypeList: EnumType[] = [
+    { label: 'MACD', value: ChartSeriesType.MACD },
+    { label: 'VOL', value: ChartSeriesType.VOL },
+    { label: 'KDJ', value: ChartSeriesType.KDJ },
+    { label: 'CCI', value: ChartSeriesType.CCI },
+]

+ 0 - 23
src/constants/enum/echarts.ts

@@ -1,23 +0,0 @@
-/**
- * 图表周期类型
- */
-export enum EChartsCycleType {
-    time = -1, // 分时
-    minutes = 1, // 1分钟
-    minutes5 = 2, // 5分钟
-    minutes30 = 3, // 30分钟
-    minutes60 = 4, // 60分钟
-    hours2 = 120, // 2小时
-    Hours4 = 240, // 4小时
-    days = 11, // 日线
-}
-
-/**
- * 图表指标类型
- */
-export enum EChartsSeriesType {
-    MACD,
-    VOL,
-    KDJ,
-    CCI,
-}

+ 18 - 3
src/constants/enum/index.ts

@@ -1,3 +1,18 @@
-export * from './funcode'
-export * from './echarts'
-export * from './theme'
+export interface EnumType {
+    label: string;
+    value: number;
+}
+
+/**
+ * 获取枚举类型名称
+ * @param list 
+ * @param value 
+ * @returns 
+ */
+export function getEnumTypeName(list: EnumType[], value: number) {
+    const item = list.find((e) => e.value === value);
+    if (item) {
+        return item.label;
+    }
+    return value.toString();
+}

+ 18 - 10
src/hooks/component/index.ts

@@ -43,13 +43,14 @@ export function useComponent<T>(callback?: () => void) {
 }
 
 /**
- * @param routeName 
+ * @param menucode 
  * @returns 
  */
-export function useDynamicComponent(routeName?: string) {
+export function useDynamicComponent(menucode?: string) {
     const { getChildrenMenu } = useMenu();
-    const dynamicComponents = shallowRef<DynamicComponent[]>([]);
-    const currentTabComponent = shallowRef<DynamicComponent>(); // 当前选中的组件
+    const dynamicComponents: DynamicComponent[] = [];
+    const currentAuth: Ermcp.AccountMenu.Auth[] = []; // 当前操作权限
+    const currentTabComponent = shallowRef<DynamicComponent>(); // 当前选中的子组件
 
     /**
      * 转换动态组件
@@ -92,19 +93,26 @@ export function useDynamicComponent(routeName?: string) {
      * @param index 
      */
     const componentChange = (index: number) => {
-        currentTabComponent.value = dynamicComponents.value[index];
+        currentTabComponent.value = dynamicComponents[index];
     }
 
-    const childrenMenus = getChildrenMenu(routeName);
-    const components = parseComponent(childrenMenus);
+    const childrenMenu = getChildrenMenu(menucode);
 
-    if (components.length) {
-        dynamicComponents.value = components;
-        componentChange(0);
+    if (childrenMenu) {
+        const { auth, children } = childrenMenu;
+        const components = parseComponent(children ?? []);
+
+        currentAuth.push(...auth ?? []);
+        dynamicComponents.push(...components);
+
+        if (components.length) {
+            componentChange(0);
+        }
     }
 
     return {
         dynamicComponents,
+        currentAuth,
         currentTabComponent,
         componentChange,
     }

+ 9 - 9
src/hooks/echarts/candlestick/index.ts

@@ -1,6 +1,6 @@
 import { ref, computed, watch } from 'vue'
 //import { timerInterceptor } from '@/utils/timer'
-import { EChartsCycleType } from '@/constants/enum/echarts'
+import { ChartCycleType } from '@/constants/enum/chart'
 import { queryHistoryDatas } from '@/services/api/quote'
 import { getQuoteDayInfoByCode } from '@/business/common'
 import { useDataset } from './dataset'
@@ -14,7 +14,7 @@ export function useCandlestickChart(goodscode: string) {
     const loading = ref(false);
     const isEmpty = ref(true);
     const dataIndex = ref(-1); // 当前数据索引值
-    const cycleType = ref(EChartsCycleType.minutes);
+    const cycleType = ref(ChartCycleType.minutes);
     const quote = getQuoteDayInfoByCode(goodscode);
 
     // 当前选中的数据项
@@ -54,7 +54,7 @@ export function useCandlestickChart(goodscode: string) {
      * 初始化数据
      * @param cycletype 周期类型
      */
-    const initData = (cycletype: EChartsCycleType) => {
+    const initData = (cycletype: ChartCycleType) => {
         clearData();
         dataIndex.value = -1;
         cycleType.value = cycletype;
@@ -87,22 +87,22 @@ export function useCandlestickChart(goodscode: string) {
     const getCycleMilliseconds = () => {
         const milliseconds = 60 * 1000; // 一分钟毫秒数
         switch (cycleType.value) {
-            case EChartsCycleType.minutes5: {
+            case ChartCycleType.minutes5: {
                 return milliseconds * 5;
             }
-            case EChartsCycleType.minutes30: {
+            case ChartCycleType.minutes30: {
                 return milliseconds * 30;
             }
-            case EChartsCycleType.minutes60: {
+            case ChartCycleType.minutes60: {
                 return milliseconds * 60;
             }
-            case EChartsCycleType.hours2: {
+            case ChartCycleType.hours2: {
                 return milliseconds * 2 * 60;
             }
-            case EChartsCycleType.Hours4: {
+            case ChartCycleType.Hours4: {
                 return milliseconds * 4 * 60;
             }
-            case EChartsCycleType.days: {
+            case ChartCycleType.days: {
                 return milliseconds * 24 * 60;
             }
             default: {

+ 16 - 16
src/hooks/menu/index.ts

@@ -4,29 +4,29 @@ import { AuthMenu } from './interface'
 
 export function useMenu() {
     const route = useRoute();
+    const auth = route.meta.auth as Ermcp.AccountMenu.Auth[];
     const menus = sessionCache.getValue('menus');
 
     /**
      * 通过code获取对应的子菜单
-     * @param routeName 
+     * @param menucode 
      * @returns 
      */
-    const getChildrenMenu = (routeName?: string) => {
-        const filter = (items: Ermcp.AccountMenu[], name?: string) => {
-            let result: Ermcp.AccountMenu[] = [];
+    const getChildrenMenu = (menucode?: string) => {
+        const filter = (items: Ermcp.AccountMenu[], name?: string): Ermcp.AccountMenu | undefined => {
             if (name) {
                 for (let i = 0; i < items.length; i++) {
                     const { code, children } = items[i];
-                    if (code === name) return children ?? result;
+                    if (code === name) return items[i];
                     if (children) {
-                        result = filter(children, name)
-                        if (result.length) return result;
+                        const res = filter(children, name);
+                        if (res) return res;
                     }
                 }
             }
-            return result;
+            return undefined;
         }
-        return filter(menus, routeName ?? route.name?.toString());
+        return filter(menus, menucode ?? route.name?.toString());
     }
 
     /**
@@ -51,29 +51,29 @@ export function useMenu() {
     }
 
     /**
-     * 获取当前页面操作权限
+     * 过滤操作权限
      * @param filtered 过滤的数据项
      * @param reverse 是否反向过滤
      * @returns 
      */
-    const getAuth = (filtered: string[] = [], reverse = false) => {
-        const result = route.meta.auth as Ermcp.AccountMenu.Auth[];
+    const authFilter = (filtered: string[] = [], reverse = false) => {
         if (filtered.length) {
             if (reverse) {
                 // 返回除指定的权限代码
-                return result.filter((e) => !filtered.includes(e.code));
+                return auth.filter((e) => !filtered.includes(e.code));
             } else {
                 // 返回指定的权限代码
-                return result.filter((e) => filtered.includes(e.code));
+                return auth.filter((e) => filtered.includes(e.code));
             }
         }
-        return result;
+        return auth;
     }
 
     return {
         menus,
+        auth,
         getChildrenMenu,
-        getAuth,
+        authFilter,
         getAuthMenu,
     }
 }

+ 1 - 1
src/hooks/theme/index.ts

@@ -1,5 +1,5 @@
 import { localCache } from '@/store'
-import { AppTheme } from '@/constants/enum'
+import { AppTheme } from '@/constants/enum/theme'
 import plus from '@/utils/h5plus'
 
 /**

+ 3 - 3
src/packages/mobile/components/modules/echarts-kline/index.vue

@@ -25,7 +25,7 @@
 
 <script lang="ts" setup>
 import { PropType, watch } from 'vue'
-import { EChartsCycleType } from '@/constants/enum'
+import { ChartCycleType } from '@/constants/enum/chart'
 import { useCandlestickChart } from '@/hooks/echarts/candlestick'
 import AppEcharts from '@/components/base/echarts/index.vue'
 
@@ -36,8 +36,8 @@ const props = defineProps({
     },
     // 周期类型
     cycleType: {
-        type: Number as PropType<EChartsCycleType>,
-        default: EChartsCycleType.minutes,
+        type: Number as PropType<ChartCycleType>,
+        default: ChartCycleType.minutes,
     },
     // 是否显示指标
     showIndicator: {

+ 7 - 14
src/packages/mobile/views/order/detail/index.vue

@@ -2,14 +2,14 @@
   <div class="order-detail g-flex">
     <app-navbar title="详情" />
     <div class="g-flex__body">
-      <app-tab theme="menu" :data-source="tabs" :data-index="1" @change="tabChange" />
-      <component :is="components.echartsTimeline" v-if="selectedCycleType === EChartsCycleType.time" />
+      <app-tab theme="menu" :data-source="chartCycleTypeList" :data-index="1" @change="tabChange" />
+      <component :is="components.echartsTimeline" v-if="selectedCycleType === ChartCycleType.time" />
       <component :is="components.echartsKline" :cycle-type="selectedCycleType" v-else />
     </div>
     <div class="order-detail__footer">
       <Button @click="openComponent('trade')" type="primary" round block>挂牌求购</Button>
     </div>
-    <component ref="childComponent" :is="components[componentId]" @closed="closeComponent" />
+    <component ref="childComponent" :is="components[componentId]" @closed="closeComponent" v-if="componentId" />
   </div>
 </template>
 
@@ -18,7 +18,7 @@ import { defineAsyncComponent, ref } from 'vue'
 import { onBeforeRouteLeave } from 'vue-router'
 import { Button } from 'vant'
 import { useComponent } from '@/hooks/component'
-import { EChartsCycleType } from '@/constants/enum'
+import { ChartCycleType, chartCycleTypeList } from '@/constants/enum/chart'
 import AppTab from '@/components/base/tab/index.vue'
 
 const components = {
@@ -27,20 +27,13 @@ const components = {
   echartsKline: defineAsyncComponent(() => import('@mobile/components/modules/echarts-kline/index.vue')),
 }
 
-const { componentId, openComponent, closeComponent } = useComponent();
+const { componentId, openComponent, closeComponent } = useComponent<typeof components>();
 const childComponent = ref();
-const selectedCycleType = ref(EChartsCycleType.minutes); // 当前选中的图表周期
-
-const tabs = [
-  { label: '分时', value: EChartsCycleType.time },
-  { label: '1分钟', value: EChartsCycleType.minutes },
-  { label: '5分钟', value: EChartsCycleType.minutes5 },
-  { label: '30分钟', value: EChartsCycleType.minutes30 },
-]
+const selectedCycleType = ref(ChartCycleType.minutes); // 当前选中的图表周期
 
 // 指标切换
 const tabChange = (index: number) => {
-  selectedCycleType.value = tabs[index].value;
+  selectedCycleType.value = chartCycleTypeList[index].value;
 }
 
 onBeforeRouteLeave((to, from, next) => {

+ 24 - 22
src/packages/pc/components/base/table/index.less

@@ -1,29 +1,31 @@
 .app-table {
-    --el-table-bg-color              : transparent; //表格背景颜色
-    --el-table-text-color            : #fff; //表格文字颜色
-    --el-table-border-color          : #161a1c; // 表格边框颜色
-    --el-table-border                : 1px solid var(--el-table-border-color); // 表格边框
-    --el-table-header-bg-color       : #212629; // 表头背景颜色
-    --el-table-header-text-color     : #556772; // 表头文字颜色
-    --el-table-tr-bg-color           : var(--el-table-bg-color); // 表格行背景颜色
-    --el-table-row-hover-bg-color    : #172b56; // 表格行鼠标经过背景色
-    --el-table-expanded-cell-bg-color: var(--el-table-bg-color); // 展开行背景颜色
-    --el-table-current-row-bg-color  : var(--el-table-row-hover-bg-color); // 当前行高亮颜色
+    .el-table {
+        --el-table-bg-color              : transparent; //表格背景颜色
+        --el-table-text-color            : #fff; //表格文字颜色
+        --el-table-border-color          : #161a1c; // 表格边框颜色
+        --el-table-border                : 1px solid var(--el-table-border-color); // 表格边框
+        --el-table-header-bg-color       : #212629; // 表头背景颜色
+        --el-table-header-text-color     : #556772; // 表头文字颜色
+        --el-table-tr-bg-color           : var(--el-table-bg-color); // 表格行背景颜色
+        --el-table-row-hover-bg-color    : #172b56; // 表格行鼠标经过背景色
+        --el-table-expanded-cell-bg-color: var(--el-table-bg-color); // 展开行背景颜色
+        --el-table-current-row-bg-color  : var(--el-table-row-hover-bg-color); // 当前行高亮颜色
 
-    width: 100%;
+        width: 100%;
 
-    th.el-table__cell {
-        font-weight: normal;
-        height     : 30px;
-        padding    : 0;
-    }
+        th.el-table__cell {
+            font-weight: normal;
+            height     : 30px;
+            padding    : 0;
+        }
 
-    td.el-table__cell {
-        height : 30px;
-        padding: 0;
-    }
+        td.el-table__cell {
+            height : 30px;
+            padding: 0;
+        }
 
-    .app-button-group {
-        justify-content: flex-end;
+        .app-button-group {
+            justify-content: flex-end;
+        }
     }
 }

+ 4 - 4
src/packages/pc/components/base/table/index.ts

@@ -68,10 +68,10 @@ export function useTable<T>(rowKey: keyof T, tableName?: string) {
         }
     }
 
-    // 表格查询
-    const search = (options: FilterOption<T>[]) => {
+    // 过滤表格
+    const filter = (options: FilterOption<T>[]) => {
         filterOptions.value = options;
-        console.log('表格查询参数', options);
+        console.log('表格过滤参数', options);
     }
 
     if (tableName) {
@@ -86,6 +86,6 @@ export function useTable<T>(rowKey: keyof T, tableName?: string) {
         selectedRow,
         rowClickExpand,
         rowContextmenu,
-        search,
+        filter,
     }
 }

+ 18 - 14
src/packages/pc/components/base/table/index.vue

@@ -1,18 +1,22 @@
 <template>
-  <el-table class="app-table" border>
-    <el-table-column type="expand" v-if="$slots.expand">
-      <template #default="{ row }">
-        <slot name="expand" :row="row"></slot>
-      </template>
-    </el-table-column>
-    <el-table-column v-for="(item, index) in columns" :key="index" :filters="item.filters"
-      :filter-method="item.filterMethod" :class-name="item.className" :label="item.label"
-      :align="item.align ?? 'center'" :width="item.width">
-      <template #default="{ row }">
-        <slot :name="item.key" :row="row">{{ row[item.key] }}</slot>
-      </template>
-    </el-table-column>
-  </el-table>
+  <div class="app-table">
+    <el-table v-bind="$attrs" border>
+      <el-table-column type="expand" v-if="$slots.expand">
+        <template #default="{ row }">
+          <slot name="expand" :row="row"></slot>
+        </template>
+      </el-table-column>
+      <el-table-column v-for="(item, index) in columns" :key="index" :filters="item.filters"
+        :filter-method="item.filterMethod" :class-name="item.className" :label="item.label"
+        :align="item.align ?? 'center'" :width="item.width">
+        <template #default="{ row }">
+          <slot :name="item.key" :row="row">{{ row[item.key] }}</slot>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 右键菜单功能,暂未实现 -->
+    <slot name="contextmenu"></slot>
+  </div>
 </template>
 
 <script lang="ts" setup>

+ 10 - 17
src/packages/pc/components/modules/echarts-kline/index.vue

@@ -22,7 +22,7 @@
       <template v-if="showIndicator">
         <div class="app-echats-kline__container indicator">
           <!-- MACD -->
-          <section class="section" v-if="activeSeriesType === EChartsSeriesType.MACD">
+          <section class="section" v-if="activeSeriesType === ChartSeriesType.MACD">
             <ul class="legend">
               <li class="legend-item">MACD: {{ selectedItem.macd }}</li>
               <li class="legend-item">DIF: {{ selectedItem.dif }}</li>
@@ -31,14 +31,14 @@
             <app-echarts :option="options.macd" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
           </section>
           <!-- VOL -->
-          <section class="section" v-if="activeSeriesType === EChartsSeriesType.VOL">
+          <section class="section" v-if="activeSeriesType === ChartSeriesType.VOL">
             <ul class="legend">
               <li class="legend-item">VOL: {{ selectedItem.vol }}</li>
             </ul>
             <app-echarts :option="options.vol" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
           </section>
           <!-- KDJ -->
-          <section class="section" v-if="activeSeriesType === EChartsSeriesType.KDJ">
+          <section class="section" v-if="activeSeriesType === ChartSeriesType.KDJ">
             <ul class="legend">
               <li class="legend-item">K: {{ selectedItem.k }}</li>
               <li class="legend-item">D: {{ selectedItem.d }}</li>
@@ -47,14 +47,14 @@
             <app-echarts :option="options.kdj" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
           </section>
           <!-- CCI -->
-          <section class="section" v-if="activeSeriesType === EChartsSeriesType.CCI">
+          <section class="section" v-if="activeSeriesType === ChartSeriesType.CCI">
             <ul class="legend">
               <li class="legend-item">CCI: {{ selectedItem.cci }}</li>
             </ul>
             <app-echarts :option="options.cci" v-model:dataIndex="dataIndex" @ready="indicatorReady" />
           </section>
         </div>
-        <app-tab theme="menu" :data-source="tabs" @change="tabChange" />
+        <app-tab theme="menu" :data-source="chartSeriesTypeList" @change="tabChange" />
       </template>
     </template>
   </div>
@@ -63,7 +63,7 @@
 <script lang="ts" setup>
 import { ref, PropType, watch } from 'vue'
 import { echarts } from '@/components/base/echarts/core'
-import { EChartsCycleType, EChartsSeriesType } from '@/constants/enum'
+import { ChartCycleType, ChartSeriesType, chartSeriesTypeList } from '@/constants/enum/chart'
 import { useCandlestickChart } from '@/hooks/echarts/candlestick'
 import AppEcharts from '@/components/base/echarts/index.vue'
 import AppTab from '@/components/base/tab/index.vue'
@@ -75,8 +75,8 @@ const props = defineProps({
   },
   // 周期类型
   cycleType: {
-    type: Number as PropType<EChartsCycleType>,
-    default: EChartsCycleType.minutes,
+    type: Number as PropType<ChartCycleType>,
+    default: ChartCycleType.minutes,
   },
   // 是否显示指标
   showIndicator: {
@@ -86,19 +86,12 @@ const props = defineProps({
 })
 
 const { loading, dataIndex, isEmpty, options, selectedItem, initData, initOptions } = useCandlestickChart(props.goodscode);
-const activeSeriesType = ref(EChartsSeriesType.MACD); // 当前选中的指标
+const activeSeriesType = ref(ChartSeriesType.MACD); // 当前选中的指标
 const chartGroup = new Map<string, echarts.ECharts>(); // 图表联动实例组
 
-const tabs = [
-  { label: 'MACD', value: EChartsSeriesType.MACD },
-  { label: 'VOL', value: EChartsSeriesType.VOL },
-  { label: 'KDJ', value: EChartsSeriesType.KDJ },
-  { label: 'CCI', value: EChartsSeriesType.CCI },
-]
-
 // 指标切换
 const tabChange = (index: number) => {
-  activeSeriesType.value = tabs[index].value;
+  activeSeriesType.value = chartSeriesTypeList[index].value;
   setTimeout(() => {
     initOptions();
   }, 0);

+ 5 - 16
src/packages/pc/views/market/goods/index.vue

@@ -2,9 +2,8 @@
   <app-view class="futures-goods" @ready="onReady">
     <div>全局共享数据:{{ goodsList }}</div>
     <el-button @click="clearGoods">清空</el-button>
-    <app-tab theme="menu" :data-source="tabs" :data-index="1" @change="tabChange" />
-    <component :is="components.echartsTimeline" style="height:70%;"
-      v-if="selectedCycleType === EChartsCycleType.time" />
+    <app-tab theme="menu" :data-source="chartCycleTypeList" :data-index="1" @change="tabChange" />
+    <component :is="components.echartsTimeline" style="height:70%;" v-if="selectedCycleType === ChartCycleType.time" />
     <component :is="components.echartsKline" :cycle-type="selectedCycleType" style="height:70%;" v-else />
     <!-- <div ref="scrollEl" style="height:300px;overflow-y:auto;">
       <div style="height:3000px;"></div>
@@ -16,7 +15,7 @@
 import { defineAsyncComponent, ref } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
 import { globalState } from '@/store'
-import { EChartsCycleType } from '@/constants/enum'
+import { ChartCycleType, chartCycleTypeList } from '@/constants/enum/chart'
 import AppTab from '@/components/base/tab/index.vue'
 
 const components = {
@@ -25,22 +24,12 @@ const components = {
 }
 
 const scrollEl = ref<HTMLDivElement>();
-const selectedCycleType = ref(EChartsCycleType.minutes); // 当前选中的图表周期
+const selectedCycleType = ref(ChartCycleType.minutes); // 当前选中的图表周期
 const goodsList = globalState.getRef('goodsList');
 
-const tabs = [
-  { label: '分时', value: EChartsCycleType.time },
-  { label: '1分钟', value: EChartsCycleType.minutes },
-  { label: '5分钟', value: EChartsCycleType.minutes5 },
-  { label: '30分钟', value: EChartsCycleType.minutes30 },
-  { label: '60分钟', value: EChartsCycleType.minutes60 },
-  { label: '4小时', value: EChartsCycleType.Hours4 },
-  { label: '日K', value: EChartsCycleType.days },
-]
-
 // 指标切换
 const tabChange = (index: number) => {
-  selectedCycleType.value = tabs[index].value;
+  selectedCycleType.value = chartCycleTypeList[index].value;
 }
 
 const clearGoods = () => {

+ 4 - 4
src/packages/pc/views/market/quote/components/futures/index.vue

@@ -1,12 +1,12 @@
 <template>
-    <div>这是期货动态组件</div>
+    <div>这是期货动态组件:{{ name }}</div>
 </template>
 
 <script lang="ts" setup>
 defineProps({
-    parentComponent: {
-        type: Object,
+    name: {
+        type: String,
         required: true
-    }
+    },
 })
 </script>

+ 7 - 3
src/packages/pc/views/market/quote/components/spot/index.vue

@@ -1,12 +1,16 @@
 <template>
-    <div>这是现货动态组件</div>
+    <div>这是现货动态组件:{{ selectedRow }}</div>
 </template>
 
 <script lang="ts" setup>
 defineProps({
-    parentComponent: {
-        type: Object,
+    name: {
+        type: String,
         required: true
+    },
+    selectedRow: {
+        type: Object,
+        default: () => ({})
     }
 })
 </script>

+ 1 - 11
src/packages/pc/views/market/quote/index.less

@@ -1,11 +1 @@
-.market-quote {
-    .tab {
-        display      : flex;
-        margin-bottom: 10px;
-
-        &-item {
-            margin-right: 10px;
-            cursor      : pointer;
-        }
-    }
-}
+.market-quote {}

+ 12 - 20
src/packages/pc/views/market/quote/index.vue

@@ -1,9 +1,10 @@
 <template>
   <app-view class="market-quote">
-    <app-filter @search="search" />
+    <app-filter @search="filter" />
     <!-- 表格数据 -->
     <app-table :columns="columns" :row-key="rowKey" :expand-row-keys="expands" :data="tableList"
       @row-click="rowClickExpand" @row-contextmenu="rowContextmenu">
+      <!-- 展开行 -->
       <template #expand="{ row }">
         <app-button-group :data="handleButton(row)" @click="openComponent" />
       </template>
@@ -12,46 +13,37 @@
     <el-button @click="socket.closeTradeServer()">断开交易服务</el-button>
     <!-- 底部动态组件 -->
     <template #footer>
-      <ul class="tab">
-        <li class="tab-item" v-for="(item, index) in dynamicComponents" :key="index" @click="componentChange(index)">
-          {{ item.title }}
-        </li>
-      </ul>
-      <div style="height:100px">
-        <component :is="currentTabComponent.component" :parent-component="currentTabComponent"
-          v-if="currentTabComponent"></component>
-      </div>
+      <app-tab-component :options="{ selectedRow, code: 'quote' }" />
     </template>
     <!-- 右键菜单 -->
     <app-contextmenu :data-source="handleButton(selectedRow)" @click="openComponent" />
     <!-- 弹窗组件 -->
-    <component :is="components[componentId]" :selected-row="selectedRow" @closed="closeComponent" />
+    <component :is="components[componentId]" :selected-row="selectedRow" @closed="closeComponent" v-if="componentId" />
   </app-view>
 </template>
 
 <script lang="ts" setup>
 import { defineAsyncComponent, onBeforeUnmount } from 'vue'
 import { queryGoodsList } from '@/services/api/goods'
-import { useComponent, useDynamicComponent } from '@/hooks/component'
+import { useComponent } from '@/hooks/component'
 import { useMenu } from '@/hooks/menu'
+import { addSubscribe } from '@/business/quote'
 import { useTable } from '@pc/components/base/table'
+import socket from '@/services/socket'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppContextmenu from '@pc/components/base/contextmenu/index.vue'
 import AppButtonGroup from '@pc/components/modules/button-group/index.vue'
 import AppFilter from './components/filter/index.vue'
-import socket from '@/services/socket'
-import { addSubscribe } from '@/business/quote'
+import AppTabComponent from '@/components/base/tab-component/index.vue'
 
 const components = {
   trade: defineAsyncComponent(() => import('@pc/components/modules/trade/index.vue')),
   detail: defineAsyncComponent(() => import('./components/detail/index.vue')),
 }
 
-const { tableList, columns, selectedRow, rowKey, expands, rowClickExpand, rowContextmenu, search } = useTable<Ermcp.Goods>('id');
+const { tableList, columns, selectedRow, rowKey, expands, rowClickExpand, rowContextmenu, filter } = useTable<Ermcp.Goods>('id');
 const { componentId, openComponent, closeComponent } = useComponent<typeof components>();
-const { dynamicComponents, currentTabComponent, componentChange } = useDynamicComponent();
-const { getAuth } = useMenu();
-const buttons = getAuth();
+const { auth } = useMenu();
 
 columns.value = [
   {
@@ -76,10 +68,10 @@ columns.value = [
 const handleButton = (item?: Ermcp.Goods) => {
   switch (item?.goodsCode) {
     case 'CFN001': {
-      return buttons.filter((e) => e.code !== 'detail')
+      return auth.filter((e) => e.code !== 'detail')
     }
     default: {
-      return buttons;
+      return auth;
     }
   }
 }

+ 1 - 1
src/services/socket/quote/index.ts

@@ -1,6 +1,6 @@
 import Long from 'long'
 import { Package40 } from '@/utils/websocket/package'
-import { FunCode } from '@/constants/enum'
+import { FunCode } from '@/constants/enum/funcode'
 import { QuoteRequest } from './interface'
 import { subscribeListToByteArrary } from './build/encode'
 import { parseSubscribeRsp } from './build/decode'

+ 1 - 1
src/services/socket/trade/index.ts

@@ -1,6 +1,6 @@
 import { v4 } from 'uuid'
 import { Package50 } from '@/utils/websocket/package'
-import { FunCode } from '@/constants/enum'
+import { FunCode } from '@/constants/enum/funcode'
 import { IMessageHead } from './protobuf/proto'
 import { TradeRequest, TradeResponse } from './interface'
 import Protobuf from './protobuf'

+ 1 - 1
src/types/store/cache.d.ts

@@ -1,4 +1,4 @@
-import { AppTheme, StatusBarStyle } from '@/constants/enum'
+import { AppTheme } from '@/constants/enum/theme'
 
 declare global {
     namespace Store {