refactor: 整合财务系统到主应用并重构后端架构
主要变更: - 将独立的 web-finance 应用整合到 web-antd 主应用中 - 重命名 backend-mock 为 backend,增强后端功能 - 新增财务模块 API 端点(账户、预算、类别、交易) - 增强财务仪表板和报表功能 - 添加 SQLite 数据存储支持和财务数据导入脚本 - 优化路由结构,删除冗余的 finance-system 模块 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
|
||||
import { useAntdDesignTokens } from '@vben/hooks';
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
@@ -28,6 +28,119 @@ const tokenTheme = computed(() => {
|
||||
token: tokens,
|
||||
};
|
||||
});
|
||||
|
||||
// Function to flatten FinWise Pro menu
|
||||
const flattenFinWiseProMenu = () => {
|
||||
const submenus = document.querySelectorAll('.vben-sub-menu');
|
||||
let finwiseMenu: Element | null = null;
|
||||
|
||||
submenus.forEach(menu => {
|
||||
const titleEl = menu.querySelector('.vben-sub-menu-content__title');
|
||||
if (titleEl?.textContent?.includes('FinWise Pro')) {
|
||||
finwiseMenu = menu;
|
||||
}
|
||||
});
|
||||
|
||||
if (!finwiseMenu) return;
|
||||
|
||||
const parentMenu = finwiseMenu.parentElement;
|
||||
const childrenUL = finwiseMenu.querySelector('.vben-menu');
|
||||
|
||||
if (!childrenUL || !parentMenu) return;
|
||||
|
||||
// Check if already processed
|
||||
if ((finwiseMenu as HTMLElement).getAttribute('data-hide-finwise') === 'true') return;
|
||||
|
||||
// Move all children to the parent menu
|
||||
const children = Array.from(childrenUL.children);
|
||||
children.forEach(child => {
|
||||
parentMenu.insertBefore(child, finwiseMenu);
|
||||
});
|
||||
|
||||
// Mark for hiding via CSS and hide directly
|
||||
(finwiseMenu as HTMLElement).setAttribute('data-hide-finwise', 'true');
|
||||
(finwiseMenu as HTMLElement).style.display = 'none';
|
||||
};
|
||||
|
||||
// Run on mount and watch for route changes
|
||||
onMounted(() => {
|
||||
// 强制修复sidebar设置,防止被用户UI操作覆盖
|
||||
const fixSidebarPreferences = () => {
|
||||
const prefsKey = Object.keys(localStorage).find(k => k.includes('preferences') && !k.includes('locale') && !k.includes('theme'));
|
||||
if (prefsKey) {
|
||||
try {
|
||||
const prefs = JSON.parse(localStorage.getItem(prefsKey) || '{}');
|
||||
if (prefs.value?.sidebar) {
|
||||
// 强制设置侧边栏为展开状态
|
||||
prefs.value.sidebar.collapsed = false;
|
||||
prefs.value.sidebar.expandOnHover = false;
|
||||
prefs.value.sidebar.collapsedButton = false;
|
||||
prefs.value.sidebar.collapsedWidth = 230;
|
||||
localStorage.setItem(prefsKey, JSON.stringify(prefs));
|
||||
}
|
||||
} catch(e) {
|
||||
console.error('Failed to fix sidebar preferences:', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 立即执行一次
|
||||
fixSidebarPreferences();
|
||||
|
||||
// Run multiple times with increasing delays to catch menu rendering
|
||||
const delays = [100, 300, 500, 1000, 1500, 2000, 2500, 3000, 4000, 5000];
|
||||
delays.forEach(delay => {
|
||||
setTimeout(flattenFinWiseProMenu, delay);
|
||||
});
|
||||
|
||||
// Watch for DOM changes (when menu is re-rendered)
|
||||
const observer = new MutationObserver(() => {
|
||||
setTimeout(flattenFinWiseProMenu, 200);
|
||||
});
|
||||
|
||||
// Observe the body for menu changes
|
||||
setTimeout(() => {
|
||||
const body = document.body;
|
||||
if (body) {
|
||||
observer.observe(body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
|
||||
// 防止侧边栏自动收起
|
||||
setTimeout(() => {
|
||||
const preventSidebarCollapse = () => {
|
||||
const sidebar = document.querySelector('[class*="sidebar"]') || document.querySelector('aside');
|
||||
|
||||
if (!sidebar) return;
|
||||
|
||||
// 创建MutationObserver监听class和style变化
|
||||
const sidebarObserver = new MutationObserver(() => {
|
||||
const currentWidth = window.getComputedStyle(sidebar).width;
|
||||
// 如果宽度小于200px,说明可能被收起了,强制恢复
|
||||
if (parseInt(currentWidth) < 200) {
|
||||
(sidebar as HTMLElement).style.width = '230px';
|
||||
}
|
||||
});
|
||||
|
||||
// 开始观察
|
||||
sidebarObserver.observe(sidebar, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class', 'style']
|
||||
});
|
||||
|
||||
// 强制设置初始宽度
|
||||
(sidebar as HTMLElement).style.width = '230px';
|
||||
};
|
||||
|
||||
// 延迟执行,等待侧边栏渲染
|
||||
setTimeout(preventSidebarCollapse, 500);
|
||||
setTimeout(preventSidebarCollapse, 1000);
|
||||
setTimeout(preventSidebarCollapse, 2000);
|
||||
}, 200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -37,3 +150,7 @@ const tokenTheme = computed(() => {
|
||||
</App>
|
||||
</ConfigProvider>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
/* Styles can be added here if needed */
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user