(function () { if (document.getElementById('uni-nav-styles')) return; var style = document.createElement('style'); style.id = 'uni-nav-styles'; style.textContent = '\ .uni-nav {\ position: fixed; top: 0; left: 0; right: 0; height: 60px;\ z-index: 10000;\ display: flex; align-items: center;\ padding: 0 16px;\ background: linear-gradient(135deg, #2563eb, #1d4ed8);\ color: #fff;\ box-shadow: 0 2px 12px rgba(37,99,235,0.25);\ }\ .uni-nav-inner {\ display: flex; align-items: center;\ width: 100%; max-width: 1400px; margin: 0 auto;\ gap: 8px;\ }\ .uni-nav-brand {\ font-size: 18px; font-weight: 700;\ white-space: nowrap;\ margin-right: 8px;\ letter-spacing: -0.3px;\ }\ .uni-nav-items {\ display: flex; align-items: center; gap: 2px;\ flex: 1; overflow: hidden;\ }\ .uni-nav-item {\ display: inline-flex; align-items: center; gap: 4px;\ padding: 6px 12px;\ border: none; background: transparent;\ color: rgba(255,255,255,0.8);\ font-size: 13px;\ border-radius: 8px;\ cursor: pointer;\ white-space: nowrap;\ transition: all 0.2s;\ }\ .uni-nav-item:hover { background: rgba(255,255,255,0.12); color: #fff; }\ .uni-nav-item.active {\ background: rgba(255,255,255,0.18); color: #fff; font-weight: 600;\ }\ .uni-nav-right {\ display: flex; align-items: center; gap: 8px;\ flex-shrink: 0;\ }\ .uni-nav-avatar {\ width: 30px; height: 30px;\ border-radius: 50%;\ background: rgba(255,255,255,0.2);\ display: flex; align-items: center; justify-content: center;\ font-size: 13px; font-weight: 600;\ }\ .uni-nav-username { font-size: 13px; color: rgba(255,255,255,0.9); }\ .uni-nav-badge {\ font-size: 10px;\ background: rgba(255,255,255,0.15);\ padding: 1px 8px; border-radius: 10px;\ margin-left: 4px;\ }\ .uni-nav-logout {\ background: rgba(255,255,255,0.1);\ border: 1px solid rgba(255,255,255,0.15);\ color: rgba(255,255,255,0.9);\ padding: 4px 12px; border-radius: 6px;\ cursor: pointer; font-size: 12px;\ transition: all 0.2s;\ }\ .uni-nav-logout:hover { background: rgba(255,255,255,0.2); }\ .uni-nav-hamburger {\ display: none;\ background: rgba(255,255,255,0.1);\ border: none; color: #fff;\ width: 36px; height: 36px;\ border-radius: 8px;\ cursor: pointer; font-size: 20px;\ align-items: center; justify-content: center;\ transition: all 0.2s;\ }\ .uni-nav-hamburger:hover { background: rgba(255,255,255,0.18); }\ .uni-nav-dropdown {\ display: none;\ position: fixed; top: 60px; left: 0; right: 0;\ background: #fff;\ box-shadow: 0 8px 24px rgba(0,0,0,0.12);\ z-index: 9999;\ padding: 8px;\ max-height: calc(100vh - 60px);\ overflow-y: auto;\ animation: uniNavSlideDown 0.2s ease-out;\ }\ .uni-nav-dropdown.open { display: block; }\ .uni-nav-dropdown-item {\ display: flex; align-items: center; gap: 8px;\ width: 100%;\ padding: 12px 16px;\ border: none; background: transparent;\ color: #303133; font-size: 14px;\ border-radius: 8px;\ cursor: pointer;\ transition: all 0.15s;\ }\ .uni-nav-dropdown-item:hover { background: #f0f4ff; color: #2563eb; }\ .uni-nav-dropdown-item.active { background: #eef2ff; color: #2563eb; font-weight: 600; }\ .uni-nav-dropdown-divider {\ height: 1px; background: #f0f0f0; margin: 4px 0;\ }\ @media (max-width: 768px) {\ .uni-nav-items { display: none; }\ .uni-nav-username { display: none; }\ .uni-nav-hamburger { display: inline-flex; }\ }\ @keyframes uniNavSlideDown {\ from { opacity: 0; transform: translateY(-8px); }\ to { opacity: 1; transform: translateY(0); }\ }\ '; document.head.appendChild(style); function getCurrentPage() { var path = window.location.pathname; if (path === '/index.html') return 'workspace'; var m = path.match(/\/(\w+)\.html/); return m ? m[1] : 'workspace'; } function navItems(isAdmin) { var items = [ { key: 'workspace', label: '工作台', page: 'index.html' }, { key: 'factory', label: '内容工厂', page: 'factory.html' }, { key: 'insights', label: '数据洞察', page: 'insights.html' }, { key: 'assets', label: '资产库', page: 'assets.html' }, ]; if (isAdmin) { items.push({ key: 'admin', label: '系统管理', page: 'admin.html', admin: true }); } return items; } var UniNav = { name: 'UniNav', props: { title: { type: String, default: '' }, username: { type: String, default: '' }, isAdmin: { type: Boolean, default: false }, currentPage: { type: String, default: null }, onNavigate: { type: Function, default: null }, }, emits: ['logout'], data: function () { return { dropdownOpen: false, profileOpen: false, showProfileDialog: false, showPwdDialog: false, profile: null, pwdForm: { old_password: '', new_password: '', confirm: '' }, pwdSubmitting: false, serverMenus: null, }; }, computed: { items: function () { if (this.serverMenus) { return this.serverMenus .filter(function (m) { return m.is_active !== false; }) .map(function (m) { return { key: m.name, label: m.name, page: m.path }; }); } return navItems(this.isAdmin); }, page: function () { return this.currentPage || getCurrentPage(); }, showTitle: function () { return this.title || '宇之然'; }, }, methods: { fetchMenus: function () { var token = localStorage.getItem('authToken'); if (!token) return; fetch('/api/menus/active', { headers: { 'Authorization': 'Bearer ' + token } }) .then(function (r) { return r.ok ? r.json() : Promise.reject(); }) .then(function (data) { if (data && data.length > 0) this.serverMenus = data; }.bind(this)) .catch(function () {}); }, navigate: function (page) { this.dropdownOpen = false; this.profileOpen = false; if (this.onNavigate) { this.onNavigate(page); return; } window.location.href = page.startsWith('/') ? page : '/' + page; }, logout: function () { this.profileOpen = false; this.$emit('logout'); }, toggleDropdown: function () { this.dropdownOpen = !this.dropdownOpen; this.profileOpen = false; }, toggleProfile: function () { this.profileOpen = !this.profileOpen; this.dropdownOpen = false; }, closeAll: function (e) { var el = this.$el; if (!el) return; if (this.dropdownOpen && !el.contains(e.target)) this.dropdownOpen = false; if (this.profileOpen && !el.querySelector('.uni-nav-profile-menu')?.contains(e.target) && e.target !== el.querySelector('.uni-nav-avatar') && !el.querySelector('.uni-nav-avatar')?.contains(e.target)) this.profileOpen = false; }, openProfile: function () { this.profileOpen = false; var token = localStorage.getItem('authToken'); if (!token) return; fetch('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + token } }) .then(function (r) { return r.ok ? r.json() : Promise.reject(); }) .then(function (d) { this.profile = d.user || d; this.showProfileDialog = true; }.bind(this)) .catch(function () { (ElementPlus.ElMessage || {}).error && ElementPlus.ElMessage.error('获取用户信息失败'); }); }, openPwdDialog: function () { this.profileOpen = false; this.pwdForm = { old_password: '', new_password: '', confirm: '' }; this.showPwdDialog = true; }, submitPwd: function () { if (this.pwdForm.new_password.length < 6) { (ElementPlus.ElMessage || {}).warning && ElementPlus.ElMessage.warning('新密码至少6位'); return; } if (this.pwdForm.new_password !== this.pwdForm.confirm) { (ElementPlus.ElMessage || {}).warning && ElementPlus.ElMessage.warning('两次密码不一致'); return; } this.pwdSubmitting = true; var token = localStorage.getItem('authToken'); fetch('/api/auth/password', { method: 'PUT', headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }, body: JSON.stringify({ old_password: this.pwdForm.old_password, new_password: this.pwdForm.new_password }) }).then(function (r) { if (r.ok) { this.showPwdDialog = false; (ElementPlus.ElMessage || {}).success && ElementPlus.ElMessage.success('密码修改成功'); } else { return r.json().then(function (d) { throw new Error(d.detail || '修改失败'); }); } }.bind(this)).catch(function (e) { (ElementPlus.ElMessage || {}).error && ElementPlus.ElMessage.error(e.message); }).finally(function () { this.pwdSubmitting = false; }.bind(this)); }, closePwdDialog: function () { this.showPwdDialog = false; }, closeProfileDialog: function () { this.showProfileDialog = false; }, }, mounted: function () { document.addEventListener('click', this.closeAll); this.fetchMenus(); }, beforeUnmount: function () { document.removeEventListener('click', this.closeAll); }, template: '\ \
\
\

个人信息

\
\
用户名{{ profile ? profile.username : \'-\' }}
\
角色{{ profile ? profile.role : \'-\' }}
\
组织{{ profile ? (profile.org_id || \'-\') : \'-\' }}
\
创建时间{{ profile && profile.created_at ? new Date(profile.created_at).toLocaleString(\'zh-CN\') : \'-\' }}
\
最后登录{{ profile && profile.last_login ? new Date(profile.last_login).toLocaleString(\'zh-CN\') : \'-\' }}
\
\
\
\
\
\
\

修改密码

\
\
\
\
\
\
\
\
\
\ \ \
\
\
', }; window.UniNav = UniNav; window.installUniNav = function (app) { app.component('uni-nav', UniNav); return app; }; })();