mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 15:32:48 +08:00
fix(debug): 修复预览不实时更新、出错位置不生效、中文Unicode转义等问题,预览改为右侧弹出面板,增加字数统计
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -48,4 +48,5 @@ extend/base/common/command/curd/migrate_output.php
|
||||
/source/**/.vscode
|
||||
.trae/documents/
|
||||
/docker-dev/
|
||||
/.sisyphus
|
||||
/.sisyphus
|
||||
/.omo
|
||||
@@ -322,6 +322,13 @@ if (!function_exists('echo_value')) {
|
||||
margin-right: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
#char-count {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
min-width: 40px;
|
||||
text-align: center;
|
||||
font-family: Consolas, monospace;
|
||||
}
|
||||
#debug-toolbar .toolbar-group label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -372,25 +379,55 @@ if (!function_exists('echo_value')) {
|
||||
}
|
||||
#markdown-preview {
|
||||
display: none;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 45%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
margin-top: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
border-left: 1px solid #ddd;
|
||||
box-shadow: -4px 0 16px rgba(0,0,0,0.12);
|
||||
z-index: 99998;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
#markdown-preview .preview-header {
|
||||
padding: 12px 20px;
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
#markdown-preview .preview-header .close-btn {
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0 4px;
|
||||
line-height: 1;
|
||||
}
|
||||
#markdown-preview .preview-header .close-btn:hover {
|
||||
color: #333;
|
||||
}
|
||||
#markdown-preview pre {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 13px;
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e8e8e8;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
color: #333;
|
||||
max-height: 600px;
|
||||
height: calc(100% - 49px);
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -517,6 +554,7 @@ if (!function_exists('echo_value')) {
|
||||
<label data-dynamic="env" data-env-key="Server/Request Data"><input type="checkbox" data-key="env_server"> Server</label>
|
||||
</span>
|
||||
<span class="toolbar-group">
|
||||
<span id="char-count" title="当前选中内容的字符数">0字</span>
|
||||
<button id="btn-copy" onclick="copyToClipboard()">复制给AI</button>
|
||||
<button id="btn-preview" onclick="togglePreview()">预览</button>
|
||||
<button id="btn-path" onclick="togglePathMode()">路径:简略</button>
|
||||
@@ -526,8 +564,12 @@ if (!function_exists('echo_value')) {
|
||||
<!-- Hidden root path -->
|
||||
<div id="root-path" style="display:none;"><?php echo \think\facade\App::getRootPath(); ?></div>
|
||||
|
||||
<!-- Markdown Preview -->
|
||||
<!-- Markdown Preview (right-side slide-out panel) -->
|
||||
<div id="markdown-preview">
|
||||
<div class="preview-header">
|
||||
<span>Markdown Preview</span>
|
||||
<button class="close-btn" onclick="togglePreview()">×</button>
|
||||
</div>
|
||||
<pre id="markdown-content"></pre>
|
||||
</div>
|
||||
|
||||
@@ -634,21 +676,24 @@ if (!function_exists('echo_value')) {
|
||||
<?php
|
||||
// Message
|
||||
if (isset($message)) {
|
||||
$md = "# \u7cfb\u7edf\u53d1\u751f\u9519\u8bef\n\n## \u9519\u8bef\u4fe1\u606f\n> " . strip_tags((string)$message) . "\n\n";
|
||||
$md = "# 系统发生错误\n\n## 错误信息\n> " . strip_tags((string)$message) . "\n\n";
|
||||
echo 'mdFragments.message = ' . json_encode($md, JSON_UNESCAPED_UNICODE) . ";\n";
|
||||
}
|
||||
|
||||
// Location
|
||||
if (isset($file) && isset($line)) {
|
||||
$fileEscaped = str_replace('\\', '\\\\', $file);
|
||||
$md = "## \u51fa\u9519\u4f4d\u7f6e\n- **File:** `{$fileEscaped}`\n- **Line:** `{$line}`\n\n";
|
||||
echo 'mdFragments.location = ' . json_encode($md, JSON_UNESCAPED_UNICODE) . ";\n";
|
||||
// Location (from first trace)
|
||||
if (isset($traces) && is_array($traces) && !empty($traces)) {
|
||||
$firstTrace = $traces[0];
|
||||
if (isset($firstTrace['file']) && isset($firstTrace['line'])) {
|
||||
$fileEscaped = str_replace('\\', '\\\\', $firstTrace['file']);
|
||||
$md = "## 出错位置\n- **File:** `{$fileEscaped}`\n- **Line:** `{$firstTrace['line']}`\n\n";
|
||||
echo 'mdFragments.location = ' . json_encode($md, JSON_UNESCAPED_UNICODE) . ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Call Stack (per trace)
|
||||
if (isset($traces) && is_array($traces)) {
|
||||
foreach ($traces as $index => $trace) {
|
||||
$md = "## \u5f02\u5e38 #{$index}\n";
|
||||
$md = "## 异常 #{$index}\n";
|
||||
if (isset($trace['message'])) {
|
||||
$md .= "**Message:** " . strip_tags($trace['message']) . "\n\n";
|
||||
}
|
||||
@@ -656,12 +701,12 @@ if (isset($traces) && is_array($traces)) {
|
||||
$md .= "**Location:** `{$trace['file']}` : {$trace['line']}\n\n";
|
||||
}
|
||||
if (!empty($trace['trace'])) {
|
||||
$md .= "### \u8c03\u7528\u6808\n";
|
||||
$md .= "### 调用栈\n";
|
||||
$count = 0;
|
||||
$total = count($trace['trace']);
|
||||
foreach ($trace['trace'] as $i => $item) {
|
||||
if ($count >= 20) {
|
||||
$md .= "... (\u5171 {$total} \u5c42\uff0c\u5df2\u622a\u65ad)\n";
|
||||
$md .= "... (共 {$total} 层,已截断)\n";
|
||||
break;
|
||||
}
|
||||
$func = $item['function'] ?? 'unknown';
|
||||
@@ -684,7 +729,7 @@ if (isset($traces) && is_array($traces)) {
|
||||
if (isset($traces) && is_array($traces)) {
|
||||
foreach ($traces as $index => $trace) {
|
||||
if (!empty($trace['source'])) {
|
||||
$md = "### \u6e90\u7801\u7247\u6bb5\n```php\n";
|
||||
$md = "### 源码片段\n```php\n";
|
||||
foreach ((array) $trace['source']['source'] as $key => $value) {
|
||||
$lineNum = $key + $trace['source']['first'];
|
||||
$marker = ($trace['line'] === $lineNum) ? ' >>>' : '';
|
||||
@@ -699,7 +744,7 @@ if (isset($traces) && is_array($traces)) {
|
||||
// Exception Data
|
||||
if (isset($datas) && is_array($datas)) {
|
||||
$hasData = false;
|
||||
$md = "## \u5f02\u5e38\u6570\u636e\n";
|
||||
$md = "## 异常数据\n";
|
||||
foreach ($datas as $label => $value) {
|
||||
if (!empty($value)) {
|
||||
$hasData = true;
|
||||
@@ -761,10 +806,14 @@ if (isset($tables) && is_array($tables)) {
|
||||
}
|
||||
restoreCheckboxState();
|
||||
updateDisabledState();
|
||||
// Auto-save on checkbox change
|
||||
updatePreviewIfOpen();
|
||||
// Auto-save on checkbox change + update preview if open
|
||||
var checkboxes = document.querySelectorAll('#debug-toolbar input[type="checkbox"]');
|
||||
checkboxes.forEach(function(cb) {
|
||||
cb.addEventListener('change', saveCheckboxState);
|
||||
cb.addEventListener('change', function() {
|
||||
saveCheckboxState();
|
||||
updatePreviewIfOpen();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -807,6 +856,19 @@ if (isset($tables) && is_array($tables)) {
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
// Update preview content if preview panel is currently open
|
||||
function updatePreviewIfOpen() {
|
||||
var preview = document.getElementById('markdown-preview');
|
||||
var content = generateMarkdown();
|
||||
var countEl = document.getElementById('char-count');
|
||||
if (countEl) {
|
||||
countEl.textContent = content.length + '字';
|
||||
}
|
||||
if (preview && preview.style.display === 'block') {
|
||||
document.getElementById('markdown-content').textContent = content;
|
||||
}
|
||||
}
|
||||
|
||||
// Update disabled state for env checkboxes based on data availability
|
||||
function updateDisabledState() {
|
||||
// Exception data
|
||||
@@ -863,20 +925,20 @@ if (isset($tables) && is_array($tables)) {
|
||||
window.copyToClipboard = function() {
|
||||
var content = generateMarkdown();
|
||||
if (!content.trim()) {
|
||||
alert('\u8bf7\u81f3\u5c11\u52fe\u9009\u4e00\u4e2a\u5185\u5bb9\u9009\u9879');
|
||||
alert('请至少勾选一个内容选项');
|
||||
return;
|
||||
}
|
||||
var btn = document.getElementById('btn-copy');
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(content).then(function() {
|
||||
btn.textContent = '\u5df2\u590d\u5236';
|
||||
btn.textContent = '已复制';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(function() {
|
||||
btn.textContent = '\u590d\u5236\u7ed9AI';
|
||||
btn.textContent = '复制给AI';
|
||||
btn.classList.remove('copied');
|
||||
}, 2000);
|
||||
}, function(err) {
|
||||
alert('\u590d\u5236\u5931\u8d25: ' + err);
|
||||
alert('复制失败: ' + err);
|
||||
});
|
||||
} else {
|
||||
var textarea = document.createElement('textarea');
|
||||
@@ -887,14 +949,14 @@ if (isset($tables) && is_array($tables)) {
|
||||
textarea.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
btn.textContent = '\u5df2\u590d\u5236';
|
||||
btn.textContent = '已复制';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(function() {
|
||||
btn.textContent = '\u590d\u5236\u7ed9AI';
|
||||
btn.textContent = '复制给AI';
|
||||
btn.classList.remove('copied');
|
||||
}, 2000);
|
||||
} catch (err) {
|
||||
alert('\u590d\u5236\u5931\u8d25');
|
||||
alert('复制失败');
|
||||
}
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
@@ -909,11 +971,11 @@ if (isset($tables) && is_array($tables)) {
|
||||
var content = generateMarkdown();
|
||||
document.getElementById('markdown-content').textContent = content;
|
||||
preview.style.display = 'block';
|
||||
btn.textContent = '\u5173\u95ed\u9884\u89c8';
|
||||
btn.textContent = '关闭预览';
|
||||
btn.classList.add('active');
|
||||
} else {
|
||||
preview.style.display = 'none';
|
||||
btn.textContent = '\u9884\u89c8';
|
||||
btn.textContent = '预览';
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
};
|
||||
@@ -923,13 +985,14 @@ if (isset($tables) && is_array($tables)) {
|
||||
var btn = document.getElementById('btn-path');
|
||||
if (currentPathMode === 'simple') {
|
||||
currentPathMode = 'full';
|
||||
btn.textContent = '\u8def\u5f84:\u5b8c\u6574';
|
||||
btn.textContent = '路径:完整';
|
||||
btn.classList.add('active');
|
||||
} else {
|
||||
currentPathMode = 'simple';
|
||||
btn.textContent = '\u8def\u5f84:\u7b80\u7565';
|
||||
btn.textContent = '路径:简洁';
|
||||
btn.classList.remove('active');
|
||||
}
|
||||
updatePreviewIfOpen();
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user