我被钓鱼网站骗了骗取建设信用卡建设银行会怎么处理钱会还回吗wordpress缓存首页不正常
我被钓鱼网站骗了骗取建设信用卡建设银行会怎么处理钱会还回吗,wordpress缓存首页不正常,九年级上册信息技术做网站,建设工程人员信息网官网当然其实这种组件太多了#xff0c;有非常多开源的后台管理库#xff0c;为什么再实现一遍#xff0c;主要还是想要自主可控#xff0c;虽然是让 AI 写的#xff0c;但是我让它实现的是一个 vue3组件#xff0c;复用性非常好#xff0c;可以和我的应用无缝集成#xff…当然其实这种组件太多了有非常多开源的后台管理库为什么再实现一遍主要还是想要自主可控虽然是让 AI 写的但是我让它实现的是一个 vue3组件复用性非常好可以和我的应用无缝集成而且我是实现给它看了我后台的菜单数据结构这样和我的数据兼容性就非常好下面是组件代码直接一个 html 就可以运行!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleVue3 多级菜单组件 - 流畅版/title script srchttps://unpkg.com/vue3/dist/vue.global.js/script style * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif; background: #f5f7fa; } .app-container { display: flex; height: 100vh; overflow: hidden; } /* 侧边栏 */ .sidebar { height: 100vh; background: linear-gradient(180deg, #1a1f2e 0%, #0f1419 100%); color: #fff; overflow-x: hidden; overflow-y: auto; box-shadow: 4px 0 15px rgba(0,0,0,0.1); transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1); position: relative; flex-shrink: 0; } .sidebar.expanded { width: 260px; } .sidebar.collapsed { width: 64px; } .sidebar-header { padding: 20px; border-bottom: 1px solid rgba(255,255,255,0.1); text-align: center; transition: all 0.3s ease; white-space: nowrap; overflow: hidden; } .sidebar.collapsed .sidebar-header { padding: 20px 0; } .sidebar-header h2 { font-size: 18px; font-weight: 600; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; transition: opacity 0.3s ease; } .sidebar.collapsed .sidebar-header h2 { opacity: 0; } /* 菜单项 */ .menu-item { position: relative; } .menu-content { display: flex; align-items: center; padding: 14px 20px; cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; user-select: none; white-space: nowrap; } .sidebar.collapsed .menu-content { padding: 14px; justify-content: center; } .menu-content:hover { background: rgba(102, 126, 234, 0.1); } .menu-content.active { background: linear-gradient(90deg, rgba(102, 126, 234, 0.2) 0%, rgba(118, 75, 162, 0.1) 100%); border-left: 3px solid #667eea; } .sidebar.collapsed .menu-content.active { border-left: none; border-bottom: 3px solid #667eea; } .menu-content::before { content: ; position: absolute; left: 0; top: 0; height: 100%; width: 0; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); transition: width 0.2s ease; opacity: 0.1; } .menu-content:hover::before { width: 100%; } /* 图标 */ .menu-icon { width: 20px; height: 20px; margin-right: 12px; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; flex-shrink: 0; } .sidebar.collapsed .menu-icon { margin-right: 0; transform: scale(1.1); } .menu-icon svg { width: 18px; height: 18px; fill: currentColor; opacity: 0.8; } /* 菜单文字 */ .menu-text { flex: 1; font-size: 14px; font-weight: 500; color: rgba(255,255,255,0.85); transition: all 0.3s ease; opacity: 1; } .sidebar.collapsed .menu-text { opacity: 0; width: 0; flex: 0; } .menu-content:hover .menu-text, .menu-content.active .menu-text { color: #fff; } /* 展开箭头 - 优化旋转动画 */ .expand-arrow { width: 16px; height: 16px; transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); opacity: 0.6; flex-shrink: 0; margin-left: 8px; will-change: transform; } .sidebar.collapsed .expand-arrow { opacity: 0; width: 0; margin-left: 0; } .menu-item.expanded .menu-content .expand-arrow { transform: rotate(180deg); } /* 子菜单 - 关键优化使用 grid 动画替代 max-height */ .submenu { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.25s cubic-bezier(0.4, 0, 0.2, 1); will-change: grid-template-rows; background: rgba(0,0,0,0.15); overflow: hidden; } .menu-item.expanded .submenu { grid-template-rows: 1fr; } .submenu-inner { overflow: hidden; } .sidebar.collapsed .submenu { display: none; } /* 嵌套层级缩进 */ .submenu .menu-content { padding-left: 48px; } .submenu .submenu .menu-content { padding-left: 68px; } /* 空状态 */ .empty-menu { padding: 40px 20px; text-align: center; color: rgba(255,255,255,0.4); font-size: 14px; } /* 主内容区 */ .main-content { flex: 1; padding: 30px; overflow-y: auto; transition: all 0.3s ease; } .content-card { background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); margin-bottom: 20px; } .content-card h3 { color: #1f2937; margin-bottom: 12px; font-size: 18px; } .content-card p { color: #6b7280; line-height: 1.6; } /* 滚动条 */ .sidebar::-webkit-scrollbar { width: 4px; } .sidebar::-webkit-scrollbar-track { background: transparent; } .sidebar::-webkit-scrollbar-thumb { background: rgba(102, 126, 234, 0.3); border-radius: 2px; } /* 菜单项入场动画 */ keyframes slideIn { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: translateX(0); } } .menu-item { animation: slideIn 0.3s ease forwards; } /* 高亮指示器 */ .active-indicator { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 4px; height: 20px; background: #667eea; border-radius: 2px 0 0 2px; opacity: 0; transition: opacity 0.2s ease; } .menu-content.active .active-indicator { opacity: 1; } .sidebar.collapsed .active-indicator { right: auto; left: 0; border-radius: 0 2px 2px 0; } /* 叶子节点标记 */ .leaf-indicator { width: 6px; height: 6px; border-radius: 50%; background: rgba(102, 126, 234, 0.5); margin-left: 8px; opacity: 0; transition: opacity 0.2s ease; flex-shrink: 0; } .menu-content:hover .leaf-indicator { opacity: 1; } .sidebar.collapsed .leaf-indicator { display: none; } /* Tooltip */ .menu-tooltip { position: fixed; background: #1a1f2e; color: #fff; padding: 8px 12px; border-radius: 6px; font-size: 13px; white-space: nowrap; pointer-events: none; opacity: 0; transform: translateX(-10px); transition: all 0.2s ease; z-index: 1000; box-shadow: 0 4px 12px rgba(0,0,0,0.3); border: 1px solid rgba(102, 126, 234, 0.3); } .menu-tooltip.show { opacity: 1; transform: translateX(0); } .menu-tooltip::before { content: ; position: absolute; left: -6px; top: 50%; transform: translateY(-50%); border-width: 6px 6px 6px 0; border-style: solid; border-color: transparent #1a1f2e transparent transparent; } /* 顶部工具栏 */ .top-bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; } .toggle-btn { padding: 10px 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 6px -1px rgba(102, 126, 234, 0.3); } .toggle-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 15px -3px rgba(102, 126, 234, 0.4); } .toggle-btn:active { transform: translateY(0); } .toggle-btn svg { width: 18px; height: 18px; fill: currentColor; transition: transform 0.3s ease; } .toggle-btn:hover svg { transform: scale(1.1); } /style /head body div idapp div classapp-container !-- 侧边栏菜单 -- aside classsidebar :classsidebarCollapsed ? collapsed : expanded mouseleavehideTooltip div classsidebar-header h2管理系统/h2 /div recursive-menu :menu-datamenuList :user-permissionsuserPermissions :collapsedsidebarCollapsed menu-clickhandleMenuClick show-tooltipshowTooltip hide-tooltiphideTooltip / /aside !-- Tooltip -- div classmenu-tooltip :class{ show: tooltipVisible } :style{ left: tooltipX px, top: tooltipY px } {{ tooltipText }} /div !-- 主内容区 -- main classmain-content div classtop-bar button classtoggle-btn clicktoggleSidebar svg v-ifsidebarCollapsed viewBox0 0 24 24 path dM3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z/ /svg svg v-else viewBox0 0 24 24 path dM3 18h13v-2H3v2zm0-5h10v-2H3v2zm0-7v2h13V6H3zm16 13l4-4-4-4v8z/ /svg {{ sidebarCollapsed ? 展开菜单 : 收起菜单 }} /button h3 stylecolor: #1f2937;Vue3 多级菜单演示/h3 /div div classcontent-card h3当前路由: {{ currentRoute }}/h3 p点击左侧菜单项展开/收起子菜单点击叶子节点进行路由跳转。/p p stylemargin-top: 8px; color: #667eea; font-weight: 500; 侧边栏状态: {{ sidebarCollapsed ? 已收起 (64px) : 已展开 (260px) }} /p /div div classcontent-card h3优化说明/h3 p• 使用 CSS Grid 动画替代 max-height性能更好/p p• 动画时长缩短至 0.25s响应更迅速/p p• 添加 will-change 属性优化渲染性能/p p• 移除 Vue Transition 组件减少框架开销/p p• 当前用户权限: code{{ JSON.stringify(userPermissions) }}/code/p button clicktogglePermission stylemargin-top: 10px; padding: 8px 16px; background: #667eea; color: white; border: none; border-radius: 6px; cursor: pointer; 切换权限测试 /button /div div classcontent-card v-ifmenuHistory.length 0 h3最近访问/h3 ul stylecolor: #6b7280; line-height: 2; li v-for(path, index) in menuHistory.slice(-5) :keyindex{{ path }}/li /ul /div /main /div /div script const { createApp, ref, computed } Vue; const IconMap { setting: svg viewBox0 0 24 24path dM12 15.5A3.5 3.5 0 0 1 8.5 12 3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97 0-.33-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1 0 .33.03.66.07 1l-2.11 1.63c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.08.73 1.69.98l.38 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1.01c.22.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.63Z//svg, user: svg viewBox0 0 24 24path dM12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z//svg, folder: svg viewBox0 0 24 24path dM20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm0 12H4V8h16v10z//svg, default: svg viewBox0 0 24 24path dM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z//svg }; const RecursiveMenu { name: RecursiveMenu, props: { menuData: { type: Array, default: () [] }, userPermissions: { type: Array, default: () [] }, parentPath: { type: String, default: }, level: { type: Number, default: 0 }, collapsed: { type: Boolean, default: false } }, emits: [menu-click, show-tooltip, hide-tooltip], setup(props, { emit }) { const expandedKeys ref(new Set()); const activeKey ref(); const hasPermission (access) { if (!access) return true; return props.userPermissions.includes(access); }; const hasChildrenPermission (children) { if (!children || children.length 0) return false; return children.some(child { if (hasPermission(child.access)) return true; if (child.children hasChildrenPermission(child.children)) return true; return false; }); }; const filteredMenuData computed(() { return props.menuData.filter(item { const selfVisible hasPermission(item.access); const childrenVisible item.children hasChildrenPermission(item.children); return selfVisible || childrenVisible; }).map(item { if (item.children) { return { ...item, children: item.children.filter(child { const childVisible hasPermission(child.access); const grandChildrenVisible child.children hasChildrenPermission(child.children); return childVisible || grandChildrenVisible; }) }; } return item; }); }); const isLeaf (item) !item.children || item.children.length 0; const toggleExpand (id) { if (props.collapsed) return; if (expandedKeys.value.has(id)) { expandedKeys.value.delete(id); } else { expandedKeys.value.add(id); } }; const handleClick (item) { const fullPath props.parentPath item.path; const leaf isLeaf(item); if (leaf) { activeKey.value item.id; emit(menu-click, { ...item, fullPath, isLeaf: true }); } else if (!props.collapsed) { toggleExpand(item.id); } }; const handleMouseEnter (item, event) { if (props.collapsed) { const rect event.currentTarget.getBoundingClientRect(); emit(show-tooltip, { text: item.name, x: rect.right 10, y: rect.top rect.height / 2 }); } }; const handleMouseLeave () { if (props.collapsed) emit(hide-tooltip); }; const renderIcon (iconName) IconMap[iconName] || IconMap.default; return { expandedKeys, activeKey, filteredMenuData, isLeaf, handleClick, handleMouseEnter, handleMouseLeave, renderIcon }; }, template: div classmenu-list div v-foritem in filteredMenuData :keyitem.id classmenu-item :class{ expanded: expandedKeys.has(item.id) } div classmenu-content :class{ active: activeKey item.id, has-children: !isLeaf(item) } clickhandleClick(item) mouseenterhandleMouseEnter(item, $event) mouseleavehandleMouseLeave span classactive-indicator/span span classmenu-icon v-htmlrenderIcon(item.icon)/span span classmenu-text{{ item.name }}/span svg v-if!isLeaf(item) classexpand-arrow viewBox0 0 24 24 path fillcurrentColor dM7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z/ /svg span v-else classleaf-indicator/span /div !-- 优化使用 Grid 动画替代 Transition 组件 -- div v-if!isLeaf(item) !collapsed classsubmenu div classsubmenu-inner recursive-menu :menu-dataitem.children :user-permissionsuserPermissions :parent-pathparentPath item.path / :levellevel 1 :collapsedcollapsed menu-click$emit(menu-click, $event) show-tooltip$emit(show-tooltip, $event) hide-tooltip$emit(hide-tooltip) / /div /div /div div v-iffilteredMenuData.length 0 classempty-menu 暂无可用菜单 /div /div }; createApp({ components: { RecursiveMenu }, setup() { const menuList ref([ { id: 1, name: 系统管理, path: /system, icon: setting, component: Layout, sort: 1, children: [ { id: 11, name: 用户管理, path: user, component: system/UserList, access: user:view, sort: 1 }, { id: 12, name: 角色管理, path: role, component: system/RoleList, access: role:view, sort: 2 }, { id: 13, name: 菜单管理, path: menu, component: system/MenuList, access: menu:view, sort: 3 } ] }, { id: 2, name: 个人中心, path: /profile, icon: user, component: Layout, access: menu:view, sort: 2, children: [ { id: 21, name: 基本资料, path: info, component: profile/BasicInfo, access: profile:view, sort: 1 }, { id: 22, name: 修改密码, path: password, component: profile/ChangePwd, access: profile:password, sort: 2 } ] } ]); const userPermissions ref([ user:view, user:create, user:update, role:view, role:permission, menu:view, profile:view, profile:update, profile:password ]); const currentRoute ref(未选择); const menuHistory ref([]); const sidebarCollapsed ref(false); const tooltipVisible ref(false); const tooltipText ref(); const tooltipX ref(0); const tooltipY ref(0); const handleMenuClick (menuItem) { currentRoute.value menuItem.fullPath; menuHistory.value.push(menuItem.fullPath); }; const togglePermission () { if (userPermissions.value.includes(role:view)) { userPermissions.value userPermissions.value.filter(p !p.startsWith(role:)); alert(已移除角色管理权限); } else { userPermissions.value.push(role:view, role:create, role:update, role:delete, role:permission); alert(已恢复角色管理权限); } }; const toggleSidebar () { sidebarCollapsed.value !sidebarCollapsed.value; }; const showTooltip ({ text, x, y }) { tooltipText.value text; tooltipX.value x; tooltipY.value y - 15; tooltipVisible.value true; }; const hideTooltip () { tooltipVisible.value false; }; return { menuList, userPermissions, currentRoute, menuHistory, sidebarCollapsed, tooltipVisible, tooltipText, tooltipX, tooltipY, handleMenuClick, togglePermission, toggleSidebar, showTooltip, hideTooltip }; } }).mount(#app); /script /body /html