diff --git a/app/View/Presenters/Menu.php b/app/View/Presenters/Menu.php index 78f4369f..a5420f31 100644 --- a/app/View/Presenters/Menu.php +++ b/app/View/Presenters/Menu.php @@ -37,6 +37,7 @@ class Menu extends Presenter return '
  • getAttributes() . '> ' . $this->getIcon($item) . ' + ' . $this->getActiveIndicator($item) . ' ' . $item->title . ' @@ -231,6 +232,15 @@ class Menu extends Presenter ' . PHP_EOL; } + public function getActiveIndicator($item) + { + if (! $item->isActive() || ! empty($item->icon)) { + return ''; + } + + return ''; + } + public function getChevron($item) { $state = $this->chevronState($item); diff --git a/presets.js b/presets.js index 0a02099d..1faf2993 100644 --- a/presets.js +++ b/presets.js @@ -3,9 +3,10 @@ const defaultTheme = require('tailwindcss/defaultTheme') const fontFamily = defaultTheme.fontFamily; fontFamily['sans'] = [ - 'Quicksand', // <-- Quicksand is default sans font now - 'system-ui', - // <-- Can provide more font fallbacks here + 'JetBrains Mono', + 'Microsoft YaHei', + 'PingFang SC', + 'monospace', ]; module.exports = { diff --git a/public/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2 b/public/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2 new file mode 100644 index 00000000..4917f434 Binary files /dev/null and b/public/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2 differ diff --git a/public/fonts/jetbrains-mono/JetBrainsMono-ExtraLight.woff2 b/public/fonts/jetbrains-mono/JetBrainsMono-ExtraLight.woff2 new file mode 100644 index 00000000..b97239f3 Binary files /dev/null and b/public/fonts/jetbrains-mono/JetBrainsMono-ExtraLight.woff2 differ diff --git a/public/fonts/jetbrains-mono/JetBrainsMono-Light.woff2 b/public/fonts/jetbrains-mono/JetBrainsMono-Light.woff2 new file mode 100644 index 00000000..65384987 Binary files /dev/null and b/public/fonts/jetbrains-mono/JetBrainsMono-Light.woff2 differ diff --git a/public/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 b/public/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 new file mode 100644 index 00000000..669d04cd Binary files /dev/null and b/public/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 differ diff --git a/public/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 b/public/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 new file mode 100644 index 00000000..40da4276 Binary files /dev/null and b/public/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 differ diff --git a/resources/assets/js/views/business/pages.js b/resources/assets/js/views/business/pages.js index e194e66e..0650e9bf 100644 --- a/resources/assets/js/views/business/pages.js +++ b/resources/assets/js/views/business/pages.js @@ -16,9 +16,10 @@ import TaobaoAlipayBills from './../../components/business/TaobaoAlipayBills.vue import AccountBills from './../../components/business/AccountBills.vue'; const GENERIC_TABS = ['taobao-wechat', 'pinduoduo', 'jd-wallet', 'jd-transactions', 'douyin', 'dewu']; +const STORE_RECEIVING_TABS = ['taobao-alipay', ...GENERIC_TABS]; -function pageContext() { - const parts = (window.location.pathname || '').split('/').filter(Boolean); +function pageContext(pathname = window.location.pathname) { + const parts = (pathname || '').split('/').filter(Boolean); const idx = parts.indexOf('workspace'); if (idx === -1) { @@ -33,25 +34,22 @@ function pageContext() { }; } -const { companyId, page, tab } = pageContext(); +function resolveComponent(context) { + const alipayBase = context.companyId + ? `/${context.companyId}/ecommerce-finance/alipay-bills` + : '/ecommerce-finance/alipay-bills'; + const accountBase = context.companyId + ? `/${context.companyId}/ecommerce-finance/account-bills` + : '/ecommerce-finance/account-bills'; -const alipayBase = companyId - ? `/${companyId}/ecommerce-finance/alipay-bills` - : '/ecommerce-finance/alipay-bills'; - -const accountBase = companyId - ? `/${companyId}/ecommerce-finance/account-bills` - : '/ecommerce-finance/account-bills'; - -function resolveComponent() { // 店铺收款账户账单 › 淘系支付宝账户(独立实现) - if (page === 'store-receiving-bills' && tab === 'taobao-alipay') { + if (context.page === 'store-receiving-bills' && context.tab === 'taobao-alipay') { return { Component: TaobaoAlipayBills, props: { apiBase: alipayBase } }; } // 店铺收款账户账单 › 其它账户类型(通用实现) - if (page === 'store-receiving-bills' && GENERIC_TABS.indexOf(tab) !== -1) { - return { Component: AccountBills, props: { apiBase: accountBase, billType: tab } }; + if (context.page === 'store-receiving-bills' && GENERIC_TABS.indexOf(context.tab) !== -1) { + return { Component: AccountBills, props: { apiBase: accountBase, billType: context.tab } }; } return null; @@ -60,18 +58,89 @@ function resolveComponent() { const mount = document.querySelector('.business-blank-page'); if (mount) { - const resolved = resolveComponent(); + const initialContext = pageContext(); + + function isStoreReceivingContext(context) { + return context.page === 'store-receiving-bills' + && STORE_RECEIVING_TABS.indexOf(context.tab) !== -1; + } + + function updateActiveTab(tab) { + document.querySelectorAll('.business-tab-link').forEach((link) => { + const linkContext = pageContext(new URL(link.href, window.location.origin).pathname); + const isActive = linkContext.tab === tab; + + link.classList.toggle('is-active', isActive); + + if (isActive) { + link.setAttribute('aria-current', 'page'); + } else { + link.removeAttribute('aria-current'); + } + }); + } /* eslint-disable no-new */ - new Vue({ + const workspace = new Vue({ el: mount, + data: { + context: initialContext, + }, render(h) { + const resolved = resolveComponent(this.context); + if (resolved) { - return h(resolved.Component, { props: resolved.props }); + return h(resolved.Component, { + key: this.context.tab, + props: resolved.props, + }); } return h('div', { class: 'business-page-empty' }, '该页面尚未实现'); }, }); + + function navigate(url, pushState = true) { + const target = new URL(url, window.location.origin); + const nextContext = pageContext(target.pathname); + + if (target.origin !== window.location.origin || !isStoreReceivingContext(nextContext)) { + return false; + } + + if (pushState && target.pathname !== window.location.pathname) { + window.history.pushState({}, '', `${target.pathname}${target.search}${target.hash}`); + } + + workspace.context = nextContext; + updateActiveTab(nextContext.tab); + + return true; + } + + document.addEventListener('click', (event) => { + const link = event.target.closest('.business-tab-link'); + + if (!link + || event.defaultPrevented + || event.button !== 0 + || event.metaKey + || event.ctrlKey + || event.shiftKey + || event.altKey + ) { + return; + } + + if (navigate(link.href)) { + event.preventDefault(); + } + }); + + window.addEventListener('popstate', () => { + navigate(window.location.href, false); + }); + + updateActiveTab(initialContext.tab); } diff --git a/resources/assets/sass/app.css b/resources/assets/sass/app.css index 9b590813..ac9cad55 100644 --- a/resources/assets/sass/app.css +++ b/resources/assets/sass/app.css @@ -1,6 +1,46 @@ @import url("../../../public/css/third_party/vue-html-editor_custom.css"); @import url("../../../public/css/third_party/dropzone_custom.css"); +@font-face { + font-family: "JetBrains Mono"; + src: url("/public/fonts/jetbrains-mono/JetBrainsMono-ExtraLight.woff2") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 200; +} + +@font-face { + font-family: "JetBrains Mono"; + src: url("/public/fonts/jetbrains-mono/JetBrainsMono-Light.woff2") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 300; +} + +@font-face { + font-family: "JetBrains Mono"; + src: url("/public/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 400; +} + +@font-face { + font-family: "JetBrains Mono"; + src: url("/public/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 500; +} + +@font-face { + font-family: "JetBrains Mono"; + src: url("/public/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 700; +} + @tailwind base; @tailwind components; @tailwind utilities; @@ -102,12 +142,12 @@ .menu-scroll::-webkit-scrollbar-track { border-radius: 10px; - background-color: #fcfcfc; + background-color: #EEE9DF; } .menu-scroll::-webkit-scrollbar-thumb { border-radius: 10px; - background-color: #DCE2F9; + background-color: #B9954F; } .menu-list ul svg { @@ -259,8 +299,6 @@ --vip-rail-bg: #050506; --vip-rail-gold: #F2E7C5; --vip-sidebar-bg: #1D1D1F; - --vip-sidebar-text: #F5F0E6; - --vip-sidebar-text-soft: #E7E0D2; --vip-sidebar-gold: #F0E4BF; --vip-sidebar-gold-soft: #DDD0AA; --vip-sidebar-active: #2A2927; @@ -269,6 +307,8 @@ --vip-content-accent-soft: #F7F0DE; --vip-content-accent-dark: #856632; --vip-border: #D8D2C7; + scrollbar-color: #B9954F #EEE9DF; + scrollbar-width: thin; } body { @@ -290,7 +330,7 @@ body { .finance-theme-sidebar { background-color: var(--vip-sidebar-bg) !important; - color: var(--vip-sidebar-text); + color: var(--vip-sidebar-gold); } .finance-theme-sidebar .text-purple, @@ -298,12 +338,12 @@ body { .finance-theme-sidebar a, .finance-theme-sidebar button, .finance-theme-sidebar summary { - color: var(--vip-sidebar-text) !important; + color: var(--vip-sidebar-gold) !important; } .finance-theme-sidebar .menu__submenu a, .finance-theme-sidebar .menu__submenu .text-purple { - color: var(--vip-sidebar-text-soft) !important; + color: var(--vip-sidebar-gold) !important; } .finance-theme-sidebar .material-icons, @@ -312,6 +352,11 @@ body { color: var(--vip-sidebar-gold) !important; } +.finance-theme-toggle, +.finance-theme-toggle .material-icons { + color: var(--vip-sidebar-gold) !important; +} + .finance-theme-sidebar .main-menu .menu__submenu a, .finance-theme-sidebar .main-menu .menu__submenu summary > div { font-size: 0.75rem !important; @@ -326,6 +371,22 @@ body { border-radius: 0.25rem; } +.finance-theme-sidebar .menu-active-indicator { + display: inline-flex; + flex: 0 0 auto; + align-items: center; + justify-content: center; + width: 1rem; + height: 1rem; + margin-inline-end: 0.35rem; + border: 1px solid rgba(246, 233, 194, 0.72); + border-radius: 999px; + background-color: rgba(246, 233, 194, 0.14); + color: #F6E9C2 !important; + font-size: 0.875rem !important; + line-height: 1rem !important; +} + .finance-theme-sidebar .main-menu a:hover, .finance-theme-sidebar .main-menu summary:hover > div { background-color: rgba(240, 228, 191, 0.10); @@ -366,6 +427,47 @@ body { background-color: rgba(242, 231, 197, 0.24); } +*::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +*::-webkit-scrollbar-track { + background-color: #EEE9DF; +} + +*::-webkit-scrollbar-thumb { + border: 2px solid #EEE9DF; + border-radius: 999px; + background-color: #B9954F; +} + +*::-webkit-scrollbar-thumb:hover { + background-color: #A17D3E; +} + +.finance-theme-rail, +.finance-theme-sidebar, +.finance-theme-rail .menu-scroll, +.finance-theme-sidebar.menu-scroll { + scrollbar-color: #D7C58F transparent; +} + +.finance-theme-rail::-webkit-scrollbar-track, +.finance-theme-sidebar::-webkit-scrollbar-track, +.finance-theme-rail .menu-scroll::-webkit-scrollbar-track, +.finance-theme-sidebar.menu-scroll::-webkit-scrollbar-track { + background-color: transparent; +} + +.finance-theme-rail::-webkit-scrollbar-thumb, +.finance-theme-sidebar::-webkit-scrollbar-thumb, +.finance-theme-rail .menu-scroll::-webkit-scrollbar-thumb, +.finance-theme-sidebar.menu-scroll::-webkit-scrollbar-thumb { + border-color: transparent; + background-color: #D7C58F; +} + .finance-theme-sidebar .bg-purple { background-color: #F6E9C2 !important; } @@ -941,7 +1043,7 @@ form { body { @apply text-black; - font-family: "Quicksand", sans-serif; + font-family: "JetBrains Mono", "Microsoft YaHei", "PingFang SC", monospace; height: 100%; } diff --git a/resources/views/components/layouts/admin/footer.blade.php b/resources/views/components/layouts/admin/footer.blade.php index afdc4443..e4ead882 100644 --- a/resources/views/components/layouts/admin/footer.blade.php +++ b/resources/views/components/layouts/admin/footer.blade.php @@ -1,16 +1,2 @@ @stack('footer_start') - @stack('footer_end') diff --git a/resources/views/components/layouts/admin/menu.blade.php b/resources/views/components/layouts/admin/menu.blade.php index cfa3a55e..d90e3c86 100644 --- a/resources/views/components/layouts/admin/menu.blade.php +++ b/resources/views/components/layouts/admin/menu.blade.php @@ -250,11 +250,11 @@ @stack('add_new_menu_end') - - + diff --git a/resources/views/components/layouts/auth/footer.blade.php b/resources/views/components/layouts/auth/footer.blade.php index 418fbe68..e4ead882 100644 --- a/resources/views/components/layouts/auth/footer.blade.php +++ b/resources/views/components/layouts/auth/footer.blade.php @@ -1,12 +1,2 @@ @stack('footer_start') - @stack('footer_end') diff --git a/resources/views/components/layouts/portal/footer.blade.php b/resources/views/components/layouts/portal/footer.blade.php index 57813563..e4ead882 100644 --- a/resources/views/components/layouts/portal/footer.blade.php +++ b/resources/views/components/layouts/portal/footer.blade.php @@ -1,15 +1,2 @@ @stack('footer_start') - @stack('footer_end') diff --git a/resources/views/components/layouts/preview/footer.blade.php b/resources/views/components/layouts/preview/footer.blade.php index 7996486a..e4ead882 100644 --- a/resources/views/components/layouts/preview/footer.blade.php +++ b/resources/views/components/layouts/preview/footer.blade.php @@ -1,18 +1,2 @@ @stack('footer_start') - - - @stack('footer_end') diff --git a/resources/views/components/layouts/signed/footer.blade.php b/resources/views/components/layouts/signed/footer.blade.php index 7996486a..e4ead882 100644 --- a/resources/views/components/layouts/signed/footer.blade.php +++ b/resources/views/components/layouts/signed/footer.blade.php @@ -1,18 +1,2 @@ @stack('footer_start') - - - @stack('footer_end')