MOP数据库备份脚本生成工具

核心代码如下:

bash 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多数据库备份脚本生成工具</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        :root {
            --primary: #2c3e50;
            --secondary: #4a6491;
            --accent: #4fc3f7;
            --success: #38a169;
            --warning: #dd6b20;
            --danger: #e53e3e;
            --light: #f8f9fa;
            --dark: #1a2a6c;
            --postgres: #336791;
            --sqlserver: #0078d7;
            --converter: #9c27b0;
            --modifier: #ff9800;
            --scheduler: #2196f3;
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background: linear-gradient(135deg, #1a2a6c, #2c3e50);
            color: #333;
            min-height: 100vh;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .container {
            max-width: 1400px;
            width: 100%;
            background: rgba(255, 255, 255, 0.97);
            border-radius: 15px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4);
            overflow: hidden;
        }
        
        header {
            background: linear-gradient(90deg, var(--primary), var(--secondary));
            color: white;
            padding: 25px 40px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            position: relative;
            overflow: hidden;
        }
        
        .logo {
            display: flex;
            align-items: center;
            gap: 15px;
            z-index: 2;
        }
        
        .logo i {
            font-size: 2.8rem;
            color: var(--accent);
            text-shadow: 0 0 10px rgba(79, 195, 247, 0.5);
            animation: pulse 2s infinite;
        }
        
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.1); }
            100% { transform: scale(1); }
        }
        
        .logo h1 {
            font-size: 2.4rem;
            font-weight: 800;
            letter-spacing: 0.5px;
        }
        
        .subtitle {
            font-size: 1.1rem;
            opacity: 0.9;
            margin-top: 5px;
        }
        
        .header-pattern {
            position: absolute;
            top: -50px;
            right: -50px;
            opacity: 0.1;
            font-size: 10rem;
            transform: rotate(15deg);
            z-index: 1;
        }
        
        .main-content {
            display: flex;
            min-height: 700px;
        }
        
        .sidebar {
            width: 300px;
            background: var(--primary);
            color: white;
            padding: 25px 0;
            position: relative;
            z-index: 2;
        }
        
        .sidebar::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 5px;
            background: linear-gradient(90deg, var(--accent), #1a9fff);
        }
        
        .sidebar-section {
            margin-bottom: 25px;
        }
        
        .sidebar-title {
            padding: 12px 25px;
            font-size: 1.1rem;
            font-weight: 600;
            color: var(--accent);
            border-bottom: 1px solid #3a506b;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .sidebar-option {
            padding: 14px 35px;
            cursor: pointer;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 12px;
            position: relative;
        }
        
        .sidebar-option:hover {
            background: rgba(58, 80, 107, 0.7);
        }
        
        .sidebar-option.active {
            background: rgba(74, 100, 145, 0.9);
            border-left: 4px solid var(--accent);
        }
        
        .sidebar-option i {
            width: 25px;
            text-align: center;
            font-size: 1.1rem;
        }
        
        .sidebar-option::after {
            content: "";
            position: absolute;
            left: 25px;
            right: 25px;
            bottom: 0;
            height: 1px;
            background: rgba(255, 255, 255, 0.05);
        }
        
        .content-area {
            flex: 1;
            padding: 30px;
            display: flex;
            flex-direction: column;
            background: #fafcff;
        }
        
        .tab-content {
            display: none;
            flex: 1;
        }
        
        .tab-content.active {
            display: flex;
            flex-direction: column;
            animation: fadeIn 0.5s;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        .section-title {
            font-size: 1.8rem;
            margin-bottom: 25px;
            color: var(--primary);
            padding-bottom: 15px;
            border-bottom: 2px solid var(--secondary);
            display: flex;
            align-items: center;
            gap: 15px;
        }
        
        .config-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
            gap: 30px;
            margin-bottom: 30px;
        }
        
        .config-card {
            background: white;
            border-radius: 12px;
            box-shadow: 0 7px 20px rgba(0, 0, 0, 0.08);
            padding: 28px;
            border: 1px solid #e0e6ed;
            transition: transform 0.3s, box-shadow 0.3s;
            position: relative;
            overflow: hidden;
        }
        
        .config-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 12px 25px rgba(0, 0, 0, 0.12);
        }
        
        .card-title {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.35rem;
            margin-bottom: 22px;
            color: var(--primary);
            padding-bottom: 12px;
            border-bottom: 1px solid #e2e8f0;
        }
        
        .card-title i {
            color: var(--secondary);
            font-size: 1.4rem;
        }
        
        .form-group {
            margin-bottom: 22px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 10px;
            font-weight: 600;
            color: #4a5568;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .form-group label i {
            color: var(--secondary);
            font-size: 0.9rem;
        }
        
        .form-group input, 
        .form-group select,
        .form-group textarea {
            width: 100%;
            padding: 14px 16px;
            border: 1px solid #cbd5e0;
            border-radius: 10px;
            font-size: 1.05rem;
            transition: all 0.3s;
            background: #f8fafc;
        }
        
        .form-group input:focus, 
        .form-group select:focus,
        .form-group textarea:focus {
            border-color: var(--secondary);
            outline: none;
            box-shadow: 0 0 0 3px rgba(74, 100, 145, 0.2);
            background: white;
        }
        
        .checkbox-group {
            display: flex;
            align-items: center;
            gap: 12px;
            margin: 18px 0;
        }
        
        .checkbox-group input {
            width: auto;
            transform: scale(1.2);
        }
        
        .btn {
            padding: 14px 28px;
            border: none;
            border-radius: 10px;
            font-size: 1.05rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s;
            display: inline-flex;
            align-items: center;
            gap: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        
        .btn-primary {
            background: linear-gradient(90deg, var(--secondary), var(--primary));
            color: white;
        }
        
        .btn-primary:hover {
            background: linear-gradient(90deg, var(--primary), var(--secondary));
            box-shadow: 0 7px 14px rgba(44, 62, 80, 0.4);
            transform: translateY(-2px);
        }
        
        .btn-secondary {
            background: #e0e6ed;
            color: #4a5568;
        }
        
        .btn-secondary:hover {
            background: #cbd5e0;
            transform: translateY(-2px);
        }
        
        .btn-success {
            background: linear-gradient(90deg, var(--success), #2f9e58);
            color: white;
        }
        
        .btn-success:hover {
            background: linear-gradient(90deg, #2f9e58, var(--success));
            transform: translateY(-2px);
        }
        
        .btn-postgres {
            background: linear-gradient(90deg, var(--postgres), #2a5b80);
            color: white;
        }
        
        .btn-sqlserver {
            background: linear-gradient(90deg, var(--sqlserver), #0066b4);
            color: white;
        }
        
        .btn-converter {
            background: linear-gradient(90deg, var(--converter), #7b1fa2);
            color: white;
        }
        
        .btn-modifier {
            background: linear-gradient(90deg, var(--modifier), #ef6c00);
            color: white;
        }
        
        .btn-scheduler {
            background: linear-gradient(90deg, var(--scheduler), #0d47a1);
            color: white;
        }
        
        .action-buttons {
            display: flex;
            gap: 18px;
            margin-top: 30px;
            flex-wrap: wrap;
        }
        
        .report-section {
            margin-top: 40px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 7px 20px rgba(0, 0, 0, 0.08);
            padding: 30px;
            border: 1px solid #e0e6ed;
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        
        .report-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 25px;
        }
        
        .report-content {
            background: #f8f9fa;
            border: 1px solid #e2e8f0;
            border-radius: 10px;
            padding: 25px;
            font-family: 'Consolas', 'Courier New', monospace;
            white-space: pre-wrap;
            flex: 1;
            overflow-y: auto;
            line-height: 1.5;
            font-size: 0.95rem;
            color: #2d3748;
            position: relative;
            min-height: 250px;
        }
        
        .report-content::before {
            content: "> 生成的备份脚本";
            position: absolute;
            top: -12px;
            left: 15px;
            background: #f8f9fa;
            padding: 0 10px;
            color: var(--secondary);
            font-size: 0.85rem;
            font-weight: 600;
        }
        
        .copy-btn {
            position: absolute;
            top: 15px;
            right: 15px;
            padding: 8px 16px;
            background: rgba(255, 255, 255, 0.9);
            border: 1px solid #cbd5e0;
            border-radius: 6px;
            font-size: 0.85rem;
            cursor: pointer;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        
        .copy-btn:hover {
            background: var(--secondary);
            color: white;
            border-color: var(--secondary);
        }
        
        .tables-list {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 10px;
        }
        
        .table-tag {
            background: #e2e8f0;
            padding: 5px 12px;
            border-radius: 20px;
            font-size: 0.9rem;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .table-tag i {
            cursor: pointer;
            color: var(--danger);
            font-size: 0.8rem;
        }
        
        footer {
            text-align: center;
            padding: 20px;
            background: var(--primary);
            color: #a0aec0;
            font-size: 0.95rem;
        }
        
        .database-icon {
            width: 45px;
            height: 45px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            color: white;
            font-size: 1.3rem;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        
        .oracle-icon {
            background: #c74634;
        }
        
        .mysql-icon {
            background: #f29111;
        }
        
        .postgres-icon {
            background: var(--postgres);
        }
        
        .sqlserver-icon {
            background: var(--sqlserver);
        }
        
        .status-indicator {
            display: flex;
            align-items: center;
            gap: 12px;
            margin-top: 15px;
            font-weight: 600;
            padding: 12px;
            border-radius: 8px;
            background: #f0f7ff;
        }
        
        .success {
            color: var(--success);
        }
        
        .warning {
            color: var(--warning);
        }
        
        .error {
            color: var(--danger);
        }
        
        .backup-type {
            display: flex;
            gap: 15px;
            margin-bottom: 20px;
            background: #f0f7ff;
            padding: 15px;
            border-radius: 10px;
        }
        
        .backup-type-btn {
            flex: 1;
            padding: 15px;
            text-align: center;
            border-radius: 8px;
            background: #e2e8f0;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: 600;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 10px;
        }
        
        .backup-type-btn.active {
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
        }
        
        .backup-type-btn i {
            font-size: 1.8rem;
        }
        
        .backup-type-btn.physical.active {
            background: var(--secondary);
            color: white;
        }
        
        .backup-type-btn.logical.active {
            background: var(--success);
            color: white;
        }
        
        .tool-content {
            padding: 20px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 7px 20px rgba(0, 0, 0, 0.08);
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        
        .tool-title {
            font-size: 1.8rem;
            margin-bottom: 20px;
            color: var(--primary);
            display: flex;
            align-items: center;
            gap: 15px;
        }
        
        .tool-description {
            margin-bottom: 30px;
            line-height: 1.6;
            color: #4a5568;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border-left: 4px solid var(--accent);
        }
        
        .tool-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 25px;
            margin-bottom: 30px;
        }
        
        .tool-card {
            background: white;
            border-radius: 12px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            padding: 25px;
            border: 1px solid #e2e8f0;
            transition: all 0.3s;
        }
        
        .tool-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
        }
        
        .tool-card h3 {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.4rem;
            margin-bottom: 20px;
            color: var(--primary);
            padding-bottom: 12px;
            border-bottom: 1px solid #e2e8f0;
        }
        
        .tool-card p {
            color: #4a5568;
            line-height: 1.6;
            margin-bottom: 20px;
        }
        
        .tool-feature {
            background: white;
            border-radius: 12px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            padding: 25px;
            margin-bottom: 25px;
            border: 1px solid #e2e8f0;
            transition: all 0.3s;
        }
        
        .tool-feature:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
        }
        
        .tool-feature h3 {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.4rem;
            margin-bottom: 20px;
            color: var(--primary);
            padding-bottom: 12px;
            border-bottom: 1px solid #e2e8f0;
        }
        
        .converter-feature h3 {
            color: var(--converter);
        }
        
        .modifier-feature h3 {
            color: var(--modifier);
        }
        
        .scheduler-feature h3 {
            color: var(--scheduler);
        }
        
        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 15px 25px;
            border-radius: 8px;
            background: var(--success);
            color: white;
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            z-index: 1000;
            display: flex;
            align-items: center;
            gap: 10px;
            transform: translateX(150%);
            transition: transform 0.3s ease-out;
        }
        
        .notification.show {
            transform: translateX(0);
        }
        
        .notification i {
            font-size: 1.2rem;
        }
        
        .database-selector {
            display: flex;
            flex-direction: column;
            gap: 15px;
            margin-bottom: 20px;
        }
        
        .database-item {
            display: flex;
            align-items: center;
            padding: 12px;
            border: 1px solid #e2e8f0;
            border-radius: 8px;
            background: #f8f9fa;
            cursor: pointer;
            transition: all 0.3s;
        }
        
        .database-item:hover {
            background: #edf2f7;
        }
        
        .database-item.selected {
            background: #ebf8ff;
            border-color: var(--accent);
        }
        
        .database-item input {
            margin-right: 12px;
        }
        
        .database-item label {
            flex: 1;
            cursor: pointer;
        }
        
        .database-item .tables-list {
            flex: 1;
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
        }
        
        .table-item {
            background: #e2e8f0;
            padding: 5px 12px;
            border-radius: 20px;
            font-size: 0.9rem;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .table-item.selected {
            background: var(--accent);
            color: white;
        }
        
        .custom-db-input {
            margin-top: 15px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border: 1px solid #e2e8f0;
        }
        
        .input-hint {
            font-size: 0.9rem;
            color: #718096;
            margin-top: 8px;
            margin-bottom: 15px;
        }
        
        .input-example {
            background: #edf2f7;
            padding: 8px 12px;
            border-radius: 6px;
            font-size: 0.85rem;
            margin-top: 8px;
        }
        
        @media (max-width: 900px) {
            .main-content {
                flex-direction: column;
            }
            
            .sidebar {
                width: 100%;
            }
            
            .config-grid {
                grid-template-columns: 1fr;
            }
            
            .backup-type {
                flex-direction: column;
            }
            
            .action-buttons {
                flex-direction: column;
            }
            
            .database-icons {
                display: none;
            }
            
            header {
                flex-direction: column;
                gap: 20px;
                text-align: center;
            }
            
            .notification {
                top: 10px;
                right: 10px;
                left: 10px;
                text-align: center;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <div class="logo">
                <i class="fas fa-database"></i>
                <div>
                    <h1>多数据库备份脚本生成工具</h1>
                    <div class="subtitle">支持Oracle, MySQL, PostgreSQL, SQL Server | 物理与逻辑备份 | 按库/表备份</div>
                </div>
            </div>
            <div class="database-icons">
                <div style="display: flex; gap: 15px;">
                    <div class="database-icon oracle-icon"><i class="fab fa-oracle"></i></div>
                    <div class="database-icon mysql-icon"><i class="fas fa-database"></i></div>
                    <div class="database-icon postgres-icon"><i class="fas fa-server"></i></div>
                    <div class="database-icon sqlserver-icon"><i class="fab fa-microsoft"></i></div>
                </div>
            </div>
            <div class="header-pattern">
                <i class="fas fa-code"></i>
            </div>
        </header>
        
        <div class="main-content">
            <div class="sidebar">
                <div class="sidebar-section">
                    <div class="sidebar-title">
                        <i class="fas fa-database"></i>
                        数据库类型
                    </div>
                    <div class="sidebar-option active" data-tab="oracle">
                        <i class="fab fa-oracle"></i>
                        Oracle
                    </div>
                    <div class="sidebar-option" data-tab="mysql">
                        <i class="fas fa-database"></i>
                        MySQL
                    </div>
                    <div class="sidebar-option" data-tab="postgres">
                        <i class="fas fa-server"></i>
                        PostgreSQL
                    </div>
                    <div class="sidebar-option" data-tab="sqlserver">
                        <i class="fab fa-microsoft"></i>
                        SQL Server
                    </div>
                </div>
                
                <div class="sidebar-section">
                    <div class="sidebar-title">
                        <i class="fas fa-tools"></i>
                        工具功能
                    </div>
                    <!-- 已移除脚本转换器 -->
                    <div class="sidebar-option" data-tab="modifier">
                        <i class="fas fa-edit"></i>
                        脚本修改器
                    </div>
                    <div class="sidebar-option" data-tab="scheduler">
                        <i class="fas fa-calendar-alt"></i>
                        计划任务生成
                    </div>
                </div>
                
                <div class="sidebar-section">
                    <div class="sidebar-title">
                        <i class="fas fa-history"></i>
                        最近脚本
                    </div>
                    <div class="sidebar-option">
                        <i class="fas fa-file-code"></i>
                        oracle_full_backup.sh
                    </div>
                    <div class="sidebar-option">
                        <i class="fas fa-file-code"></i>
                        mysql_tables_backup.sql
                    </div>
                    <div class="sidebar-option">
                        <i class="fas fa-file-code"></i>
                        pg_daily_backup.sh
                    </div>
                </div>
            </div>
            
            <div class="content-area">
                <!-- Oracle 配置 -->
                <div class="tab-content active" id="oracle">
                    <h2 class="section-title"><i class="fab fa-oracle"></i> Oracle 备份配置</h2>
                    
                    <div class="backup-type">
                        <div class="backup-type-btn physical active" data-type="physical">
                            <i class="fas fa-hard-drive"></i>
                            物理备份
                        </div>
                        <div class="backup-type-btn logical" data-type="logical">
                            <i class="fas fa-file-code"></i>
                            逻辑备份
                        </div>
                    </div>
                    
                    <div class="config-grid">
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-plug"></i> 连接设置</h3>
                            <div class="form-group">
                                <label for="oracle-host"><i class="fas fa-server"></i> 主机地址</label>
                                <input type="text" id="oracle-host" placeholder="例如: 192.168.1.100" value="dbserver01">
                            </div>
                            <div class="form-group">
                                <label for="oracle-port"><i class="fas fa-network-wired"></i> 端口</label>
                                <input type="text" id="oracle-port" value="1521">
                            </div>
                            <div class="form-group">
                                <label for="oracle-service"><i class="fas fa-cog"></i> 服务名/SID</label>
                                <input type="text" id="oracle-service" placeholder="例如: ORCL" value="ORCL">
                            </div>
                            <div class="form-group">
                                <label for="oracle-user"><i class="fas fa-user"></i> 用户名</label>
                                <input type="text" id="oracle-user" placeholder="例如: sys" value="sys as sysdba">
                            </div>
                            <div class="form-group">
                                <label for="oracle-password"><i class="fas fa-key"></i> 密码</label>
                                <input type="password" id="oracle-password" placeholder="输入密码" value="********">
                            </div>
                        </div>
                        
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-cog"></i> 备份设置</h3>
                            <div class="form-group">
                                <label for="oracle-backup-path"><i class="fas fa-folder-open"></i> 备份路径</label>
                                <input type="text" id="oracle-backup-path" value="/backup/oracle/">
                            </div>
                            
                            <!-- 物理备份特定设置 -->
                            <div class="backup-options physical active">
                                <div class="form-group">
                                    <label for="oracle-parallel"><i class="fas fa-microchip"></i> 并行度</label>
                                    <input type="number" id="oracle-parallel" min="1" max="16" value="4">
                                </div>
                                <div class="form-group">
                                    <label for="oracle-compression"><i class="fas fa-compress"></i> 压缩级别</label>
                                    <select id="oracle-compression">
                                        <option value="low">低</option>
                                        <option value="medium" selected>中</option>
                                        <option value="high">高</option>
                                    </select>
                                </div>
                            </div>
                            
                            <!-- 逻辑备份特定设置 - 自定义输入 -->
                            <div class="backup-options logical">
                                <div class="form-group">
                                    <label><i class="fas fa-database"></i> 数据库和表配置</label>
                                    <div class="custom-db-input">
                                        <div class="input-hint">
                                            输入格式:数据库名:表1,表2,表3(每行一个数据库)
                                        </div>
                                        <textarea id="oracle-db-config" rows="4" placeholder="例如:
APP_DB:USERS,ORDERS,PRODUCTS
REPORT_DB:SALES,INVENTORY">APP_DB:USERS,ORDERS</textarea>
                                        <div class="input-example">
                                            示例:<br>
                                            HR_DB:EMPLOYEES,DEPARTMENTS<br>
                                            FINANCE_DB:ACCOUNTS,TRANSACTIONS
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <div class="form-group">
                                <label>高级选项</label>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="oracle-encryption">
                                    <label for="oracle-encryption">启用加密</label>
                                </div>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="oracle-validate" checked>
                                    <label for="oracle-validate">备份后验证</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="action-buttons">
                        <button class="btn btn-primary" id="generate-oracle">
                            <i class="fas fa-code"></i> 生成备份脚本
                        </button>
                        <button class="btn btn-secondary">
                            <i class="fas fa-save"></i> 保存配置
                        </button>
                    </div>
                    
                    <div class="report-section">
                        <div class="report-header">
                            <h3 class="section-title"><i class="fas fa-file-code"></i> 生成的备份脚本</h3>
                        </div>
                        
                        <div class="report-content" id="oracle-script">
                            <!-- 生成的脚本将显示在这里 -->
                        </div>
                    </div>
                </div>
                
                <!-- MySQL 配置 -->
                <div class="tab-content" id="mysql">
                    <h2 class="section-title"><i class="fas fa-database"></i> MySQL 备份配置</h2>
                    
                    <div class="backup-type">
                        <div class="backup-type-btn physical active" data-type="physical">
                            <i class="fas fa-hard-drive"></i>
                            物理备份
                        </div>
                        <div class="backup-type-btn logical" data-type="logical">
                            <i class="fas fa-file-code"></i>
                            逻辑备份
                        </div>
                    </div>
                    
                    <div class="config-grid">
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-plug"></i> 连接设置</h3>
                            <div class="form-group">
                                <label for="mysql-host"><i class="fas fa-server"></i> 主机地址</label>
                                <input type="text" id="mysql-host" placeholder="例如: 192.168.1.100" value="db-mysql-01">
                            </div>
                            <div class="form-group">
                                <label for="mysql-port"><i class="fas fa-network-wired"></i> 端口</label>
                                <input type="text" id="mysql-port" value="3306">
                            </div>
                            <div class="form-group">
                                <label for="mysql-db"><i class="fas fa-database"></i> 数据库名</label>
                                <input type="text" id="mysql-db" placeholder="例如: app_db" value="app_db">
                            </div>
                            <div class="form-group">
                                <label for="mysql-user"><i class="fas fa-user"></i> 用户名</label>
                                <input type="text" id="mysql-user" placeholder="例如: root" value="admin">
                            </div>
                            <div class="form-group">
                                <label for="mysql-password"><i class="fas fa-key"></i> 密码</label>
                                <input type="password" id="mysql-password" placeholder="输入密码" value="********">
                            </div>
                        </div>
                        
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-cog"></i> 备份设置</h3>
                            <div class="form-group">
                                <label for="mysql-backup-path"><i class="fas fa-folder-open"></i> 备份路径</label>
                                <input type="text" id="mysql-backup-path" value="/backup/mysql/">
                            </div>
                            
                            <!-- 物理备份特定设置 -->
                            <div class="backup-options physical active">
                                <div class="form-group">
                                    <label for="mysql-threads"><i class="fas fa-microchip"></i> 线程数</label>
                                    <input type="number" id="mysql-threads" min="1" max="16" value="4">
                                </div>
                                <div class="form-group">
                                    <label for="mysql-compression"><i class="fas fa-compress"></i> 压缩级别</label>
                                    <select id="mysql-compression">
                                        <option value="1">快速</option>
                                        <option value="2" selected>平衡</option>
                                        <option value="9">最佳</option>
                                    </select>
                                </div>
                            </div>
                            
                            <!-- 逻辑备份特定设置 - 自定义输入 -->
                            <div class="backup-options logical">
                                <div class="form-group">
                                    <label><i class="fas fa-database"></i> 数据库和表配置</label>
                                    <div class="custom-db-input">
                                        <div class="input-hint">
                                            输入格式:数据库名:表1,表2,表3(每行一个数据库)
                                        </div>
                                        <textarea id="mysql-db-config" rows="4" placeholder="例如:
app_db:users,orders,products
report_db:sales,inventory">app_db:users,orders</textarea>
                                        <div class="input-example">
                                            示例:<br>
                                            wordpress:wp_posts,wp_users<br>
                                            inventory:products,categories
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <div class="form-group">
                                <label>高级选项</label>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="mysql-encryption">
                                    <label for="mysql-encryption">启用加密</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="action-buttons">
                        <button class="btn btn-primary" id="generate-mysql">
                            <i class="fas fa-code"></i> 生成备份脚本
                        </button>
                        <button class="btn btn-secondary">
                            <i class="fas fa-save"></i> 保存配置
                        </button>
                    </div>
                    
                    <div class="report-section">
                        <div class="report-header">
                            <h3 class="section-title"><i class="fas fa-file-code"></i> 生成的备份脚本</h3>
                        </div>
                        
                        <div class="report-content" id="mysql-script">
                            <!-- 生成的脚本将显示在这里 -->
                        </div>
                    </div>
                </div>
                
                <!-- PostgreSQL 配置 -->
                <div class="tab-content" id="postgres">
                    <h2 class="section-title"><i class="fas fa-server"></i> PostgreSQL 备份配置</h2>
                    
                    <div class="backup-type">
                        <div class="backup-type-btn physical active" data-type="physical">
                            <i class="fas fa-hard-drive"></i>
                            物理备份
                        </div>
                        <div class="backup-type-btn logical" data-type="logical">
                            <i class="fas fa-file-code"></i>
                            逻辑备份
                        </div>
                    </div>
                    
                    <div class="config-grid">
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-plug"></i> 连接设置</h3>
                            <div class="form-group">
                                <label for="postgres-host"><i class="fas fa-server"></i> 主机地址</label>
                                <input type="text" id="postgres-host" placeholder="例如: 192.168.1.100" value="pg-server">
                            </div>
                            <div class="form-group">
                                <label for="postgres-port"><i class="fas fa-network-wired"></i> 端口</label>
                                <input type="text" id="postgres-port" value="5432">
                            </div>
                            <div class="form-group">
                                <label for="postgres-db"><i class="fas fa-database"></i> 数据库名</label>
                                <input type="text" id="postgres-db" placeholder="例如: app_db" value="app_db">
                            </div>
                            <div class="form-group">
                                <label for="postgres-user"><i class="fas fa-user"></i> 用户名</label>
                                <input type="text" id="postgres-user" placeholder="例如: postgres" value="admin">
                            </div>
                            <div class="form-group">
                                <label for="postgres-password"><i class="fas fa-key"></i> 密码</label>
                                <input type="password" id="postgres-password" placeholder="输入密码" value="********">
                            </div>
                        </div>
                        
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-cog"></i> 备份设置</h3>
                            <div class="form-group">
                                <label for="postgres-backup-path"><i class="fas fa-folder-open"></i> 备份路径</label>
                                <input type="text" id="postgres-backup-path" value="/backup/postgres/">
                            </div>
                            
                            <!-- 物理备份特定设置 -->
                            <div class="backup-options physical active">
                                <div class="form-group">
                                    <label for="postgres-compress"><i class="fas fa-compress"></i> 压缩级别</label>
                                    <select id="postgres-compress">
                                        <option value="0">无压缩</option>
                                        <option value="1">快速</option>
                                        <option value="6" selected>平衡</option>
                                        <option value="9">最佳</option>
                                    </select>
                                </div>
                                <div class="form-group">
                                    <label for="postgres-checkpoint"><i class="fas fa-check-circle"></i> 检查点模式</label>
                                    <select id="postgres-checkpoint">
                                        <option value="fast">快速</option>
                                        <option value="spread" selected>分散</option>
                                        <option value="full">完整</option>
                                    </select>
                                </div>
                            </div>
                            
                            <!-- 逻辑备份特定设置 - 自定义输入 -->
                            <div class="backup-options logical">
                                <div class="form-group">
                                    <label><i class="fas fa-database"></i> 数据库和表配置</label>
                                    <div class="custom-db-input">
                                        <div class="input-hint">
                                            输入格式:数据库名:表1,表2,表3(每行一个数据库)
                                        </div>
                                        <textarea id="postgres-db-config" rows="4" placeholder="例如:
app_db:users,orders,products
report_db:sales,inventory">app_db:users,orders</textarea>
                                        <div class="input-example">
                                            示例:<br>
                                            public_data:customers,transactions<br>
                                            logs:access_logs,error_logs
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <div class="form-group">
                                <label>高级选项</label>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="postgres-verify" checked>
                                    <label for="postgres-verify">备份后验证</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="action-buttons">
                        <button class="btn btn-postgres" id="generate-postgres">
                            <i class="fas fa-code"></i> 生成备份脚本
                        </button>
                        <button class="btn btn-secondary">
                            <i class="fas fa-save"></i> 保存配置
                        </button>
                    </div>
                    
                    <div class="report-section">
                        <div class="report-header">
                            <h3 class="section-title"><i class="fas fa-file-code"></i> 生成的备份脚本</h3>
                        </div>
                        
                        <div class="report-content" id="postgres-script">
                            <!-- 生成的脚本将显示在这里 -->
                        </div>
                    </div>
                </div>
                
                <!-- SQL Server 配置 -->
                <div class="tab-content" id="sqlserver">
                    <h2 class="section-title"><i class="fab fa-microsoft"></i> SQL Server 备份配置</h2>
                    
                    <div class="backup-type">
                        <div class="backup-type-btn physical active" data-type="physical">
                            <i class="fas fa-hard-drive"></i>
                            物理备份
                        </div>
                        <div class="backup-type-btn logical" data-type="logical">
                            <i class="fas fa-file-code"></i>
                            逻辑备份
                        </div>
                    </div>
                    
                    <div class="config-grid">
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-plug"></i> 连接设置</h3>
                            <div class="form-group">
                                <label for="sqlserver-host"><i class="fas fa-server"></i> 主机地址</label>
                                <input type="text" id="sqlserver-host" placeholder="例如: 192.168.1.100" value="sql-server">
                            </div>
                            <div class="form-group">
                                <label for="sqlserver-port"><i class="fas fa-network-wired"></i> 端口</label>
                                <input type="text" id="sqlserver-port" value="1433">
                            </div>
                            <div class="form-group">
                                <label for="sqlserver-db"><i class="fas fa-database"></i> 数据库名</label>
                                <input type="text" id="sqlserver-db" placeholder="例如: app_db" value="app_db">
                            </div>
                            <div class="form-group">
                                <label for="sqlserver-user"><i class="fas fa-user"></i> 用户名</label>
                                <input type="text" id="sqlserver-user" placeholder="例如: sa" value="admin">
                            </div>
                            <div class="form-group">
                                <label for="sqlserver-password"><i class="fas fa-key"></i> 密码</label>
                                <input type="password" id="sqlserver-password" placeholder="输入密码" value="********">
                            </div>
                        </div>
                        
                        <div class="config-card">
                            <h3 class="card-title"><i class="fas fa-cog"></i> 备份设置</h3>
                            <div class="form-group">
                                <label for="sqlserver-backup-path"><i class="fas fa-folder-open"></i> 备份路径</label>
                                <input type="text" id="sqlserver-backup-path" value="C:\\Backup\\">
                            </div>
                            
                            <!-- 物理备份特定设置 -->
                            <div class="backup-options physical active">
                                <div class="form-group">
                                    <label for="sqlserver-compress"><i class="fas fa-compress"></i> 压缩级别</label>
                                    <select id="sqlserver-compress">
                                        <option value="low">低</option>
                                        <option value="medium" selected>中</option>
                                        <option value="high">高</option>
                                    </select>
                                </div>
                                <div class="form-group">
                                    <label for="sqlserver-blocksize"><i class="fas fa-cube"></i> 块大小</label>
                                    <select id="sqlserver-blocksize">
                                        <option value="64">64 KB</option>
                                        <option value="128" selected>128 KB</option>
                                        <option value="256">256 KB</option>
                                    </select>
                                </div>
                            </div>
                            
                            <!-- 逻辑备份特定设置 - 自定义输入 -->
                            <div class="backup-options logical">
                                <div class="form-group">
                                    <label><i class="fas fa-database"></i> 数据库和表配置</label>
                                    <div class="custom-db-input">
                                        <div class="input-hint">
                                            输入格式:数据库名:表1,表2,表3(每行一个数据库)
                                        </div>
                                        <textarea id="sqlserver-db-config" rows="4" placeholder="例如:
AppDB:Users,Orders,Products
ReportDB:Sales,Inventory">AppDB:Users,Orders</textarea>
                                        <div class="input-example">
                                            示例:<br>
                                            Northwind:Customers,Orders<br>
                                            AdventureWorks:Product,ProductCategory
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <div class="form-group">
                                <label>高级选项</label>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="sqlserver-verify" checked>
                                    <label for="sqlserver-verify">备份后验证</label>
                                </div>
                                <div class="checkbox-group">
                                    <input type="checkbox" id="sqlserver-checksum">
                                    <label for="sqlserver-checksum">使用校验和</label>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="action-buttons">
                        <button class="btn btn-sqlserver" id="generate-sqlserver">
                            <i class="fas fa-code"></i> 生成备份脚本
                        </button>
                        <button class="btn btn-secondary">
                            <i class="fas fa-save"></i> 保存配置
                        </button>
                    </div>
                    
                    <div class="report-section">
                        <div class="report-header">
                            <h3 class="section-title"><i class="fas fa-file-code"></i> 生成的备份脚本</h3>
                        </div>
                        
                        <div class="report-content" id="sqlserver-script">
                            <!-- 生成的脚本将显示在这里 -->
                        </div>
                    </div>
                </div>
                
                <!-- 脚本修改器 -->
                <div class="tab-content" id="modifier">
                    <div class="tool-content">
                        <h2 class="tool-title"><i class="fas fa-edit"></i> 脚本修改器</h2>
                        <div class="tool-description">
                            使用此工具修改和优化现有的备份脚本。支持语法高亮、参数替换和错误检测功能。
                        </div>
                        
                        <div class="tool-grid">
                            <div class="tool-card">
                                <h3><i class="fas fa-bolt"></i> 快速优化</h3>
                                <p>一键优化现有脚本,提高执行效率并减少资源占用。</p>
                                <button class="btn btn-modifier">
                                    <i class="fas fa-magic"></i> 优化脚本
                                </button>
                            </div>
                            <div class="tool-card">
                                <h3><i class="fas fa-code"></i> 语法检查</h3>
                                <p>检查脚本语法错误,确保脚本在目标环境中能正确执行。</p>
                                <button class="btn btn-modifier">
                                    <i class="fas fa-check-circle"></i> 检查语法
                                </button>
                            </div>
                            <div class="tool-card">
                                <h3><i class="fas fa-exchange-alt"></i> 变量替换</h3>
                                <p>批量替换脚本中的占位符变量为实际值。</p>
                                <button class="btn btn-modifier">
                                    <i class="fas fa-sync-alt"></i> 替换变量
                                </button>
                            </div>
                        </div>
                        
                        <div class="tool-feature modifier-feature">
                            <h3><i class="fas fa-file-code"></i> 脚本编辑器</h3>
                            <div class="form-group">
                                <label for="script-content">输入要修改的备份脚本:</label>
                                <textarea id="script-content" rows="12" placeholder="在此粘贴您的备份脚本..."></textarea>
                            </div>
                            <button class="btn btn-modifier">
                                <i class="fas fa-play"></i> 执行修改
                            </button>
                        </div>
                    </div>
                </div>
                
                <!-- 计划任务生成 -->
                <div class="tab-content" id="scheduler">
                    <div class="tool-content">
                        <h2 class="tool-title"><i class="fas fa-calendar-alt"></i> 计划任务生成器</h2>
                        <div class="tool-description">
                            为您的备份脚本创建计划任务配置,支持Windows任务计划程序和Linux Cron配置生成。
                        </div>
                        
                        <div class="tool-grid">
                            <div class="tool-card">
                                <h3><i class="fab fa-windows"></i> Windows任务计划</h3>
                                <p>生成Windows任务计划程序配置文件(.xml)或命令行。</p>
                                <button class="btn btn-scheduler">
                                    <i class="fas fa-download"></i> 生成配置
                                </button>
                            </div>
                            <div class="tool-card">
                                <h3><i class="fab fa-linux"></i> Linux Cron配置</h3>
                                <p>生成Linux Cron配置文件或命令行。</p>
                                <button class="btn btn-scheduler">
                                    <i class="fas fa-download"></i> 生成配置
                                </button>
                            </div>
                            <div class="tool-card">
                                <h3><i class="fas fa-history"></i> 执行历史</h3>
                                <p>查看和管理之前生成的计划任务配置。</p>
                                <button class="btn btn-scheduler">
                                    <i class="fas fa-clock"></i> 查看历史
                                </button>
                            </div>
                        </div>
                        
                        <div class="tool-feature scheduler-feature">
                            <h3><i class="fas fa-cogs"></i> 任务配置</h3>
                            <div class="config-grid">
                                <div class="config-card">
                                    <h3 class="card-title"><i class="fas fa-clock"></i> 计划时间</h3>
                                    <div class="form-group">
                                        <label for="schedule-frequency">执行频率</label>
                                        <select id="schedule-frequency">
                                            <option value="daily">每天</option>
                                            <option value="weekly" selected>每周</option>
                                            <option value="monthly">每月</option>
                                            <option value="hourly">每小时</option>
                                        </select>
                                    </div>
                                    <div class="form-group">
                                        <label for="schedule-time">执行时间</label>
                                        <input type="time" id="schedule-time" value="02:00">
                                    </div>
                                    <div class="form-group">
                                        <label for="schedule-days">选择星期(如果适用)</label>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="monday" checked>
                                            <label for="monday">周一</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="tuesday" checked>
                                            <label for="tuesday">周二</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="wednesday" checked>
                                            <label for="wednesday">周三</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="thursday" checked>
                                            <label for="thursday">周四</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="friday" checked>
                                            <label for="friday">周五</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="saturday">
                                            <label for="saturday">周六</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="sunday">
                                            <label for="sunday">周日</label>
                                        </div>
                                    </div>
                                </div>
                                
                                <div class="config-card">
                                    <h3 class="card-title"><i class="fas fa-file-alt"></i> 脚本设置</h3>
                                    <div class="form-group">
                                        <label for="script-path">脚本路径</label>
                                        <input type="text" id="script-path" placeholder="例如: /backup/scripts/mysql_backup.sh">
                                    </div>
                                    <div class="form-group">
                                        <label for="output-log">输出日志路径</label>
                                        <input type="text" id="output-log" placeholder="例如: /var/log/backup.log">
                                    </div>
                                    <div class="form-group">
                                        <label>高级选项</label>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="email-notify">
                                            <label for="email-notify">完成后发送邮件通知</label>
                                        </div>
                                        <div class="checkbox-group">
                                            <input type="checkbox" id="error-only">
                                            <label for="error-only">仅在错误时通知</label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <button class="btn btn-scheduler">
                                <i class="fas fa-cogs"></i> 生成计划任务配置
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <footer>
            <p>多数据库备份脚本生成工具 v3.2 | © 2023 数据库管理解决方案 | 支持 Oracle, MySQL, PostgreSQL, SQL Server</p>
        </footer>
    </div>

    <div class="notification" id="notification">
        <i class="fas fa-check-circle"></i>
        <span id="notification-text">脚本已复制到剪贴板!</span>
    </div>

    <script>
        // 显示通知
        function showNotification(message) {
            const notification = document.getElementById('notification');
            const notificationText = document.getElementById('notification-text');
            
            notificationText.textContent = message;
            notification.classList.add('show');
            
            setTimeout(() => {
                notification.classList.remove('show');
            }, 3000);
        }
        
        // 可靠的复制到剪贴板函数
        function copyToClipboard(text) {
            // 创建临时textarea元素
            const textarea = document.createElement('textarea');
            textarea.value = text;
            textarea.setAttribute('readonly', '');
            textarea.style.position = 'absolute';
            textarea.style.left = '-9999px';
            document.body.appendChild(textarea);
            
            // 选择文本
            textarea.select();
            
            try {
                // 尝试使用新的Clipboard API
                if (navigator.clipboard) {
                    navigator.clipboard.writeText(text).then(() => {
                        showNotification('脚本已复制到剪贴板!');
                    }).catch(err => {
                        // 如果Clipboard API失败,使用传统方法
                        document.execCommand('copy');
                        showNotification('脚本已复制到剪贴板!');
                    });
                } else {
                    // 使用传统方法
                    document.execCommand('copy');
                    showNotification('脚本已复制到剪贴板!');
                }
            } catch (err) {
                showNotification('复制失败: ' + err);
            } finally {
                // 移除临时元素
                document.body.removeChild(textarea);
            }
        }

        // 数据库切换功能
        document.querySelectorAll('.sidebar-option[data-tab]').forEach(option => {
            option.addEventListener('click', () => {
                // 移除所有活动标签
                document.querySelectorAll('.sidebar-option').forEach(el => {
                    el.classList.remove('active');
                });
                
                // 设置当前选项为活动状态
                option.classList.add('active');
                
                // 隐藏所有内容区域
                document.querySelectorAll('.tab-content').forEach(el => {
                    el.classList.remove('active');
                });
                
                // 显示选中的内容区域
                const tabId = option.getAttribute('data-tab');
                document.getElementById(tabId).classList.add('active');
            });
        });
        
        // 备份类型切换
        document.querySelectorAll('.backup-type-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                const parent = btn.parentElement;
                const backupType = btn.dataset.type;
                
                // 更新按钮状态
                parent.querySelectorAll('.backup-type-btn').forEach(b => {
                    b.classList.remove('active');
                });
                btn.classList.add('active');
                
                // 更新备份选项显示
                const container = parent.closest('.tab-content');
                container.querySelectorAll('.backup-options').forEach(opt => {
                    opt.classList.remove('active');
                });
                container.querySelectorAll(`.backup-options.${backupType}`).forEach(opt => {
                    opt.classList.add('active');
                });
            });
        });
        
        // 表选择功能
        document.querySelectorAll('.table-item').forEach(item => {
            item.addEventListener('click', function() {
                this.classList.toggle('selected');
            });
        });
        
        // 数据库选择功能
        document.querySelectorAll('.database-item input').forEach(input => {
            input.addEventListener('change', function() {
                const parent = this.closest('.database-item');
                parent.classList.toggle('selected', this.checked);
            });
        });
        
        // 生成Oracle备份脚本
        document.getElementById('generate-oracle').addEventListener('click', () => {
            const host = document.getElementById('oracle-host').value || 'dbserver01';
            const port = document.getElementById('oracle-port').value || '1521';
            const service = document.getElementById('oracle-service').value || 'ORCL';
            const user = document.getElementById('oracle-user').value || 'sys as sysdba';
            const path = document.getElementById('oracle-backup-path').value || '/backup/oracle/';
            
            const isPhysical = document.querySelector('#oracle .backup-type-btn.physical').classList.contains('active');
            
            let script = '';
            
            if (isPhysical) {
                // 物理备份脚本
                const parallel = document.getElementById('oracle-parallel').value || 4;
                const compression = document.getElementById('oracle-compression').value || 'medium';
                const encryption = document.getElementById('oracle-encryption').checked;
                const validate = document.getElementById('oracle-validate').checked;
                
                script = `#!/bin/bash
# Oracle 物理备份脚本 (RMAN)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
SERVICE="${service}"
USER="${user}"
BACKUP_DIR="${path}"
PARALLEL=${parallel}
COMPRESSION="${compression}"

echo "开始Oracle物理备份..."
echo "目标主机: $HOST:$PORT/$SERVICE"
echo "备份目录: $BACKUP_DIR"
echo "并行度: $PARALLEL"
echo "压缩级别: $COMPRESSION"
${encryption ? 'echo "加密: 启用"' : ''}
${validate ? 'echo "验证: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

# 运行RMAN备份
rman target $USER/$SERVICE << EOF
run {
    allocate channel ch1 type disk;
    allocate channel ch2 type disk;
    ${parallel > 2 ? `allocate channel ch3 type disk;\n    allocate channel ch4 type disk;` : ''}
    
    set compression on for backup;
    ${encryption ? 'set encryption on;' : ''}
    
    backup as compressed backupset database 
        format '${path}full_%d_%T_%U.bkp'
        tag 'FULL_DB_BACKUP';
    
    backup current controlfile 
        format '${path}control_%d_%T_%U.bkp';
    
    backup archivelog all delete input;
    
    release channel ch1;
    release channel ch2;
    ${parallel > 2 ? 'release channel ch3;\n    release channel ch4;' : ''}
}
EOF

${validate ? `
echo "验证备份文件..."
rman target $USER/$SERVICE << EOF
validate backupset all;
EOF
` : ''}

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            } else {
                // 逻辑备份脚本
                const encryption = document.getElementById('oracle-encryption').checked;
                const validate = document.getElementById('oracle-validate').checked;
                const dbConfig = document.getElementById('oracle-db-config').value;
                
                // 解析自定义数据库配置
                const dbEntries = dbConfig.split('\n').filter(line => line.trim() !== '');
                let backupCommands = '';
                let validateCommands = '';
                
                const dateStr = "$(date +%Y%m%d_%H%M%S)";
                
                dbEntries.forEach((entry, index) => {
                    const [dbName, tables] = entry.split(':').map(item => item.trim());
                    if (dbName && tables) {
                        const tableList = tables.split(',').map(t => t.trim()).filter(t => t !== '').join(',');
                        const dumpFile = `${path}${dbName.toLowerCase()}_tables_${dateStr}.dmp`;
                        const logFile = `${path}${dbName.toLowerCase()}_tables_${dateStr}.log`;
                        
                        backupCommands += `
echo "备份数据库 ${dbName} 中的表: ${tableList}"
expdp $USER/$SERVICE@$HOST:$PORT/$SERVICE \\
    tables=${tableList} \\
    directory=DATA_PUMP_DIR \\
    dumpfile=${dumpFile} \\
    logfile=${logFile} \\
    compression=all \\
    ${encryption ? 'encryption_password=backup_pass' : ''}
`;
                        
                        if (validate) {
                            validateCommands += `
echo "验证备份文件: ${dumpFile}"
impdp $USER/$SERVICE@$HOST:$PORT/$SERVICE \\
    sqlfile=${dumpFile.replace('.dmp', '.sql')} \\
    directory=DATA_PUMP_DIR \\
    dumpfile=${dumpFile} \\
    validate_only=y
`;
                        }
                    }
                });
                
                script = `#!/bin/bash
# Oracle 逻辑备份脚本 (expdp)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
SERVICE="${service}"
USER="${user}"
BACKUP_DIR="${path}"

echo "开始Oracle逻辑备份..."
echo "目标主机: $HOST:$PORT/$SERVICE"
echo "备份目录: $BACKUP_DIR"
${encryption ? 'echo "加密: 启用"' : ''}
${validate ? 'echo "验证: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

${backupCommands}
${validate ? validateCommands : ''}

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            }
            
            const reportContent = document.getElementById('oracle-script');
            reportContent.innerHTML = `<pre class="script-content">${script}</pre>
                <button class="copy-btn" onclick="copyToClipboard(\`${script}\`)"><i class="fas fa-copy"></i> 复制脚本</button>`;
        });
        
        // 生成MySQL备份脚本
        document.getElementById('generate-mysql').addEventListener('click', () => {
            const host = document.getElementById('mysql-host').value || 'db-mysql-01';
            const port = document.getElementById('mysql-port').value || '3306';
            const user = document.getElementById('mysql-user').value || 'admin';
            const path = document.getElementById('mysql-backup-path').value || '/backup/mysql/';
            
            const isPhysical = document.querySelector('#mysql .backup-type-btn.physical').classList.contains('active');
            
            let script = '';
            
            if (isPhysical) {
                // 物理备份脚本
                const threads = document.getElementById('mysql-threads').value || 4;
                const compression = document.getElementById('mysql-compression').value || 2;
                const encryption = document.getElementById('mysql-encryption').checked;
                
                script = `#!/bin/bash
# MySQL 物理备份脚本 (Percona XtraBackup)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
USER="${user}"
BACKUP_DIR="${path}"
THREADS=${threads}
COMPRESSION=${compression}

echo "开始MySQL物理备份..."
echo "目标主机: $HOST:$PORT"
echo "备份目录: $BACKUP_DIR"
echo "线程数: $THREADS"
echo "压缩级别: $COMPRESSION"
${encryption ? 'echo "加密: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

# 运行XtraBackup
xtrabackup \\
    --host=$HOST \\
    --port=$PORT \\
    --user=$USER \\
    --password=your_password_here \\
    --backup \\
    --target-dir=$BACKUP_DIR \\
    --compress \\
    --compress-threads=$THREADS \\
    --parallel=$THREADS \\
    ${encryption ? '--encrypt=AES256 --encrypt-key="your_encryption_key"' : ''}

echo "准备备份文件..."
xtrabackup --prepare --target-dir=$BACKUP_DIR

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            } else {
                // 逻辑备份脚本
                const encryption = document.getElementById('mysql-encryption').checked;
                const dbConfig = document.getElementById('mysql-db-config').value;
                
                // 解析自定义数据库配置
                const dbEntries = dbConfig.split('\n').filter(line => line.trim() !== '');
                let backupCommands = '';
                
                const dateStr = "$(date +%Y%m%d_%H%M%S)";
                
                dbEntries.forEach((entry, index) => {
                    const [dbName, tables] = entry.split(':').map(item => item.trim());
                    if (dbName && tables) {
                        const tableList = tables.split(',').map(t => t.trim()).filter(t => t !== '').join(' ');
                        const dumpFile = `${path}${dbName}_tables_${dateStr}.sql`;
                        
                        backupCommands += `
echo "备份数据库 ${dbName} 中的表: ${tableList}"
mysqldump \\
    -h $HOST \\
    -P $PORT \\
    -u $USER \\
    -p \\
    ${dbName} \\
    ${tableList} \\
    ${encryption ? '--encrypt=AES256 --encrypt-key="your_encryption_key"' : ''} \\
    > ${dumpFile}
`;
                    }
                });
                
                script = `#!/bin/bash
# MySQL 逻辑备份脚本 (mysqldump)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
USER="${user}"
BACKUP_DIR="${path}"

echo "开始MySQL逻辑备份..."
echo "目标主机: $HOST:$PORT"
echo "备份目录: $BACKUP_DIR"
${encryption ? 'echo "加密: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

${backupCommands}

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            }
            
            const reportContent = document.getElementById('mysql-script');
            reportContent.innerHTML = `<pre class="script-content">${script}</pre>
                <button class="copy-btn" onclick="copyToClipboard(\`${script}\`)"><i class="fas fa-copy"></i> 复制脚本</button>`;
        });
        
        // 生成PostgreSQL备份脚本
        document.getElementById('generate-postgres').addEventListener('click', () => {
            const host = document.getElementById('postgres-host').value || 'pg-server';
            const port = document.getElementById('postgres-port').value || '5432';
            const user = document.getElementById('postgres-user').value || 'admin';
            const path = document.getElementById('postgres-backup-path').value || '/backup/postgres/';
            
            const isPhysical = document.querySelector('#postgres .backup-type-btn.physical').classList.contains('active');
            
            let script = '';
            
            if (isPhysical) {
                // 物理备份脚本
                const compress = document.getElementById('postgres-compress').value || 6;
                const checkpoint = document.getElementById('postgres-checkpoint').value || 'spread';
                const verify = document.getElementById('postgres-verify').checked;
                
                script = `#!/bin/bash
# PostgreSQL 物理备份脚本 (pg_basebackup)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
USER="${user}"
BACKUP_DIR="${path}"
COMPRESSION=${compress}
CHECKPOINT="${checkpoint}"

echo "开始PostgreSQL物理备份..."
echo "目标主机: $HOST:$PORT"
echo "备份目录: $BACKUP_DIR"
echo "压缩级别: $COMPRESSION"
echo "检查点模式: $CHECKPOINT"
${verify ? 'echo "验证: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

# 运行物理备份
pg_basebackup \\
    -h $HOST \\
    -p $PORT \\
    -U $USER \\
    -D $BACKUP_DIR/postgres_basebackup_$(date +%Y%m%d) \\
    -Ft \\
    -z -Z $COMPRESSION \\
    -c $CHECKPOINT \\
    -P

${verify ? `
echo "验证备份文件..."
pg_verifybackup $BACKUP_DIR/postgres_basebackup_$(date +%Y%m%d)
` : ''}

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            } else {
                // 逻辑备份脚本
                const verify = document.getElementById('postgres-verify').checked;
                const dbConfig = document.getElementById('postgres-db-config').value;
                
                // 解析自定义数据库配置
                const dbEntries = dbConfig.split('\n').filter(line => line.trim() !== '');
                let backupCommands = '';
                let verifyCommands = '';
                
                const dateStr = "$(date +%Y%m%d_%H%M%S)";
                
                dbEntries.forEach((entry, index) => {
                    const [dbName, tables] = entry.split(':').map(item => item.trim());
                    if (dbName && tables) {
                        const tableList = tables.split(',').map(t => t.trim()).filter(t => t !== '');
                        let tableOptions = '';
                        
                        tableList.forEach(table => {
                            tableOptions += ` -t ${table}`;
                        });
                        
                        const dumpFile = `${path}${dbName}_tables_${dateStr}.dump`;
                        
                        backupCommands += `
echo "备份数据库 ${dbName} 中的表: ${tableList.join(', ')}"
pg_dump \\
    -h $HOST \\
    -p $PORT \\
    -U $USER \\
    -d ${dbName} \\
    ${tableOptions} \\
    -Fc \\
    -f ${dumpFile}
`;
                        
                        if (verify) {
                            verifyCommands += `
echo "验证备份文件: ${dumpFile}"
pg_restore -l ${dumpFile} > /dev/null
if [ $? -eq 0 ]; then
    echo "备份验证成功!"
else
    echo "备份验证失败!"
fi
`;
                        }
                    }
                });
                
                script = `#!/bin/bash
# PostgreSQL 逻辑备份脚本 (pg_dump)
# 生成时间: ${new Date().toLocaleString()}

# 配置参数
HOST="${host}"
PORT="${port}"
USER="${user}"
BACKUP_DIR="${path}"

echo "开始PostgreSQL逻辑备份..."
echo "目标主机: $HOST:$PORT"
echo "备份目录: $BACKUP_DIR"
${verify ? 'echo "验证: 启用"' : ''}

# 创建备份目录
mkdir -p $BACKUP_DIR

${backupCommands}
${verify ? verifyCommands : ''}

echo "备份完成! 备份文件保存在 $BACKUP_DIR";
`;
            }
            
            const reportContent = document.getElementById('postgres-script');
            reportContent.innerHTML = `<pre class="script-content">${script}</pre>
                <button class="copy-btn" onclick="copyToClipboard(\`${script}\`)"><i class="fas fa-copy"></i> 复制脚本</button>`;
        });
        
        // 生成SQL Server备份脚本
        document.getElementById('generate-sqlserver').addEventListener('click', () => {
            const host = document.getElementById('sqlserver-host').value || 'sql-server';
            const port = document.getElementById('sqlserver-port').value || '1433';
            const user = document.getElementById('sqlserver-user').value || 'admin';
            const path = document.getElementById('sqlserver-backup-path').value || 'C:\\Backup\\';
            
            const isPhysical = document.querySelector('#sqlserver .backup-type-btn.physical').classList.contains('active');
            
            let script = '';
            
            if (isPhysical) {
                // 物理备份脚本
                const compress = document.getElementById('sqlserver-compress').value || 'medium';
                const blocksize = document.getElementById('sqlserver-blocksize').value || 128;
                const verify = document.getElementById('sqlserver-verify').checked;
                const checksum = document.getElementById('sqlserver-checksum').checked;
                
                script = `-- SQL Server 物理备份脚本
-- 生成时间: ${new Date().toLocaleString()}

-- 配置参数
DECLARE @backupPath NVARCHAR(255) = '${path.replace(/\\/g, '\\\\')}sqlserver_backup_${new Date().getTime()}.bak'
DECLARE @compression NVARCHAR(20) = '${compress}'
DECLARE @blocksize INT = ${blocksize} * 1024
DECLARE @verify BIT = ${verify ? 1 : 0}
DECLARE @checksum BIT = ${checksum ? 1 : 0}

-- 开始备份
BACKUP DATABASE [APP_DB]
TO DISK = @backupPath
WITH 
    FORMAT,
    COMPRESSION,
    BLOCKSIZE = @blocksize,
    ${checksum ? 'CHECKSUM,' : ''}
    STATS = 5;

${verify ? `
-- 验证备份
RESTORE VERIFYONLY 
FROM DISK = @backupPath
WITH CHECKSUM;
` : ''}

PRINT '备份完成! 备份文件保存在: ' + @backupPath;
`;
            } else {
                // 逻辑备份脚本
                const verify = document.getElementById('sqlserver-verify').checked;
                const dbConfig = document.getElementById('sqlserver-db-config').value;
                
                // 解析自定义数据库配置
                const dbEntries = dbConfig.split('\n').filter(line => line.trim() !== '');
                let backupCommands = '';
                let verifyCommands = '';
                
                const dateStr = "CONVERT(NVARCHAR, GETDATE(), 112) + '_' + REPLACE(CONVERT(NVARCHAR, GETDATE(), 108), ':', '')";
                
                dbEntries.forEach((entry, index) => {
                    const [dbName, tables] = entry.split(':').map(item => item.trim());
                    if (dbName && tables) {
                        const tableList = tables.split(',').map(t => t.trim()).filter(t => t !== '');
                        
                        tableList.forEach(table => {
                            const dataFile = `@backupPath + '${dbName}_${table}_' + ${dateStr} + '.dat'`;
                            
                            backupCommands += `
PRINT '正在备份表: ${dbName}.dbo.${table}'
EXEC xp_cmdshell 'bcp "${dbName}.dbo.${table}" out "' + ${dataFile} + '" -T -c -t,'
`;
                            
                            if (verify) {
                                verifyCommands += `
PRINT '验证表: ${dbName}.dbo.${table}'
DECLARE @${table.replace(/\s/g, '')}Count INT
SELECT @${table.replace(/\s/g, '')}Count = COUNT(*) FROM [${dbName}].dbo.[${table}]
PRINT '源表行数: ' + CAST(@${table.replace(/\s/g, '')}Count AS NVARCHAR)

DECLARE @${table.replace(/\s/g, '')}BackupCount INT
EXEC xp_cmdshell 'find /c /v "" "' + ${dataFile} + '"', no_output
SELECT @${table.replace(/\s/g, '')}BackupCount = CAST(REPLACE(@@ROWCOUNT, '行数', '') AS INT) - 1
PRINT '备份行数: ' + CAST(@${table.replace(/\s/g, '')}BackupCount AS NVARCHAR)

IF @${table.replace(/\s/g, '')}Count <> @${table.replace(/\s/g, '')}BackupCount
    PRINT '警告: ${table}表备份行数与源表不一致!'
`;
                            }
                        });
                    }
                });
                
                script = `-- SQL Server 逻辑备份脚本
-- 生成时间: ${new Date().toLocaleString()}

-- 配置参数
DECLARE @backupPath NVARCHAR(255) = '${path.replace(/\\/g, '\\\\')}'
DECLARE @dateStr NVARCHAR(20) = ${dateStr}
DECLARE @verify BIT = ${verify ? 1 : 0}

PRINT '开始SQL Server逻辑备份...'
PRINT '目标主机: ${host}:${port}'
PRINT '备份目录: ' + @backupPath

${backupCommands}
${verify ? verifyCommands : ''}

PRINT '备份完成! 备份文件保存在: ' + @backupPath;
`;
            }
            
            const reportContent = document.getElementById('sqlserver-script');
            reportContent.innerHTML = `<pre class="script-content">${script}</pre>
                <button class="copy-btn" onclick="copyToClipboard(\`${script}\`)"><i class="fas fa-copy"></i> 复制脚本</button>`;
        });
        
        // 初始化页面
        document.addEventListener('DOMContentLoaded', () => {
            // 生成初始Oracle脚本
            document.getElementById('generate-oracle').click();
            
            // 初始化备份选项显示
            document.querySelectorAll('.backup-options').forEach(opt => {
                opt.classList.remove('active');
            });
            document.querySelectorAll('.backup-options.physical').forEach(opt => {
                opt.classList.add('active');
            });
        });
    </script>
</body>
</html>
相关推荐
姑苏洛言7 分钟前
编写产品需求文档:黄历日历小程序
前端·javascript·后端
小光学长29 分钟前
基于vue框架的防疫科普网站0838x(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库
知识分享小能手31 分钟前
Vue3 学习教程,从入门到精通,使用 VSCode 开发 Vue3 的详细指南(3)
前端·javascript·vue.js·学习·前端框架·vue·vue3
极限实验室35 分钟前
使用 Docker Compose 简化 INFINI Console 与 Easysearch 环境搭建
数据库·docker·devops
飞翔的佩奇39 分钟前
Java项目:基于SSM框架实现的旅游协会管理系统【ssm+B/S架构+源码+数据库+毕业论文】
java·数据库·mysql·毕业设计·ssm·旅游·jsp
姑苏洛言1 小时前
搭建一款结合传统黄历功能的日历小程序
前端·javascript·后端
你的人类朋友2 小时前
🤔什么时候用BFF架构?
前端·javascript·后端
知识分享小能手2 小时前
Bootstrap 5学习教程,从入门到精通,Bootstrap 5 表单验证语法知识点及案例代码(34)
前端·javascript·学习·typescript·bootstrap·html·css3
一只小灿灿2 小时前
前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
前端·opencv·计算机视觉