Files
kt-financial-system/apps/web-antd/src/app.vue
woshiqp465 1e42191296 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>
2025-10-04 21:14:21 +08:00

157 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import { computed, onMounted, watch } from 'vue';
import { useAntdDesignTokens } from '@vben/hooks';
import { preferences, usePreferences } from '@vben/preferences';
import { App, ConfigProvider, theme } from 'ant-design-vue';
import { antdLocale } from '#/locales';
defineOptions({ name: 'App' });
const { isDark } = usePreferences();
const { tokens } = useAntdDesignTokens();
const tokenTheme = computed(() => {
const algorithm = isDark.value
? [theme.darkAlgorithm]
: [theme.defaultAlgorithm];
// antd 紧凑模式算法
if (preferences.app.compact) {
algorithm.push(theme.compactAlgorithm);
}
return {
algorithm,
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>
<ConfigProvider :locale="antdLocale" :theme="tokenTheme">
<App>
<RouterView />
</App>
</ConfigProvider>
</template>
<style>
/* Styles can be added here if needed */
</style>