This commit is contained in:
MeSHard
2025-11-14 17:34:39 +08:00
commit ca6f1086b0
18 changed files with 3297 additions and 0 deletions

64
background/design.md Normal file
View File

@@ -0,0 +1,64 @@
# 企业设置管理系统设计规范
## 设计理念
采用现代简约的企业级设计风格,强调专业性和易用性,通过精致的视觉细节和流畅的交互动画提升用户体验。
## 色彩系统
- **主色调**: 深蓝灰 (#2D3748) - 专业稳重
- **辅助色**: 柔和蓝 (#4A90E2) - 交互元素
- **强调色**: 温暖橙 (#F56500) - 重要操作
- **背景色**: 浅灰白 (#F7FAFC) - 主背景
- **文本色**: 深灰 (#2D3748) 和中灰 (#4A5568)
## 字体系统
- **标题字体**: Noto Sans SC (粗体) - 现代感强
- **正文字体**: Noto Sans SC (常规) - 清晰易读
- **字体层级**:
- H1: 2.5rem (40px)
- H2: 2rem (32px)
- H3: 1.5rem (24px)
- 正文: 1rem (16px)
- 小字: 0.875rem (14px)
## 视觉效果
### 背景效果
- 使用液态金属位移效果作为页面背景
- 微妙的粒子动画增强视觉层次
### 交互动画
- 按钮悬停: 3D倾斜效果 + 阴影扩展
- 表单元素: 聚焦时边框发光效果
- 开关切换: 平滑的滑动动画
- 卡片悬停: 轻微上浮 + 阴影加深
### 图标系统
- 使用线性图标风格
- 统一的描边粗细 (2px)
- 悬停时填充动画
## 布局系统
- **网格系统**: 12列响应式网格
- **间距系统**: 4px基础单位的倍数
- **圆角**: 统一使用8px圆角
- **阴影**: 多层次阴影系统营造深度感
## 组件设计
### 登录表单
- 居中布局最大宽度400px
- 半透明背景卡片
- 渐变边框装饰
### 设置面板
- 左侧导航栏 (固定宽度280px)
- 右侧内容区域 (自适应)
- 分组的设置卡片
### 开关控件
- iOS风格的滑动开关
- 颜色状态反馈
- 微动画过渡
### 输入控件
- 浮动标签设计
- 聚焦时动画效果
- 错误状态视觉反馈

71
background/index.html Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>企业设置管理系统</title>
<meta http-equiv="refresh" content="0; url=login.html">
<style>
body {
font-family: 'Noto Sans SC', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
margin: 0;
padding: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
.loading-container {
text-align: center;
}
.spinner {
width: 50px;
height: 50px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-top: 3px solid white;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 18px;
margin-bottom: 10px;
}
.loading-subtitle {
font-size: 14px;
opacity: 0.8;
}
</style>
</head>
<body>
<div class="loading-container">
<div class="spinner"></div>
<div class="loading-text">企业设置管理系统</div>
<div class="loading-subtitle">正在加载登录页面...</div>
<div style="margin-top: 30px;">
<p style="font-size: 12px; opacity: 0.6;">
如果页面没有自动跳转,请<a href="login.html" style="color: #4A90E2; text-decoration: none;">点击这里</a>
</p>
</div>
</div>
<script>
// 确保在3秒后强制跳转
setTimeout(function() {
window.location.href = 'login.html';
}, 3000);
</script>
</body>
</html>

56
background/interaction.md Normal file
View File

@@ -0,0 +1,56 @@
# 企业设置管理系统交互设计
## 系统概述
一个专为企业管理设置的双页面Web应用包含登录功能和企业设置管理功能。
## 页面结构
1. **登录页面** - 企业用户身份验证
2. **设置页面** - 企业配置管理
## 详细交互设计
### 登录页面交互
- **表单验证**: 实时验证企业ID和密码
- **错误提示**: 友好的错误信息展示
- **记住登录**: 可选的记住登录状态功能
- **动画反馈**: 按钮悬停和点击动画效果
### 设置页面交互
- **设置分类**:
- 交通管理设置
- 是否禁停 (开关切换)
- 是否禁行 (开关切换)
- 是否是危险源 (开关切换)
- 车辆管理设置
- 可停车辆数 (数字输入框)
- 可行车辆数 (数字输入框)
- 安全设置
- 最大限速 (滑动条 + 数字输入)
- 企业信息
- 企业产品 (多行文本框)
- **交互特性**:
- 实时预览设置效果
- 数值输入验证和限制
- 开关状态的视觉反馈
- 保存确认对话框
- 重置为默认设置选项
### 数据持久化
- 使用localStorage保存设置数据
- 登录状态管理
- 设置变更历史记录
## 用户体验流程
1. 用户访问登录页面
2. 输入企业凭证进行登录
3. 进入设置页面查看当前配置
4. 修改各项企业设置参数
5. 预览设置效果
6. 保存设置并确认
7. 可选择退出登录
## 响应式设计
- 适配桌面端和移动端
- 触摸友好的交互元素
- 合理的布局缩放

391
background/login.html Normal file
View File

@@ -0,0 +1,391 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>企业设置管理系统 - 登录</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Sans SC', sans-serif;
}
.liquid-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.liquid-metal {
position: absolute;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.15) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(120, 119, 198, 0.4) 0%, transparent 50%);
animation: liquidFlow 20s ease-in-out infinite;
}
@keyframes liquidFlow {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
33% { transform: translate(-20px, -20px) rotate(1deg); }
66% { transform: translate(20px, -10px) rotate(-1deg); }
}
.glass-card {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
}
.form-input {
background: rgba(255, 255, 255, 0.9);
border: 2px solid transparent;
transition: all 0.3s ease;
}
.form-input:focus {
background: rgba(255, 255, 255, 1);
border-color: #4A90E2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
transform: translateY(-2px);
}
.btn-primary {
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-primary:hover {
transform: translateY(-3px) rotateX(5deg);
box-shadow: 0 15px 35px rgba(74, 144, 226, 0.4);
}
.btn-primary:active {
transform: translateY(-1px) rotateX(2deg);
}
.floating-particles {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
.particle {
position: absolute;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0px) rotate(0deg); opacity: 0; }
50% { transform: translateY(-100px) rotate(180deg); opacity: 1; }
}
.logo-animation {
animation: logoFloat 3s ease-in-out infinite;
}
@keyframes logoFloat {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.error-shake {
animation: shake 0.5s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="liquid-bg">
<div class="liquid-metal"></div>
<div class="floating-particles" id="particles"></div>
</div>
<div class="glass-card rounded-3xl p-8 w-full max-w-md transform transition-all duration-500 hover:scale-105">
<!-- Logo Section -->
<div class="text-center mb-8">
<div class="logo-animation mb-4">
<div class="w-20 h-20 mx-auto bg-gradient-to-br from-blue-400 to-blue-600 rounded-3xl flex items-center justify-center shadow-2xl">
<svg class="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-4m-5 0H9m0 0H5m0 0h2M7 7h10M7 11h10M7 15h10"></path>
</svg>
</div>
</div>
<h1 class="text-3xl font-bold text-white mb-2">企业设置管理</h1>
<p class="text-blue-100 text-sm">安全高效的企业配置平台</p>
</div>
<!-- Login Form -->
<form id="loginForm" class="space-y-6">
<div class="form-group">
<label for="companyId" class="block text-white text-sm font-medium mb-2">企业ID</label>
<input
type="text"
id="companyId"
name="companyId"
class="form-input w-full px-4 py-3 rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none"
placeholder="请输入企业ID"
required
>
<div class="error-message text-red-300 text-xs mt-1 hidden" id="companyIdError"></div>
</div>
<div class="form-group">
<label for="password" class="block text-white text-sm font-medium mb-2">登录密码</label>
<input
type="password"
id="password"
name="password"
class="form-input w-full px-4 py-3 rounded-xl text-gray-800 placeholder-gray-500 focus:outline-none"
placeholder="请输入登录密码"
required
>
<div class="error-message text-red-300 text-xs mt-1 hidden" id="passwordError"></div>
</div>
<div class="flex items-center justify-between">
<label class="flex items-center">
<input type="checkbox" id="rememberMe" class="w-4 h-4 text-blue-600 rounded focus:ring-blue-500">
<span class="ml-2 text-sm text-blue-100">记住登录状态</span>
</label>
<a href="#" class="text-sm text-blue-200 hover:text-white transition-colors">忘记密码?</a>
</div>
<button
type="submit"
class="btn-primary w-full py-3 px-6 rounded-xl text-white font-medium text-lg focus:outline-none focus:ring-4 focus:ring-blue-300"
id="loginBtn"
>
<span class="btn-text">安全登录</span>
<span class="btn-loading hidden">
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
验证中...
</span>
</button>
</form>
<!-- Footer -->
<div class="text-center mt-8">
<p class="text-blue-200 text-xs">
© 2025 企业设置管理系统 | 安全可靠的配置管理平台
</p>
</div>
</div>
<!-- Success Modal -->
<div id="successModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-2xl p-8 max-w-sm mx-4 transform transition-all duration-300 scale-95">
<div class="text-center">
<div class="w-16 h-16 mx-auto bg-green-100 rounded-full flex items-center justify-center mb-4">
<svg class="w-8 h-8 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<h3 class="text-lg font-semibold text-gray-900 mb-2">登录成功</h3>
<p class="text-gray-600 text-sm mb-6">正在进入企业设置管理平台...</p>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-blue-600 h-2 rounded-full transition-all duration-1000" style="width: 0%" id="progressBar"></div>
</div>
</div>
</div>
</div>
<script>
// 创建浮动粒子效果
function createParticles() {
const particlesContainer = document.getElementById('particles');
const particleCount = 15;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
const size = Math.random() * 4 + 2;
const left = Math.random() * 100;
const animationDelay = Math.random() * 6;
const animationDuration = Math.random() * 3 + 4;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
particle.style.left = `${left}%`;
particle.style.bottom = '-10px';
particle.style.animationDelay = `${animationDelay}s`;
particle.style.animationDuration = `${animationDuration}s`;
particlesContainer.appendChild(particle);
}
}
// 表单验证
function validateForm() {
const companyId = document.getElementById('companyId');
const password = document.getElementById('password');
let isValid = true;
// 验证企业ID
if (!companyId.value.trim()) {
showError('companyIdError', '企业ID不能为空');
companyId.classList.add('error-shake');
setTimeout(() => companyId.classList.remove('error-shake'), 500);
isValid = false;
} else {
hideError('companyIdError');
}
// 验证密码
if (!password.value.trim()) {
showError('passwordError', '登录密码不能为空');
password.classList.add('error-shake');
setTimeout(() => password.classList.remove('error-shake'), 500);
isValid = false;
} else {
hideError('passwordError');
}
return isValid;
}
function showError(elementId, message) {
const errorElement = document.getElementById(elementId);
errorElement.textContent = message;
errorElement.classList.remove('hidden');
}
function hideError(elementId) {
const errorElement = document.getElementById(elementId);
errorElement.classList.add('hidden');
}
// 登录处理
function handleLogin(event) {
event.preventDefault();
if (!validateForm()) {
return;
}
const loginBtn = document.getElementById('loginBtn');
const btnText = loginBtn.querySelector('.btn-text');
const btnLoading = loginBtn.querySelector('.btn-loading');
// 显示加载状态
btnText.classList.add('hidden');
btnLoading.classList.remove('hidden');
loginBtn.disabled = true;
// 模拟登录验证
setTimeout(() => {
// 保存登录状态
const rememberMe = document.getElementById('rememberMe').checked;
const loginData = {
companyId: document.getElementById('companyId').value,
loginTime: new Date().toISOString(),
rememberMe: rememberMe
};
if (rememberMe) {
localStorage.setItem('companyLogin', JSON.stringify(loginData));
} else {
sessionStorage.setItem('companyLogin', JSON.stringify(loginData));
}
// 显示成功模态框
showSuccessModal();
// 3秒后跳转到设置页面
setTimeout(() => {
window.location.href = 'settings.html';
}, 3000);
}, 2000);
}
// 显示成功模态框
function showSuccessModal() {
const modal = document.getElementById('successModal');
const progressBar = document.getElementById('progressBar');
modal.classList.remove('hidden');
// 动画显示模态框
anime({
targets: modal.querySelector('.bg-white'),
scale: [0.95, 1],
opacity: [0, 1],
duration: 300,
easing: 'easeOutQuad'
});
// 进度条动画
anime({
targets: progressBar,
width: '100%',
duration: 3000,
easing: 'linear'
});
}
// 初始化
document.addEventListener('DOMContentLoaded', function() {
createParticles();
// 检查是否已登录
const savedLogin = localStorage.getItem('companyLogin') || sessionStorage.getItem('companyLogin');
if (savedLogin) {
const loginData = JSON.parse(savedLogin);
document.getElementById('companyId').value = loginData.companyId || '';
document.getElementById('rememberMe').checked = loginData.rememberMe || false;
}
// 表单提交事件
document.getElementById('loginForm').addEventListener('submit', handleLogin);
// 输入框聚焦动画
const inputs = document.querySelectorAll('.form-input');
inputs.forEach(input => {
input.addEventListener('focus', function() {
anime({
targets: this,
scale: [1, 1.02],
duration: 200,
easing: 'easeOutQuad'
});
});
input.addEventListener('blur', function() {
anime({
targets: this,
scale: [1.02, 1],
duration: 200,
easing: 'easeOutQuad'
});
});
});
});
</script>
</body>
</html>

383
background/main.js Normal file
View File

@@ -0,0 +1,383 @@
// 企业设置管理系统 - 主要JavaScript文件
// 包含所有核心功能和交互逻辑
class EnterpriseSettingsApp {
constructor() {
this.currentUser = null;
this.settings = {};
this.init();
}
init() {
this.checkAuthentication();
this.initializeDefaultSettings();
this.bindGlobalEvents();
}
// 身份验证管理
checkAuthentication() {
const loginData = localStorage.getItem('companyLogin') || sessionStorage.getItem('companyLogin');
if (loginData) {
this.currentUser = JSON.parse(loginData);
} else if (window.location.pathname.includes('settings.html')) {
window.location.href = 'login.html';
}
}
// 初始化默认设置
initializeDefaultSettings() {
const defaultSettings = {
noParking: false,
noTraffic: false,
dangerSource: false,
parkingCapacity: 50,
trafficCapacity: 100,
speedLimit: 60,
companyProducts: '我们专注于提供高质量的企业管理解决方案,包括智能交通管理系统、企业资源规划系统、安全监控系统等。致力于为各类企业提供全方位的数字化转型服务。'
};
const savedSettings = localStorage.getItem('companySettings');
this.settings = savedSettings ? { ...defaultSettings, ...JSON.parse(savedSettings) } : defaultSettings;
}
// 绑定全局事件
bindGlobalEvents() {
// 页面可见性变化
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
this.onPageHidden();
} else {
this.onPageVisible();
}
});
// 窗口大小变化
window.addEventListener('resize', this.debounce(() => {
this.onWindowResize();
}, 250));
// 键盘快捷键
document.addEventListener('keydown', (e) => {
this.handleKeyboardShortcuts(e);
});
}
// 页面隐藏时的处理
onPageHidden() {
// 保存当前状态
if (Object.keys(this.settings).length > 0) {
localStorage.setItem('companySettings', JSON.stringify(this.settings));
}
}
// 页面显示时的处理
onPageVisible() {
// 检查会话状态
this.checkAuthentication();
}
// 窗口大小变化处理
onWindowResize() {
// 响应式布局调整
const isMobile = window.innerWidth < 768;
document.body.classList.toggle('mobile', isMobile);
}
// 键盘快捷键处理
handleKeyboardShortcuts(e) {
// Ctrl/Cmd + S: 保存设置
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
e.preventDefault();
this.saveSettings();
}
// Ctrl/Cmd + R: 重置设置
if ((e.ctrlKey || e.metaKey) && e.key === 'r') {
e.preventDefault();
this.resetSettings();
}
// Escape: 退出当前操作
if (e.key === 'Escape') {
this.exitCurrentOperation();
}
}
// 防抖函数
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 节流函数
throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 设置管理
saveSettings() {
localStorage.setItem('companySettings', JSON.stringify(this.settings));
this.showNotification('设置已保存', 'success');
this.logActivity('设置保存', '用户保存了企业设置');
}
resetSettings() {
if (confirm('确定要重置所有设置为默认值吗?此操作不可撤销。')) {
localStorage.removeItem('companySettings');
this.initializeDefaultSettings();
this.updateAllUI();
this.showNotification('设置已重置为默认值', 'info');
this.logActivity('设置重置', '用户重置了所有企业设置');
}
}
// 退出当前操作
exitCurrentOperation() {
// 关闭所有模态框
document.querySelectorAll('.modal, .toast').forEach(element => {
element.classList.remove('show', 'active');
});
// 清除焦点
document.activeElement.blur();
}
// 更新所有UI元素
updateAllUI() {
// 更新开关状态
Object.keys(this.settings).forEach(key => {
const element = document.getElementById(key);
if (element) {
if (element.type === 'checkbox') {
element.checked = this.settings[key];
} else if (element.type === 'range' || element.type === 'number') {
element.value = this.settings[key];
} else {
element.value = this.settings[key];
}
}
});
// 更新显示值
this.updateDisplayValues();
}
// 更新显示值
updateDisplayValues() {
const displays = {
parkingCapacityValue: `${this.settings.parkingCapacity}`,
trafficCapacityValue: `${this.settings.trafficCapacity}`,
speedLimitValue: `${this.settings.speedLimit}`,
charCount: `${this.settings.companyProducts.length} 字符`
};
Object.keys(displays).forEach(id => {
const element = document.getElementById(id);
if (element) {
element.textContent = displays[id];
}
});
}
// 通知系统
showNotification(message, type = 'info', duration = 3000) {
const notification = this.createNotification(message, type);
document.body.appendChild(notification);
// 显示动画
setTimeout(() => {
notification.classList.add('show');
}, 10);
// 自动隐藏
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => {
document.body.removeChild(notification);
}, 300);
}, duration);
}
createNotification(message, type) {
const notification = document.createElement('div');
notification.className = `notification notification-${type}`;
const icons = {
success: '✓',
error: '✕',
warning: '⚠',
info: ''
};
const colors = {
success: 'bg-green-500',
error: 'bg-red-500',
warning: 'bg-yellow-500',
info: 'bg-blue-500'
};
notification.innerHTML = `
<div class="flex items-center space-x-3 p-4 bg-white rounded-lg shadow-lg">
<div class="w-8 h-8 ${colors[type]} rounded-full flex items-center justify-center text-white font-bold">
${icons[type]}
</div>
<div>
<p class="font-medium text-gray-800">${message}</p>
</div>
</div>
`;
return notification;
}
// 活动日志
logActivity(action, description) {
const activity = {
timestamp: new Date().toISOString(),
action,
description,
user: this.currentUser?.companyId || '未知用户'
};
const activities = JSON.parse(localStorage.getItem('activityLog') || '[]');
activities.unshift(activity);
// 保留最近100条记录
if (activities.length > 100) {
activities.splice(100);
}
localStorage.setItem('activityLog', JSON.stringify(activities));
}
// 获取活动日志
getActivityLog(limit = 10) {
const activities = JSON.parse(localStorage.getItem('activityLog') || '[]');
return activities.slice(0, limit);
}
// 数据验证
validateSettings() {
const errors = [];
if (this.settings.parkingCapacity < 0 || this.settings.parkingCapacity > 1000) {
errors.push('停车容量必须在0-1000之间');
}
if (this.settings.trafficCapacity < 0 || this.settings.trafficCapacity > 1000) {
errors.push('通行容量必须在0-1000之间');
}
if (this.settings.speedLimit < 10 || this.settings.speedLimit > 120) {
errors.push('限速必须在10-120 km/h之间');
}
return errors;
}
// 导出设置
exportSettings() {
const data = {
settings: this.settings,
exportTime: new Date().toISOString(),
version: '1.0'
};
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `enterprise-settings-${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
this.logActivity('设置导出', '用户导出了企业设置');
}
// 导入设置
importSettings(file) {
const reader = new FileReader();
reader.onload = (e) => {
try {
const data = JSON.parse(e.target.result);
if (data.settings) {
this.settings = { ...this.settings, ...data.settings };
this.updateAllUI();
this.saveSettings();
this.showNotification('设置导入成功', 'success');
this.logActivity('设置导入', '用户导入了企业设置');
}
} catch (error) {
this.showNotification('设置文件格式错误', 'error');
}
};
reader.readAsText(file);
}
// 获取系统状态
getSystemStatus() {
return {
authenticated: !!this.currentUser,
settingsCount: Object.keys(this.settings).length,
lastActivity: this.getActivityLog(1)[0]?.timestamp || null,
storageUsed: this.getStorageInfo()
};
}
// 获取存储信息
getStorageInfo() {
let total = 0;
for (let key in localStorage) {
if (localStorage.hasOwnProperty(key)) {
total += localStorage[key].length;
}
}
return {
used: total,
available: 5 * 1024 * 1024, // 5MB
percent: (total / (5 * 1024 * 1024)) * 100
};
}
}
// 全局实例
let app;
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
app = new EnterpriseSettingsApp();
// 添加全局错误处理
window.addEventListener('error', function(e) {
console.error('应用错误:', e.error);
app.showNotification('应用出现错误,请刷新页面', 'error');
});
// 添加未处理的Promise错误
window.addEventListener('unhandledrejection', function(e) {
console.error('未处理的Promise错误:', e.reason);
app.showNotification('网络请求失败,请检查网络连接', 'error');
});
});
// 导出到全局作用域
window.EnterpriseSettingsApp = EnterpriseSettingsApp;

774
background/settings.html Normal file
View File

@@ -0,0 +1,774 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>企业设置管理系统 - 设置面板</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Sans SC', sans-serif;
}
.liquid-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.liquid-metal {
position: absolute;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.15) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(120, 119, 198, 0.4) 0%, transparent 50%);
animation: liquidFlow 20s ease-in-out infinite;
}
@keyframes liquidFlow {
0%, 100% { transform: translate(0, 0) rotate(0deg); }
33% { transform: translate(-20px, -20px) rotate(1deg); }
66% { transform: translate(20px, -10px) rotate(-1deg); }
}
.sidebar {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border-right: 1px solid rgba(255, 255, 255, 0.2);
}
.main-content {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
}
.glass-card {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.glass-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
.nav-item {
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.nav-item:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateX(5px);
}
.nav-item.active {
background: rgba(74, 144, 226, 0.2);
border-left: 4px solid #4A90E2;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #4A90E2;
}
input:checked + .slider:before {
transform: translateX(26px);
}
.range-slider {
-webkit-appearance: none;
width: 100%;
height: 8px;
border-radius: 5px;
background: #ddd;
outline: none;
transition: all 0.3s ease;
}
.range-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #4A90E2;
cursor: pointer;
box-shadow: 0 2px 10px rgba(74, 144, 226, 0.3);
transition: all 0.3s ease;
}
.range-slider::-webkit-slider-thumb:hover {
transform: scale(1.2);
box-shadow: 0 4px 15px rgba(74, 144, 226, 0.5);
}
.btn-primary {
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(74, 144, 226, 0.3);
}
.btn-secondary {
background: linear-gradient(135deg, #718096 0%, #4A5568 100%);
transition: all 0.3s ease;
}
.btn-secondary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(113, 128, 150, 0.3);
}
.form-input {
border: 2px solid #e2e8f0;
transition: all 0.3s ease;
}
.form-input:focus {
border-color: #4A90E2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
transform: translateY(-1px);
}
.section-fade {
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.toast {
position: fixed;
top: 20px;
right: 20px;
z-index: 1000;
transform: translateX(400px);
transition: all 0.3s ease;
}
.toast.show {
transform: translateX(0);
}
</style>
</head>
<body class="min-h-screen flex overflow-hidden">
<!-- Background -->
<div class="liquid-bg">
<div class="liquid-metal"></div>
</div>
<!-- Sidebar -->
<div class="sidebar w-80 h-screen flex flex-col">
<!-- Logo -->
<div class="p-6 border-b border-white/20">
<div class="flex items-center space-x-3">
<div class="w-12 h-12 bg-gradient-to-br from-blue-400 to-blue-600 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-4m-5 0H9m0 0H5m0 0h2M7 7h10M7 11h10M7 15h10"></path>
</svg>
</div>
<div>
<h2 class="text-white font-bold text-lg">企业设置中心</h2>
<p class="text-blue-200 text-sm" id="companyName">企业管理系统</p>
</div>
</div>
</div>
<!-- Navigation -->
<nav class="flex-1 p-4">
<ul class="space-y-2">
<li class="nav-item active rounded-xl p-3 cursor-pointer" data-section="traffic">
<div class="flex items-center space-x-3">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="text-white font-medium">交通管理设置</span>
</div>
</li>
<li class="nav-item rounded-xl p-3 cursor-pointer" data-section="vehicle">
<div class="flex items-center space-x-3">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"></path>
</svg>
<span class="text-white font-medium">车辆管理设置</span>
</div>
</li>
<li class="nav-item rounded-xl p-3 cursor-pointer" data-section="safety">
<div class="flex items-center space-x-3">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
<span class="text-white font-medium">安全设置</span>
</div>
</li>
<li class="nav-item rounded-xl p-3 cursor-pointer" data-section="company">
<div class="flex items-center space-x-3">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-4m-5 0H9m0 0H5m0 0h2M7 7h10M7 11h10M7 15h10"></path>
</svg>
<span class="text-white font-medium">企业信息</span>
</div>
</li>
</ul>
</nav>
<!-- User Info -->
<div class="p-6 border-t border-white/20">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 bg-gradient-to-br from-green-400 to-green-600 rounded-full flex items-center justify-center">
<span class="text-white font-bold text-sm" id="userInitial"></span>
</div>
<div class="flex-1">
<p class="text-white font-medium text-sm" id="userName">管理员</p>
<p class="text-blue-200 text-xs">在线</p>
</div>
<button id="logoutBtn" class="text-white hover:text-red-300 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"></path>
</svg>
</button>
</div>
</div>
</div>
<!-- Main Content -->
<div class="main-content flex-1 overflow-y-auto">
<!-- Header -->
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-800" id="sectionTitle">交通管理设置</h1>
<p class="text-gray-600 text-sm mt-1" id="sectionDescription">配置企业交通管理相关参数</p>
</div>
<div class="flex space-x-3">
<button id="resetBtn" class="btn-secondary px-6 py-2 rounded-xl text-white font-medium">
重置设置
</button>
<button id="saveBtn" class="btn-primary px-6 py-2 rounded-xl text-white font-medium">
保存设置
</button>
</div>
</div>
</div>
<!-- Content Sections -->
<div class="p-6">
<!-- Traffic Management Section -->
<div id="traffic-section" class="section-content">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Parking Settings -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-red-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728L5.636 5.636m12.728 12.728L18.364 5.636M5.636 18.364l12.728-12.728"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">禁停设置</h3>
<p class="text-gray-600 text-sm">是否禁止车辆停放</p>
</div>
</div>
<div class="flex items-center justify-between">
<span class="text-gray-700">启用禁停</span>
<label class="switch">
<input type="checkbox" id="noParking" class="setting-toggle">
<span class="slider"></span>
</label>
</div>
<div class="mt-4 p-3 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">启用后,企业区域内将禁止所有车辆停放。</p>
</div>
</div>
<!-- Traffic Settings -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-orange-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">禁行设置</h3>
<p class="text-gray-600 text-sm">是否禁止车辆通行</p>
</div>
</div>
<div class="flex items-center justify-between">
<span class="text-gray-700">启用禁行</span>
<label class="switch">
<input type="checkbox" id="noTraffic" class="setting-toggle">
<span class="slider"></span>
</label>
</div>
<div class="mt-4 p-3 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">启用后,企业区域内将禁止所有车辆通行。</p>
</div>
</div>
<!-- Danger Source Settings -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-yellow-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">危险源设置</h3>
<p class="text-gray-600 text-sm">是否标记为危险源</p>
</div>
</div>
<div class="flex items-center justify-between">
<span class="text-gray-700">危险源标记</span>
<label class="switch">
<input type="checkbox" id="dangerSource" class="setting-toggle">
<span class="slider"></span>
</label>
</div>
<div class="mt-4 p-3 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">标记后,系统将对此区域进行特殊安全监控。</p>
</div>
</div>
</div>
</div>
<!-- Vehicle Management Section -->
<div id="vehicle-section" class="section-content hidden">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Parking Capacity -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-blue-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">可停车辆数</h3>
<p class="text-gray-600 text-sm">设置最大停车数量</p>
</div>
</div>
<div class="space-y-4">
<input
type="number"
id="parkingCapacity"
class="form-input w-full px-4 py-3 rounded-xl focus:outline-none"
min="0"
max="1000"
value="50"
>
<div class="flex items-center justify-between text-sm text-gray-600">
<span>当前设置</span>
<span id="parkingCapacityValue" class="font-semibold text-blue-600">50 辆</span>
</div>
</div>
</div>
<!-- Traffic Capacity -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-green-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">可行车辆数</h3>
<p class="text-gray-600 text-sm">设置最大通行数量</p>
</div>
</div>
<div class="space-y-4">
<input
type="number"
id="trafficCapacity"
class="form-input w-full px-4 py-3 rounded-xl focus:outline-none"
min="0"
max="1000"
value="100"
>
<div class="flex items-center justify-between text-sm text-gray-600">
<span>当前设置</span>
<span id="trafficCapacityValue" class="font-semibold text-green-600">100 辆</span>
</div>
</div>
</div>
</div>
</div>
<!-- Safety Settings Section -->
<div id="safety-section" class="section-content hidden">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Speed Limit -->
<div class="glass-card rounded-2xl p-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-red-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">最大限速</h3>
<p class="text-gray-600 text-sm">设置最高允许车速</p>
</div>
</div>
<div class="space-y-4">
<div class="flex items-center space-x-4">
<input
type="range"
id="speedLimit"
class="range-slider flex-1"
min="10"
max="120"
value="60"
>
<div class="text-2xl font-bold text-red-600 min-w-[60px]" id="speedLimitValue">60</div>
<span class="text-gray-600">km/h</span>
</div>
<div class="p-3 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">建议根据企业区域特点设置合适的限速值。</p>
</div>
</div>
</div>
</div>
</div>
<!-- Company Info Section -->
<div id="company-section" class="section-content hidden">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Company Products -->
<div class="glass-card rounded-2xl p-6 lg:col-span-2">
<div class="flex items-center space-x-3 mb-4">
<div class="w-12 h-12 bg-purple-100 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-4m-5 0H9m0 0H5m0 0h2M7 7h10M7 11h10M7 15h10"></path>
</svg>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">企业产品</h3>
<p class="text-gray-600 text-sm">描述企业主要产品和服务</p>
</div>
</div>
<div class="space-y-4">
<textarea
id="companyProducts"
class="form-input w-full px-4 py-3 rounded-xl focus:outline-none h-32 resize-none"
placeholder="请输入企业主要产品和服务描述..."
>我们专注于提供高质量的企业管理解决方案,包括智能交通管理系统、企业资源规划系统、安全监控系统等。致力于为各类企业提供全方位的数字化转型服务。</textarea>
<div class="flex items-center justify-between text-sm text-gray-600">
<span>字符统计</span>
<span id="charCount" class="font-semibold text-purple-600">0 字符</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Toast Notification -->
<div id="toast" class="toast bg-white rounded-xl shadow-lg p-4 max-w-sm">
<div class="flex items-center space-x-3">
<div id="toastIcon" class="w-8 h-8 rounded-full flex items-center justify-center">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<div>
<p id="toastMessage" class="font-medium text-gray-800">设置已保存</p>
<p class="text-sm text-gray-600">更改已成功应用到系统</p>
</div>
</div>
</div>
<script>
// 设置数据管理
class SettingsManager {
constructor() {
this.settings = this.loadSettings();
this.init();
}
init() {
this.bindEvents();
this.loadUserInfo();
this.showSection('traffic');
this.updateAllValues();
}
loadSettings() {
const defaultSettings = {
noParking: false,
noTraffic: false,
dangerSource: false,
parkingCapacity: 50,
trafficCapacity: 100,
speedLimit: 60,
companyProducts: '我们专注于提供高质量的企业管理解决方案,包括智能交通管理系统、企业资源规划系统、安全监控系统等。致力于为各类企业提供全方位的数字化转型服务。'
};
const saved = localStorage.getItem('companySettings');
return saved ? { ...defaultSettings, ...JSON.parse(saved) } : defaultSettings;
}
saveSettings() {
localStorage.setItem('companySettings', JSON.stringify(this.settings));
this.showToast('设置已保存', 'success');
}
loadUserInfo() {
const loginData = localStorage.getItem('companyLogin') || sessionStorage.getItem('companyLogin');
if (loginData) {
const data = JSON.parse(loginData);
document.getElementById('companyName').textContent = data.companyId || '企业管理系统';
document.getElementById('userInitial').textContent = (data.companyId || '企业').charAt(0);
}
}
bindEvents() {
// 导航切换
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', (e) => {
const section = e.currentTarget.dataset.section;
this.showSection(section);
this.updateNavigation(e.currentTarget);
});
});
// 开关切换
document.querySelectorAll('.setting-toggle').forEach(toggle => {
toggle.addEventListener('change', (e) => {
this.settings[e.target.id] = e.target.checked;
this.animateToggle(e.target);
});
});
// 数值输入
document.getElementById('parkingCapacity').addEventListener('input', (e) => {
this.settings.parkingCapacity = parseInt(e.target.value) || 0;
document.getElementById('parkingCapacityValue').textContent = `${e.target.value}`;
});
document.getElementById('trafficCapacity').addEventListener('input', (e) => {
this.settings.trafficCapacity = parseInt(e.target.value) || 0;
document.getElementById('trafficCapacityValue').textContent = `${e.target.value}`;
});
document.getElementById('speedLimit').addEventListener('input', (e) => {
this.settings.speedLimit = parseInt(e.target.value) || 0;
document.getElementById('speedLimitValue').textContent = e.target.value;
});
document.getElementById('companyProducts').addEventListener('input', (e) => {
this.settings.companyProducts = e.target.value;
document.getElementById('charCount').textContent = `${e.target.value.length} 字符`;
});
// 按钮事件
document.getElementById('saveBtn').addEventListener('click', () => {
this.saveSettings();
});
document.getElementById('resetBtn').addEventListener('click', () => {
this.resetSettings();
});
document.getElementById('logoutBtn').addEventListener('click', () => {
this.logout();
});
}
showSection(sectionName) {
// 隐藏所有区域
document.querySelectorAll('.section-content').forEach(section => {
section.classList.add('hidden');
});
// 显示选中区域
const targetSection = document.getElementById(`${sectionName}-section`);
if (targetSection) {
targetSection.classList.remove('hidden');
targetSection.classList.add('section-fade');
// 更新标题
const titles = {
traffic: { title: '交通管理设置', desc: '配置企业交通管理相关参数' },
vehicle: { title: '车辆管理设置', desc: '管理企业区域内车辆容量配置' },
safety: { title: '安全设置', desc: '设置企业安全相关参数' },
company: { title: '企业信息', desc: '管理企业基本信息和产品描述' }
};
const info = titles[sectionName];
document.getElementById('sectionTitle').textContent = info.title;
document.getElementById('sectionDescription').textContent = info.desc;
}
}
updateNavigation(activeItem) {
document.querySelectorAll('.nav-item').forEach(item => {
item.classList.remove('active');
});
activeItem.classList.add('active');
}
updateAllValues() {
// 更新开关状态
document.getElementById('noParking').checked = this.settings.noParking;
document.getElementById('noTraffic').checked = this.settings.noTraffic;
document.getElementById('dangerSource').checked = this.settings.dangerSource;
// 更新数值输入
document.getElementById('parkingCapacity').value = this.settings.parkingCapacity;
document.getElementById('trafficCapacity').value = this.settings.trafficCapacity;
document.getElementById('speedLimit').value = this.settings.speedLimit;
document.getElementById('companyProducts').value = this.settings.companyProducts;
// 更新显示值
document.getElementById('parkingCapacityValue').textContent = `${this.settings.parkingCapacity}`;
document.getElementById('trafficCapacityValue').textContent = `${this.settings.trafficCapacity}`;
document.getElementById('speedLimitValue').textContent = this.settings.speedLimit;
document.getElementById('charCount').textContent = `${this.settings.companyProducts.length} 字符`;
}
animateToggle(toggle) {
const slider = toggle.nextElementSibling;
anime({
targets: slider,
scale: [1, 1.1, 1],
duration: 300,
easing: 'easeOutQuad'
});
}
resetSettings() {
if (confirm('确定要重置所有设置为默认值吗?')) {
localStorage.removeItem('companySettings');
this.settings = this.loadSettings();
this.updateAllValues();
this.showToast('设置已重置', 'info');
}
}
logout() {
if (confirm('确定要退出登录吗?')) {
localStorage.removeItem('companyLogin');
sessionStorage.removeItem('companyLogin');
window.location.href = 'login.html';
}
}
showToast(message, type = 'success') {
const toast = document.getElementById('toast');
const toastMessage = document.getElementById('toastMessage');
const toastIcon = document.getElementById('toastIcon');
toastMessage.textContent = message;
// 设置图标和颜色
const colors = {
success: 'bg-green-500',
error: 'bg-red-500',
info: 'bg-blue-500',
warning: 'bg-yellow-500'
};
toastIcon.className = `w-8 h-8 rounded-full flex items-center justify-center ${colors[type] || colors.success}`;
// 显示toast
toast.classList.add('show');
// 3秒后隐藏
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
}
// 初始化应用
document.addEventListener('DOMContentLoaded', function() {
// 检查登录状态
const loginData = localStorage.getItem('companyLogin') || sessionStorage.getItem('companyLogin');
if (!loginData) {
window.location.href = 'login.html';
return;
}
// 初始化设置管理器
new SettingsManager();
// 添加页面加载动画
anime({
targets: '.glass-card',
opacity: [0, 1],
translateY: [30, 0],
delay: anime.stagger(100),
duration: 600,
easing: 'easeOutQuad'
});
});
</script>
</body>
</html>