Update: Js 4 Log.html 95% --next move the loglevel to settingserver

This commit is contained in:
XOF
2025-11-27 00:51:04 +08:00
parent c86e7a7ba4
commit 166437c0ac
26 changed files with 20500 additions and 2435 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -449,6 +449,9 @@
.z-50 {
z-index: 50;
}
.z-1000 {
z-index: 1000;
}
.z-\[100\] {
z-index: 100;
}
@@ -503,6 +506,9 @@
.my-2 {
margin-block: calc(var(--spacing) * 2);
}
.mt-0 {
margin-top: calc(var(--spacing) * 0);
}
.mt-0\.5 {
margin-top: calc(var(--spacing) * 0.5);
}
@@ -624,6 +630,9 @@
width: calc(var(--spacing) * 6);
height: calc(var(--spacing) * 6);
}
.h-0 {
height: calc(var(--spacing) * 0);
}
.h-0\.5 {
height: calc(var(--spacing) * 0.5);
}
@@ -708,6 +717,9 @@
.w-0 {
width: calc(var(--spacing) * 0);
}
.w-1 {
width: calc(var(--spacing) * 1);
}
.w-1\/4 {
width: calc(1/4 * 100%);
}
@@ -822,6 +834,9 @@
.flex-1 {
flex: 1;
}
.flex-shrink {
flex-shrink: 1;
}
.shrink-0 {
flex-shrink: 0;
}
@@ -834,6 +849,9 @@
.caption-bottom {
caption-side: bottom;
}
.border-collapse {
border-collapse: collapse;
}
.origin-center {
transform-origin: center;
}
@@ -860,6 +878,10 @@
--tw-translate-x: 100%;
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1 {
--tw-translate-y: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1\/2 {
--tw-translate-y: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -1028,6 +1050,9 @@
margin-block-end: calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)));
}
}
.gap-x-1 {
column-gap: calc(var(--spacing) * 1);
}
.gap-x-1\.5 {
column-gap: calc(var(--spacing) * 1.5);
}
@@ -1180,6 +1205,9 @@
.\!border-primary {
border-color: var(--color-primary) !important;
}
.border-black {
border-color: var(--color-black);
}
.border-black\/10 {
border-color: color-mix(in srgb, #000 10%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@@ -1207,6 +1235,9 @@
.border-green-200 {
border-color: var(--color-green-200);
}
.border-primary {
border-color: var(--color-primary);
}
.border-primary\/20 {
border-color: var(--color-primary);
@supports (color: color-mix(in lab, red, red)) {
@@ -1243,12 +1274,18 @@
.border-zinc-300 {
border-color: var(--color-zinc-300);
}
.border-zinc-500 {
border-color: var(--color-zinc-500);
}
.border-zinc-500\/30 {
border-color: color-mix(in srgb, oklch(55.2% 0.016 285.938) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
border-color: color-mix(in oklab, var(--color-zinc-500) 30%, transparent);
}
}
.border-zinc-700 {
border-color: var(--color-zinc-700);
}
.border-zinc-700\/50 {
border-color: color-mix(in srgb, oklch(37% 0.013 285.805) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@@ -1324,6 +1361,9 @@
.bg-gray-500 {
background-color: var(--color-gray-500);
}
.bg-gray-950 {
background-color: var(--color-gray-950);
}
.bg-gray-950\/5 {
background-color: color-mix(in srgb, oklch(13% 0.028 261.692) 5%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@@ -1538,6 +1578,10 @@
--tw-gradient-position: to right in oklab;
background-image: linear-gradient(var(--tw-gradient-stops));
}
.from-blue-500 {
--tw-gradient-from: var(--color-blue-500);
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
}
.from-blue-500\/30 {
--tw-gradient-from: color-mix(in srgb, oklch(62.3% 0.214 259.815) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@@ -1608,6 +1652,9 @@
.px-8 {
padding-inline: calc(var(--spacing) * 8);
}
.py-0 {
padding-block: calc(var(--spacing) * 0);
}
.py-0\.5 {
padding-block: calc(var(--spacing) * 0.5);
}
@@ -1656,6 +1703,9 @@
.pr-20 {
padding-right: calc(var(--spacing) * 20);
}
.pb-1 {
padding-bottom: calc(var(--spacing) * 1);
}
.pb-1\.5 {
padding-bottom: calc(var(--spacing) * 1.5);
}
@@ -1765,6 +1815,9 @@
.break-words {
overflow-wrap: break-word;
}
.wrap-break-word {
overflow-wrap: break-word;
}
.break-all {
word-break: break-all;
}
@@ -1949,6 +2002,9 @@
--tw-ordinal: ordinal;
font-variant-numeric: var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);
}
.underline {
text-decoration-line: underline;
}
.opacity-0 {
opacity: 0%;
}
@@ -2010,6 +2066,10 @@
--tw-inset-shadow: inset 0 2px 4px var(--tw-inset-shadow-color, oklab(from rgb(0 0 0 / 0.05) l a b / 25%));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.inset-shadow-sm {
--tw-inset-shadow: inset 0 2px 4px var(--tw-inset-shadow-color, rgb(0 0 0 / 0.05));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring-black {
--tw-ring-color: var(--color-black);
}
@@ -2034,12 +2094,19 @@
.ring-input {
--tw-ring-color: var(--color-input);
}
.ring-zinc-500 {
--tw-ring-color: var(--color-zinc-500);
}
.ring-zinc-500\/30 {
--tw-ring-color: color-mix(in srgb, oklch(55.2% 0.016 285.938) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
--tw-ring-color: color-mix(in oklab, var(--color-zinc-500) 30%, transparent);
}
}
.outline {
outline-style: var(--tw-outline-style);
outline-width: 1px;
}
.blur {
--tw-blur: blur(8px);
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
@@ -2145,6 +2212,13 @@
.ring-inset {
--tw-ring-inset: inset;
}
.group-hover\:opacity-0 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
opacity: 0%;
}
}
}
.group-hover\:opacity-100 {
&:is(:where(.group):hover *) {
@media (hover: hover) {
@@ -2152,6 +2226,38 @@
}
}
}
.even\:bg-zinc-50\/50 {
&:nth-child(even) {
background-color: color-mix(in srgb, oklch(98.5% 0 0) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-zinc-50) 50%, transparent);
}
}
}
.even\:bg-zinc-100\/50 {
&:nth-child(even) {
background-color: color-mix(in srgb, oklch(96.7% 0.001 286.375) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-zinc-100) 50%, transparent);
}
}
}
.even\:bg-zinc-200\/30 {
&:nth-child(even) {
background-color: color-mix(in srgb, oklch(92% 0.004 286.32) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-zinc-200) 30%, transparent);
}
}
}
.even\:bg-zinc-200\/50 {
&:nth-child(even) {
background-color: color-mix(in srgb, oklch(92% 0.004 286.32) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-zinc-200) 50%, transparent);
}
}
}
.focus-within\:border-blue-500 {
&:focus-within {
border-color: var(--color-blue-500);
@@ -3129,6 +3235,106 @@
}
}
}
.dark\:even\:bg-black\/5 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 5%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 5%, transparent);
}
}
}
}
.dark\:even\:bg-black\/10 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 10%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 10%, transparent);
}
}
}
}
.dark\:even\:bg-black\/20 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 20%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 20%, transparent);
}
}
}
}
.dark\:even\:bg-black\/30 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 30%, transparent);
}
}
}
}
.dark\:even\:bg-black\/50 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 50%, transparent);
}
}
}
}
.dark\:even\:bg-black\/60 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 60%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 60%, transparent);
}
}
}
}
.dark\:even\:bg-black\/90 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #000 90%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-black) 90%, transparent);
}
}
}
}
.dark\:even\:bg-white\/5 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #fff 5%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 5%, transparent);
}
}
}
}
.dark\:even\:bg-white\/15 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #fff 15%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 15%, transparent);
}
}
}
}
.dark\:even\:bg-white\/50 {
&:where(.dark, .dark *) {
&:nth-child(even) {
background-color: color-mix(in srgb, #fff 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-white) 50%, transparent);
}
}
}
}
.dark\:hover\:border-blue-400 {
&:where(.dark, .dark *) {
&:hover {
@@ -3448,7 +3654,6 @@
border-radius: var(--radius-lg);
border-style: var(--tw-border-style);
border-width: 1px;
border-color: var(--color-border);
border-color: color-mix(in srgb, oklch(55.2% 0.016 285.938) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
border-color: color-mix(in oklab, var(--color-zinc-500) 30%, transparent);
@@ -3564,7 +3769,7 @@
font-weight: var(--font-weight-semibold);
}
.flatpickr-current-month .flatpickr-monthDropdown-months {
width: 5.5rem;
width: calc(var(--spacing) * 22);
border-style: var(--tw-border-style);
border-width: 0px;
background-color: transparent;
@@ -4165,7 +4370,6 @@
transition-duration: 200ms;
}
.task-stage-content {
display: flex;
flex-grow: 1;
align-items: baseline;
justify-content: space-between;
@@ -4916,7 +5120,7 @@
.tag-input-container {
margin-top: calc(var(--spacing) * 1);
display: flex;
min-height: 40px;
min-height: calc(var(--spacing) * 10);
width: 100%;
flex-wrap: wrap;
align-items: center;
@@ -5582,6 +5786,11 @@
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
initial-value: solid;
}
@property --tw-blur {
syntax: "*";
inherits: false;
@@ -5679,11 +5888,6 @@
syntax: "*";
inherits: false;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
initial-value: solid;
}
@keyframes spin {
to {
transform: rotate(360deg);
@@ -5749,6 +5953,7 @@
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
--tw-outline-style: solid;
--tw-blur: initial;
--tw-brightness: initial;
--tw-contrast: initial;
@@ -5773,7 +5978,6 @@
--tw-backdrop-sepia: initial;
--tw-duration: initial;
--tw-ease: initial;
--tw-outline-style: solid;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1609,7 +1609,7 @@ var LogList = class {
const requestTime = new Date(log.RequestTime).toLocaleString();
const checkedAttr = isChecked ? "checked" : "";
return `
<tr class="table-row" data-log-id="${log.ID}" ${errorMessageAttr}>
<tr class="table-row group" data-log-id="${log.ID}" ${errorMessageAttr}>
<td class="table-cell">
<input type="checkbox" class="h-4 w-4 rounded border-zinc-300 text-blue-600 focus:ring-blue-500" ${checkedAttr}>
</td>
@@ -1620,10 +1620,26 @@ var LogList = class {
<td class="table-cell">${errorInfo.statusCodeHtml}</td>
<td class="table-cell">${modelNameFormatted}</td>
<td class="table-cell text-muted-foreground text-xs">${requestTime}</td>
<td class="table-cell">
<button class="btn btn-ghost btn-icon btn-sm" aria-label="\u67E5\u770B\u8BE6\u60C5">
<i class="fas fa-ellipsis-h h-4 w-4"></i>
</button>
<td class="table-cell relative">
<!-- [MODIFIED] - 2. \u66FF\u6362\u539F\u6709\u6309\u94AE\u4E3A\u60AC\u6D6E\u64CD\u4F5C\u83DC\u5355 -->
<div class="flex items-center justify-center">
<!-- \u9ED8\u8BA4\u663E\u793A\u7684\u56FE\u6807 -->
<span class="text-zinc-400 group-hover:opacity-0 transition-opacity">
<i class="fas fa-ellipsis-h h-4 w-4"></i>
</span>
<!-- \u60AC\u6D6E\u65F6\u663E\u793A\u7684\u64CD\u4F5C\u6309\u94AE -->
<div class="absolute right-2 top-1/2 -translate-y-1/2 flex items-center bg-zinc-100 dark:bg-zinc-700 rounded-full shadow-md opacity-0 group-hover:opacity-100 transition-opacity duration-200 z-10">
<button class="px-2 py-1 text-zinc-500 hover:text-blue-500" data-action="view-log-details" title="\u67E5\u770B\u8BE6\u60C5">
<i class="fas fa-eye"></i>
</button>
<button class="px-2 py-1 text-zinc-500 hover:text-green-500" data-action="copy-api-key" title="\u590D\u5236APIKey">
<i class="fas fa-copy"></i>
</button>
<button class="px-2 py-1 text-zinc-500 hover:text-red-500" data-action="delete-log" title="\u5220\u9664\u65E5\u5FD7">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
</td>
</tr>
`;
@@ -2559,8 +2575,14 @@ var LogsPage = class {
this.elements.selectAllCheckbox.addEventListener("change", (event) => this.handleSelectAllChange(event));
}
if (this.elements.tableBody) {
this.elements.tableBody.addEventListener("change", (event) => {
if (event.target.type === "checkbox") this.handleSelectionChange(event.target);
this.elements.tableBody.addEventListener("click", (event) => {
const checkbox = event.target.closest('input[type="checkbox"]');
const actionButton = event.target.closest("button[data-action]");
if (checkbox) {
this.handleSelectionChange(checkbox);
} else if (actionButton) {
this._handleLogRowAction(actionButton);
}
});
}
if (this.elements.searchInput) {
@@ -2663,6 +2685,115 @@ var LogsPage = class {
deleteSelectedBtn.disabled = !hasSelection;
}
}
async _handleLogRowAction(button) {
const action = button.dataset.action;
const row = button.closest(".table-row");
const isDarkMode = document.documentElement.classList.contains("dark");
if (!row) return;
const logId = parseInt(row.dataset.logId, 10);
const log = this.state.logs.find((l) => l.ID === logId);
if (!log) {
Swal.fire({ toast: true, position: "top-end", icon: "error", title: "\u627E\u4E0D\u5230\u65E5\u5FD7\u6570\u636E", showConfirmButton: false, timer: 2e3 });
return;
}
switch (action) {
case "view-log-details": {
const detailsHtml = `
<div class="space-y-3 text-left text-sm p-2">
<div class="flex"><p class="w-24 font-semibold text-zinc-500 shrink-0">\u72B6\u6001\u7801</p><p class="font-mono text-zinc-800 dark:text-zinc-200">${log.StatusCode || "N/A"}</p></div>
<div class="flex"><p class="w-24 font-semibold text-zinc-500 shrink-0">\u72B6\u6001</p><p class="font-mono text-zinc-800 dark:text-zinc-200">${log.Status || "N/A"}</p></div>
<div class="flex"><p class="w-24 font-semibold text-zinc-500 shrink-0">\u6A21\u578B</p><p class="font-mono text-zinc-800 dark:text-zinc-200">${log.ModelName || "N/A"}</p></div>
<div class="border-t border-zinc-200 dark:border-zinc-700 my-2"></div>
<div>
<p class="font-semibold text-zinc-500 mb-1">\u9519\u8BEF\u6D88\u606F</p>
<div class="max-h-40 overflow-y-auto bg-zinc-100 dark:bg-zinc-800 p-2 rounded-md text-zinc-700 dark:text-zinc-300 break-words text-xs">
${log.ErrorMessage ? log.ErrorMessage.replace(/\n/g, "<br>") : "\u65E0\u9519\u8BEF\u6D88\u606F\u3002"}
</div>
</div>
</div>
`;
Swal.fire({
target: "#main-content-wrapper",
width: "32rem",
backdrop: `rgba(0,0,0,0.5)`,
heightAuto: false,
customClass: {
popup: `swal2-custom-style rounded-xl ${document.documentElement.classList.contains("dark") ? "swal2-dark" : ""}`,
title: "text-lg font-bold",
htmlContainer: "m-0 text-left"
},
title: "\u65E5\u5FD7\u8BE6\u60C5",
html: detailsHtml,
showCloseButton: false,
showConfirmButton: false
});
break;
}
case "copy-api-key": {
const key = dataStore.keys.get(log.KeyID);
if (key && key.APIKey) {
navigator.clipboard.writeText(key.APIKey).then(() => {
Swal.fire({ toast: true, position: "top-end", customClass: { popup: `swal2-custom-style ${document.documentElement.classList.contains("dark") ? "swal2-dark" : ""}` }, icon: "success", title: "API Key \u5DF2\u590D\u5236", showConfirmButton: false, timer: 1500 });
}).catch((err) => {
Swal.fire({ toast: true, position: "top-end", icon: "error", title: "\u590D\u5236\u5931\u8D25", text: err.message, showConfirmButton: false, timer: 2e3 });
});
} else {
Swal.fire({ toast: true, position: "top-end", icon: "warning", title: "\u672A\u627E\u5230\u5B8C\u6574\u7684API Key", showConfirmButton: false, timer: 2e3 });
return;
}
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(key.APIKey).then(() => {
Swal.fire({ toast: true, position: "top-end", icon: "success", title: "API Key \u5DF2\u590D\u5236", showConfirmButton: false, timer: 1500 });
}).catch((err) => {
Swal.fire({ toast: true, position: "top-end", icon: "error", title: "\u590D\u5236\u5931\u8D25", text: err.message, showConfirmButton: false, timer: 2e3 });
});
} else {
Swal.fire({
icon: "error",
title: "\u590D\u5236\u5931\u8D25",
text: "\u6B64\u529F\u80FD\u9700\u8981\u5B89\u5168\u8FDE\u63A5 (HTTPS) \u6216\u5728 localhost \u73AF\u5883\u4E0B\u4F7F\u7528\u3002",
target: "#main-content-wrapper",
customClass: { popup: `swal2-custom-style ${document.documentElement.classList.contains("dark") ? "swal2-dark" : ""}` }
});
}
break;
}
case "delete-log": {
Swal.fire({
width: "20rem",
backdrop: `rgba(0,0,0,0.5)`,
heightAuto: false,
customClass: { popup: `swal2-custom-style ${document.documentElement.classList.contains("dark") ? "swal2-dark" : ""}` },
title: "\u786E\u8BA4\u5220\u9664",
text: `\u60A8\u786E\u5B9A\u8981\u5220\u9664\u8FD9\u6761\u65E5\u5FD7\u5417\uFF1F\u6B64\u64CD\u4F5C\u4E0D\u53EF\u64A4\u9500\u3002`,
showCancelButton: true,
confirmButtonText: "\u786E\u8BA4\u5220\u9664",
cancelButtonText: "\u53D6\u6D88",
reverseButtons: false,
confirmButtonColor: "#ef4444",
cancelButtonColor: "#6b7280",
focusCancel: true,
target: "#main-content-wrapper"
}).then(async (result) => {
if (result.isConfirmed) {
try {
const url = `/admin/logs?ids=${logId}`;
const { success, message } = await apiFetchJson(url, { method: "DELETE" });
if (success) {
Swal.fire({ toast: true, position: "top-end", icon: "success", title: "\u5220\u9664\u6210\u529F", showConfirmButton: false, timer: 2e3, timerProgressBar: true });
this.loadAndRenderLogs();
} else {
throw new Error(message || "\u5220\u9664\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
}
} catch (error) {
Swal.fire({ icon: "error", title: "\u64CD\u4F5C\u5931\u8D25", text: error.message, target: "#main-content-wrapper" });
}
}
});
break;
}
}
}
changePageSize(newSize) {
this.state.filters.page_size = newSize;
this.state.filters.page = 1;

1237
web/static/js/main.css Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long