| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- import { ref, computed, watch, nextTick, onMounted } from 'vue'
- import { useI18n } from 'vue-i18n'
- import Config from '@/config/index'
- import { localesList, switchAppLanguage } from '@/locale/index'
- import { lang } from '@/composables/config'
- import { useWindowWidth } from '@/composables/useWindowWidth'
- import useGlobalStore from '@/stores/use-global-store'
- import useRouter from '@/hooks/useRouter'
- import useRoute from '@/hooks/useRoute'
- import LiveChatService from '@/utils/liveChat.js'
- export interface MenuItem {
- path: string
- label: string
- icon: string
- children?: MenuItem[]
- isOpenMenu?: boolean
- submenuHeight?: number
- isExternal?: boolean
- type?: string
- lang?: string
- }
- function cloneMenu(menus: MenuItem[]): MenuItem[] {
- return menus.map(item => ({
- ...item,
- children: item.children ? cloneMenu(item.children) : [],
- isOpenMenu: item.isOpenMenu ?? false,
- // 🔥 直接按数量 × 40px
- submenuHeight: (item.children?.length || 0) * ((40 + 8)) + 8,
- }))
- }
- export function useMenuSplit(handleClick1: (item: MenuItem) => void) {
- const { locale } = useI18n()
- const globalStore = useGlobalStore()
- const mode = computed(() => globalStore.mode)
- const windowWidth = useWindowWidth(300)
- const shouldShowLanguageMenu = computed(() => windowWidth.value <= 991)
- const { host } = Config
- const router = useRouter()
- const route = useRoute()
- const submenuRefs = ref<any[]>([])
- function setSubmenuRef(index: number, el: HTMLElement | null) { }
- // 设置全局模式
- function setMode(code: string) {
- globalStore.setMode(code);
- switch (code) {
- case 'follow':
- router.reLaunch('/pages/follow/index')
- break
- case 'ib':
- router.reLaunch('/pages/ib/index')
- break
- case 'customer':
- router.reLaunch('/pages/customer/dashboard')
- // router.reLaunch('/pages/customer/index')
- break
- default:
- break
- }
- if (code === 'ib') {
- uni.$emit('open-ib')
- }
- }
- // 🔥 已删除:measureHeight
- // 🔥 已删除:updateSubmenuHeight
- let clickTimer: ReturnType<typeof setTimeout> | null = null
- function handleClick(index: number) {
- if (clickTimer) return
- clickTimer = setTimeout(() => {
- clickTimer = null
- }, 300)
- const item = menus.value[index]
- if (!item.children || item.children.length === 0) {
- // #ifdef H5
- if (item.type === 'chat' && !shouldShowLanguageMenu.value) {
- if (LiveChatService) {
- LiveChatService.showChat();
- }
- return
- } else {
- shouldShowLanguageMenu.value && handleClick1(item)
- router.push(item.path)
- return
- }
- // #endif
- shouldShowLanguageMenu.value && handleClick1(item)
- router.push(item.path)
- return
- }
- item.isOpenMenu = !item.isOpenMenu
- }
- function handleSubmenuClick(subItem: any) {
- if (subItem.type === 'lang') {
- switchAppLanguage(subItem.lang, { locale, lang })
- return
- }
- if (subItem.isExternal) {
- // #ifdef H5
- window.open(subItem.path, '_blank')
- // #endif
- // #ifdef APP-PLUS
- plus.runtime.openURL(subItem.path)
- // #endif
- return
- }
- shouldShowLanguageMenu.value && handleClick1(subItem)
- router.push(subItem.path)
- }
- const handleResize = () => { }
- const customMenuList = computed(() =>
- localesList.map((code) => ({
- label: `language.${code}`,
- lang: code,
- type: "lang",
- path: '/'
- }))
- )
- const languageMenuItem = computed<MenuItem>(() => ({
- path: '/',
- isOpenMenu: false,
- label: 'language.index',
- icon: 'cwg-lang',
- children: customMenuList.value,
- submenuHeight: customMenuList.value.length * ((40 + 8)) + 8,
- }))
- const customerBaseMenus = computed<MenuItem[]>(() => [
- {
- isOpenMenu: false,
- path: '/pages/customer/dashboard',
- label: 'Documentary.console.item1',
- icon: 'crm-mb',
- submenuHeight: 0,
- },
- {
- isOpenMenu: false,
- submenuHeight: 4 * ((40 + 8)) + 8,
- path: '/',
- label: 'Shop.Index.Transaction',
- icon: 'crm-trade',
- children: [
- { path: '/pages/customer/index', label: 'Custom.Index.AccountList', icon: 'icon-client' },
- { path: '/pages/customer/trade-history', label: 'Ib.Report.Tit1', icon: 'icon-transfer' },
- { path: '/pages/customer/trade-position', label: 'Ib.Report.Tit4', icon: 'icon-transfer' },
- { path: '/pages/customer/recording-history', label: 'Home.page_customer.item7', icon: 'icon-application' },
- ],
- },
- {
- isOpenMenu: false,
- submenuHeight: 6 * ((40 + 8)) + 8,
- path: '/',
- label: 'vu.item6',
- icon: 'crm-payment',
- children: [
- { path: '/pages/customer/deposit-select', label: 'Home.page_customer.item2', icon: 'icon-deposit' },
- { path: '/pages/customer/withdrawal-select', label: 'Home.page_customer.item3', icon: 'icon-withdrawal' },
- { path: '/pages/customer/payment-history', label: 'Home.page_customer.item4', icon: 'icon-payment' },
- { path: '/pages/customer/transfer', label: 'Custom.Index.Transfer', icon: 'icon-transfer' },
- { path: '/pages/customer/wallet-transfer', label: 'wallet.item62', icon: 'icon-transfer' },
- { path: '/pages/customer/wallet-history', label: 'wallet.item7', icon: 'icon-transfer' },
- ],
- },
- {
- path: '/pages/activities/index',
- isOpenMenu: false,
- label: 'Home.page_customer.item6',
- icon: 'crm-hd',
- children: [],
- submenuHeight: 0,
- },
- {
- path: '/',
- isOpenMenu: false,
- submenuHeight: 2 * ((40 + 8)) + 8,
- label: 'vu.item5',
- icon: 'crm-chart-area',
- children: [
- { path: '/pages/analytics/analystViews', label: 'News.Announcement', icon: 'icon-application' },
- { path: '/pages/analytics/news', label: 'News.NewsInformation', icon: 'icon-application' },
- ],
- },
- // {
- // path: '/pages/common/download',
- // isOpenMenu: false,
- // label: 'Downloadpage.item1',
- // icon: 'crm-download',
- // children: [],
- // submenuHeight: 0,
- // },
- // {
- // path: '/pages/common/chat',
- // isOpenMenu: false,
- // label: 'Downloadpage.item16',
- // icon: 'crm-headset',
- // children: [],
- // type: 'chat',
- // submenuHeight: 0,
- // },
- {
- path: '/',
- isOpenMenu: false,
- submenuHeight: 5 * ((40 + 8)) + 8,
- label: 'Custom.Index.Settings',
- icon: 'crm-sz',
- children: [
- { path: '/pages/mine/info?type=1', label: 'PersonalManagement.Title.PersonalInformation', icon: 'crm-headset' },
- { path: '/pages/mine/info?type=2', label: 'PersonalManagement.Title.BankInformation', icon: 'crm-headset' },
- { path: '/pages/mine/info?type=3', label: 'PersonalManagement.Title.FileManagement', icon: 'crm-headset' },
- { path: '/pages/mine/info?type=4', label: 'PersonalManagement.Title.SecurityCenter', icon: 'crm-headset' },
- { path: '/pages/common/notice', label: 'News.Notice', icon: 'crm-headset' },
- ],
- },
- ])
- const ibBaseMenus = computed<MenuItem[]>(() => [
- {
- isOpenMenu: false,
- path: '/pages/ib/index',
- label: 'Documentary.console.item1',
- icon: 'crm-mb',
- submenuHeight: 0,
- },
- {
- path: '/',
- label: 'Ib.Custom.Manage3',
- icon: 'crm-bg',
- submenuHeight: 4 * ((40 + 8)) + 8,
- children: [
- { path: '/pages/ib/customer', label: 'Ib.Custom.Manage3', icon: 'icon-deposit' },
- { path: '/pages/ib/subsList', label: 'Ib.Custom.Manage2', icon: 'icon-deposit' },
- // { path: '/pages/ib/agentList', label: 'Documentary.console.item23', icon: 'icon-deposit' },
- { path: '/pages/ib/accountList', label: 'Ib.Custom.Manage1', icon: 'icon-deposit' }
- ],
- },
- {
- isOpenMenu: false,
- submenuHeight: 4 * ((40 + 8)) + 8,
- path: '/',
- label: 'vu.item6',
- icon: 'crm-payment',
- children: [
- { path: '/pages/ib/transfer', label: 'Home.page_ib.item4', icon: 'icon-payment' },
- { path: '/pages/ib/withdraw-select', label: 'Home.page_ib.item5', icon: 'icon-transfer' },
- { path: '/pages/ib/agent-transfer', label: 'Home.page_ib.item9', icon: 'icon-transfer' },
- { path: '/pages/ib/recording', label: 'Home.page_ib.item7', icon: 'icon-application' },
- ],
- },
- {
- isOpenMenu: false,
- submenuHeight: 2 * ((40 + 8)) + 8,
- path: '/',
- label: 'Home.page_ib.item3',
- icon: 'crm-newspaper',
- children: [
- // { path: '/pages/ib/report', label: 'Home.page_ib.item3', icon: 'icon-withdrawal' },
- { path: '/pages/ib/complexReport', label: 'Home.page_ib.item11', icon: 'icon-withdrawal' },
- { path: '/pages/ib/reportTrade?detailType=4', label: 'Ib.Report.Tit4', icon: 'icon-withdrawal' },
- { path: '/pages/ib/reportTrade?detailType=1', label: 'Ib.Report.Tit1', icon: 'icon-withdrawal' },
- { path: '/pages/ib/report?type=1', label: 'Ib.Report.Title1', icon: 'icon-withdrawal' },
- { path: '/pages/ib/report?type=2', label: 'Ib.Report.Title2', icon: 'icon-withdrawal' },
- { path: '/pages/ib/report?type=3', label: 'Ib.Report.Title3', icon: 'icon-withdrawal' },
- { path: '/pages/ib/report?type=6', label: 'news_add_field.IbReport.Title6', icon: 'icon-withdrawal' },
- ],
- },
- // 推广
- // {
- // isOpenMenu: false,
- // path: '/',
- // label: 'Home.page_ib.item12',
- // icon: 'crm-bulletin',
- // submenuHeight: 1 * ((40 + 8)) + 8,
- // children: [
- // { path: '/pages/ib/promotion', label: 'Home.page_ib.item13', icon: 'icon-withdrawal' },
- // ],
- // },
- ])
- const followBaseMenus = computed<MenuItem[]>(() => [
- {
- isOpenMenu: false,
- path: '/pages/follow/index',
- label: 'Documentary.console.item1',
- icon: 'crm-mb',
- submenuHeight: 0,
- },
- {
- isOpenMenu: false,
- path: '/pages/follow/trading-center',
- label: 'Documentary.page_doc.item2',
- icon: 'crm-gd',
- submenuHeight: 0,
- },
- {
- isOpenMenu: false,
- submenuHeight: 1 * ((40 + 8)) + 8,
- path: '/',
- label: 'Documentary.page_doc.item3',
- icon: 'crm-newspaper',
- children: [
- { path: '/pages/follow/report', label: 'Documentary.page_doc.item3', icon: 'icon-client' },
- ],
- },
- {
- isOpenMenu: false,
- submenuHeight: 2 * ((40 + 8)) + 8,
- path: '/',
- label: 'Documentary.page_doc.item4',
- icon: 'crm-payment',
- children: [
- { path: '/pages/follow/transfer', label: 'Documentary.TundManagement.item2', icon: 'icon-client' },
- { path: '/pages/follow/transfer-history', label: 'Documentary.TundManagement.item3', icon: 'icon-transfer' }
- ],
- },
- {
- isOpenMenu: false,
- submenuHeight: 5 * ((40 + 8)) + 8,
- path: '/',
- label: 'Documentary.page_doc.item5',
- icon: 'crm-trade',
- children: [
- { path: '/pages/follow/trading-management', label: 'Documentary.TundManagement.item11', icon: 'icon-client' },
- { path: '/pages/follow/follow-list', label: 'Documentary.TundManagement.item17', icon: 'icon-client' },
- { path: '/pages/follow/account-management', label: 'Documentary.TundManagement.item9', icon: 'icon-transfer' },
- { path: '/pages/follow/subscribe-list', label: 'Documentary.TundManagement.item45', icon: 'icon-transfer' },
- { path: '/pages/follow/record', label: 'Documentary.TundManagement.item10', icon: 'icon-transfer' }
- ],
- },
- ])
- const menus = ref<MenuItem[]>([])
- watch(mode, (newMode, oldMode) => {
- if (newMode !== oldMode) {
- let base: MenuItem[] = []
- switch (newMode) {
- case 'follow': base = [...followBaseMenus.value]; break
- case 'ib': base = [...ibBaseMenus.value]; break
- case 'customer': base = [...customerBaseMenus.value]; break
- default: break
- }
- if (shouldShowLanguageMenu.value) base.push(languageMenuItem.value)
- menus.value = cloneMenu(base)
- }
- }, { immediate: true })
- watch(route, () => {
- const currentPath = route.path
- menus.value.forEach((item, idx) => {
- if (item.children?.length) {
- const isActive = item.children.some(child => {
- if (child.isExternal || child.type === 'lang') return false
- return currentPath === child.path || currentPath.startsWith(child.path + '?')
- })
- if (isActive) item.isOpenMenu = true
- }
- })
- }, { immediate: true })
- onMounted(() => { })
- return {
- menus,
- mode,
- shouldShowLanguageMenu,
- windowWidth,
- setMode,
- setSubmenuRef,
- handleClick,
- handleSubmenuClick,
- }
- }
|