初始提交:OCI 面板前端(含 GenAI 网关一期)

This commit is contained in:
Wang Defa
2026-07-09 15:31:29 +08:00
commit db45a669e3
135 changed files with 25220 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
import { useMessage } from 'naive-ui'
import { h, ref, type Ref, type VNodeChild } from 'vue'
type ToastKind = 'error' | 'warning'
const AUTO_CLOSE_MS = 8000
function renderDetail(kind: ToastKind, detail: string, copied: Ref<boolean>): VNodeChild {
return h('div', { class: 'toast-code' }, [
h('div', { class: 'toast-code-head' }, [
h('span', { class: `toast-tag toast-tag-${kind}` }, kind === 'error' ? 'ERROR' : 'WARN'),
h(
'button',
{
class: 'toast-copy',
onClick: () => {
void navigator.clipboard.writeText(detail)
copied.value = true
},
},
copied.value ? '已复制' : '⎘ 复制',
),
]),
h('pre', { class: 'toast-code-pre' }, detail),
])
}
function renderToast(
kind: ToastKind,
text: string,
detail: string,
expanded: Ref<boolean>,
copied: Ref<boolean>,
toggle: () => void,
): VNodeChild {
const rows: VNodeChild[] = [
h('div', { class: 'toast-line' }, [
h('span', text),
h('a', { class: 'toast-toggle', onClick: toggle }, expanded.value ? '收起 ▴' : '展开详情 ▾'),
]),
]
if (expanded.value) rows.push(renderDetail(kind, detail, copied))
return h('div', { class: 'toast-body' }, rows)
}
/**
* 带可展开详情的消息封装:error/warning 传 detail 时,toast 内嵌
* 「展开详情」代码块(带复制);展开期间暂停 8s 自动关闭,收起后重新计时。
*/
export function useToast() {
const message = useMessage()
function show(kind: ToastKind, text: string, detail?: string) {
if (!detail) {
message[kind](text)
return
}
const expanded = ref(false)
const copied = ref(false)
let timer = 0
const inst = message[kind](
() => renderToast(kind, text, detail, expanded, copied, toggle),
{ duration: 0, closable: true },
)
const arm = () => {
timer = window.setTimeout(() => inst.destroy(), AUTO_CLOSE_MS)
}
function toggle() {
expanded.value = !expanded.value
window.clearTimeout(timer)
if (!expanded.value) arm()
}
arm()
}
return {
success: (text: string) => message.success(text),
info: (text: string) => message.info(text),
error: (text: string, detail?: string) => show('error', text, detail),
warning: (text: string, detail?: string) => show('warning', text, detail),
}
}