初始化
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
$activeMenu = 'databaseUpgrade';
|
||||
include APP_PATH . 'app/views/layouts/admin_header.php';
|
||||
?>
|
||||
|
||||
<style>
|
||||
.sql-preview {
|
||||
background: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
font-family: 'Consolas', 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
.sql-preview::-webkit-scrollbar { width: 6px; }
|
||||
.sql-preview::-webkit-scrollbar-track { background: #2d2d2d; }
|
||||
.sql-preview::-webkit-scrollbar-thumb { background: #555; border-radius: 3px; }
|
||||
.badge-status { font-size: 12px; }
|
||||
.btn-execute-all { margin-left: 10px; }
|
||||
</style>
|
||||
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-<?php echo $messageType; ?> alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h4><i class="icon fa fa-<?php echo $messageType === 'success' ? 'check' : ($messageType === 'danger' ? 'ban' : 'warning'); ?>"></i> 提示</h4>
|
||||
<?php echo nl2br(htmlspecialchars($message)); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box box-success">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><i class="fa fa-wrench"></i> 数据库升级/迁移</h3>
|
||||
<div class="box-tools">
|
||||
<?php if ($pendingCount > 0): ?>
|
||||
<span class="badge bg-yellow" style="font-size:13px;"><?php echo $pendingCount; ?> 个待执行</span>
|
||||
<form method="post" style="display:inline;" class="confirm-form" data-confirm="确定要一键执行所有未执行的迁移脚本吗?此操作将按文件名顺序依次执行所有未执行过的 .sql 文件。">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="execute_all">
|
||||
<button type="submit" class="btn btn-sm btn-success btn-execute-all">
|
||||
<i class="fa fa-bolt"></i> 一键全部执行
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-green" style="font-size:13px;">全部已执行</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="callout callout-info" style="margin-bottom: 15px;">
|
||||
<h4><i class="icon fa fa-info-circle"></i> 使用说明</h4>
|
||||
<p style="margin-bottom:0;">
|
||||
1. 系统会自动扫描 <code>sql/</code> 目录下的所有 <code>.sql</code> 文件。<br>
|
||||
2. 已执行过的脚本会标记为 <span class="label label-success">已执行</span>,不会重复执行。<br>
|
||||
3. 每个脚本在事务中执行,失败会自动回滚。<br>
|
||||
4. 点击文件名可展开查看 SQL 内容预览。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php if (empty($fileList)): ?>
|
||||
<div class="text-center" style="padding: 40px;">
|
||||
<i class="fa fa-inbox" style="font-size: 48px; color: #ccc;"></i>
|
||||
<p style="color: #999; margin-top: 10px;">sql/ 目录下没有找到 .sql 迁移文件</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">#</th>
|
||||
<th>文件名</th>
|
||||
<th style="width: 100px;">状态</th>
|
||||
<th style="width: 160px;">执行时间</th>
|
||||
<th style="width: 120px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $idx = 1; foreach ($fileList as $file): ?>
|
||||
<tr>
|
||||
<td><?php echo $idx++; ?></td>
|
||||
<td>
|
||||
<a href="#" class="sql-preview-link" data-preview="preview-<?php echo $idx; ?>" style="font-family: monospace;">
|
||||
<i class="fa fa-file-code-o"></i> <?php echo htmlspecialchars($file['name']); ?>
|
||||
</a>
|
||||
<div id="preview-<?php echo $idx; ?>" class="sql-preview" style="display:none; margin-top:8px;">
|
||||
<?php echo $file['preview']; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($file['is_migrated']): ?>
|
||||
<?php if ($file['status'] == 1): ?>
|
||||
<span class="label label-success">已执行</span>
|
||||
<?php else: ?>
|
||||
<span class="label label-danger" title="<?php echo htmlspecialchars($file['error_msg']); ?>">执行失败</span>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<span class="label label-warning">待执行</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($file['is_migrated'] && $file['executed_at']): ?>
|
||||
<small><?php echo htmlspecialchars($file['executed_at']); ?></small>
|
||||
<?php else: ?>
|
||||
<small style="color:#999;">—</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (!$file['is_migrated'] || $file['status'] == 0): ?>
|
||||
<form method="post" style="display:inline;" class="confirm-form" data-confirm="确定要执行该迁移脚本吗?">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrfToken); ?>">
|
||||
<input type="hidden" name="action" value="execute">
|
||||
<input type="hidden" name="file" value="<?php echo htmlspecialchars($file['name']); ?>">
|
||||
<button type="submit" class="btn btn-sm btn-primary">
|
||||
<i class="fa fa-play"></i> 执行
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<button class="btn btn-sm btn-default" disabled>
|
||||
<i class="fa fa-check"></i> 已完成
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if ($file['is_migrated'] && $file['status'] == 0 && !empty($file['error_msg'])): ?>
|
||||
<br><small class="text-danger" style="display:inline-block;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="<?php echo htmlspecialchars($file['error_msg']); ?>"><?php echo htmlspecialchars($file['error_msg']); ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="<?php echo csp_nonce(); ?>">
|
||||
function togglePreview(link, previewId) {
|
||||
var preview = document.getElementById(previewId);
|
||||
var icon = link.querySelector('i');
|
||||
if (preview.style.display === 'none' || preview.style.display === '') {
|
||||
preview.style.display = 'block';
|
||||
if (icon) {
|
||||
icon.className = 'fa fa-file-code-o';
|
||||
}
|
||||
} else {
|
||||
preview.style.display = 'none';
|
||||
if (icon) {
|
||||
icon.className = 'fa fa-file-code-o';
|
||||
}
|
||||
}
|
||||
}
|
||||
// CSP:文件名预览切换改为事件委托(替代内联 onclick / javascript:)
|
||||
document.addEventListener('click', function (e) {
|
||||
var link = e.target.closest ? e.target.closest('.sql-preview-link') : null;
|
||||
if (!link) return;
|
||||
e.preventDefault();
|
||||
togglePreview(link, link.getAttribute('data-preview'));
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include APP_PATH . 'app/views/layouts/admin_footer.php'; ?>
|
||||
Reference in New Issue
Block a user