li.shaoyi 3 tahun lalu
induk
melakukan
0d6e28fe22

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

@@ -116,7 +116,7 @@ export function useMenu(authCode?: string) {
      * @param reverse 
      * @returns 
      */
-    const getAuthButton = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Button, filtered, reverse)
+    const getAuthButtons = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Button, filtered, reverse)
 
     /**
      * 获取权限组件
@@ -124,7 +124,7 @@ export function useMenu(authCode?: string) {
      * @param reverse 
      * @returns 
      */
-    const getAuthComponent = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Component, filtered, reverse)
+    const getAuthComponents = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Component, filtered, reverse)
 
     return {
         route,
@@ -133,7 +133,7 @@ export function useMenu(authCode?: string) {
         componentMap,
         getMenus,
         getChildrenMenus,
-        getAuthButton,
-        getAuthComponent,
+        getAuthButtons,
+        getAuthComponents,
     }
 }

+ 108 - 0
src/packages/pc/components/base/menu-group/index.vue

@@ -0,0 +1,108 @@
+<template>
+    <div class="app-menu-group">
+        <teleport to="body" v-if="type === 'contextmenu'">
+            <div class="app-menu-group__contextmenu" @contextmenu.prevent.capture @click="closeContextmenu"
+                v-show="contextmenuOptions.show">
+                <ul :style="styles">
+                    <li :class="item.code" v-for="(item, index) in menus" :key="index"
+                        @click.stop="onClick(item, index)">
+                        <el-icon v-if="item.icon">
+                            <component :is="item.icon" />
+                        </el-icon>
+                        <span>{{ item.title }}</span>
+                    </li>
+                </ul>
+            </div>
+        </teleport>
+        <el-dropdown class="app-menu-group__dropdown" v-else-if="type === 'dropdown'">
+            <el-button type="info" icon="Setting" />
+            <template #dropdown>
+                <el-dropdown-menu>
+                    <el-dropdown-item :class="item.code" v-for="(item, index) in menus" :key="index" :icon="item.icon"
+                        @click="onClick(item, index)">
+                        {{ item.title }}
+                    </el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+        </el-dropdown>
+        <div class="app-menu-group__btnbar" v-else>
+            <template v-for="(item, index) in menus" :key="index">
+                <el-button :class="item.code" :type="item.buttonType" :disabled="activeName === item.code"
+                    @click="onClick(item, index)" :link="linkButton">
+                    <el-icon v-if="item.icon">
+                        <component :is="item.icon" />
+                    </el-icon>
+                    <span v-if="item.title">{{ item.title }}</span>
+                </el-button>
+            </template>
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed, watch, PropType } from 'vue'
+
+interface ActionMenu {
+    name: string;
+    label: string;
+    type?: string;
+    className?: string;
+    icon?: string;
+    disabled?: boolean;
+    hide?: boolean;
+}
+
+const props = defineProps({
+    // 操作菜单
+    menus: {
+        type: Array as PropType<Ermcp.UserMenu[]>,
+        required: true,
+    },
+    // 操作类型
+    type: {
+        type: String as PropType<'button' | 'dropdown' | 'contextmenu'>,
+        default: 'button',
+    },
+    // 右键菜单
+    contextmenu: {
+        type: Object as PropType<{ show: boolean; clientX: number; clientY: number; }>,
+        default: () => ({
+            show: false,
+            clientX: 0,
+            clientY: 0,
+        }),
+    },
+    // 链接按钮
+    linkButton: {
+        type: Boolean,
+        default: false,
+    },
+    options: Object
+})
+
+const emit = defineEmits(['click'])
+const contextmenuOptions = shallowRef(props.contextmenu)
+const activeName = shallowRef('')
+
+// 右键菜单坐标
+const styles = computed(() => {
+    const { clientX, clientY } = contextmenuOptions.value
+    return {
+        left: clientX + 'px',
+        top: clientY + 'px',
+    }
+})
+
+// 关闭右键菜单
+const closeContextmenu = () => {
+    contextmenuOptions.value.show = false
+}
+
+const onClick = (item: Ermcp.UserMenu, index: number) => {
+    activeName.value = item.code
+    closeContextmenu()
+    emit('click', activeName.value, props.options, index)
+}
+
+watch(() => props.contextmenu, (options) => contextmenuOptions.value = options)
+</script>

+ 2 - 2
src/packages/pc/components/modules/auth-component/index.vue

@@ -40,7 +40,7 @@ const props = defineProps({
     },
 })
 
-const { componentMap, getAuthComponent } = useMenu(props.code)
+const { componentMap, getAuthComponents } = useMenu(props.code)
 const { onChange } = useAttrs()
 const componentId = shallowRef<string>()
 const dataList = shallowRef<Ermcp.UserMenu[]>([]) // 数据列表
@@ -56,7 +56,7 @@ const onTabChange = (code: string) => {
 }
 
 onMounted(() => {
-    const auth = getAuthComponent();
+    const auth = getAuthComponents();
 
     if (props.tabs.length) {
         dataList.value = auth.filter((e) => props.tabs.includes(e.code))

+ 2 - 2
src/packages/pc/components/modules/auth-operation/index.vue

@@ -79,7 +79,7 @@ const props = defineProps({
     },
 })
 
-const { componentMap, getAuthButton } = useMenu(props.code);
+const { componentMap, getAuthButtons } = useMenu(props.code);
 const componentId = shallowRef<string>();
 const contextmenuOption = shallowRef(props.contextmenu);
 const auth = shallowRef<Ermcp.UserMenu[]>([]);
@@ -126,7 +126,7 @@ const closeComponent = (isCallback?: boolean) => {
 
 watch(() => props.contextmenu, (val) => contextmenuOption.value = val)
 
-onMounted(() => auth.value = getAuthButton())
+onMounted(() => auth.value = getAuthButtons())
 onUnmounted(() => closeComponent())
 onDeactivated(() => closeComponent())
 </script>

+ 2 - 2
src/packages/pc/views/trade/buy/components/details/index.vue

@@ -24,7 +24,7 @@
                 <div>履约规则</div>
                 <app-performance-rule :item="getPerformanceTemplateById(selectedRow.performancetemplateid)" />
             </div>
-            <template v-for="(auth, index) in getAuthComponent()" :key="index">
+            <template v-for="(auth, index) in getAuthComponents()" :key="index">
                 <component :is="componentMap.get(auth.code)" v-bind="{ selectedRow }" v-if="showComponent" />
             </template>
         </app-view>
@@ -46,7 +46,7 @@ const props = defineProps({
 })
 
 const { getUserId } = useLoginStore()
-const { componentMap, getAuthComponent } = useMenu(props.code)
+const { componentMap, getAuthComponents } = useMenu(props.code)
 const { getPerformanceTemplateById } = usePerformanceStore()
 
 // 不能购买自己发布的求购