2e2c161770
- backed/: Go Fiber backend with cpdaily integration - frondend/: Vue 3 + Vite frontend - Dockerfile: multi-stage build (Node → Go → Alpine) - deploy/docker-compose.yml: production compose file - .woodpecker/build.yml: CI/CD with blue-green zero-downtime deploy - /health endpoint for deployment health checks - Port 8884/8885 blue-green swap via 1Panel OpenResty
70 lines
1.8 KiB
Vue
70 lines
1.8 KiB
Vue
<script setup lang="ts">
|
|
import { watch } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useMessage } from '@/composables/useMessage'
|
|
|
|
const route = useRoute()
|
|
const { toasts, removeToast } = useMessage()
|
|
|
|
// 监听路由变化,在 admin 模式下移除手机容器限制
|
|
watch(
|
|
() => route.meta?.admin,
|
|
(isAdmin) => {
|
|
const app = document.getElementById('app')
|
|
if (app) {
|
|
if (isAdmin) {
|
|
app.classList.add('admin-mode')
|
|
} else {
|
|
app.classList.remove('admin-mode')
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<router-view />
|
|
|
|
<!-- Toast 容器 -->
|
|
<Teleport to="body">
|
|
<div class="fixed top-4 right-4 z-50 flex flex-col gap-2 max-w-sm">
|
|
<TransitionGroup name="toast">
|
|
<div
|
|
v-for="toast in toasts"
|
|
:key="toast.id"
|
|
:class="[
|
|
'px-4 py-3 rounded-lg shadow-lg border text-sm flex items-center gap-2 transition-all',
|
|
toast.type === 'success' && 'bg-green-50 border-green-200 text-green-700',
|
|
toast.type === 'error' && 'bg-red-50 border-red-200 text-red-700',
|
|
toast.type === 'info' && 'bg-blue-50 border-blue-200 text-blue-700',
|
|
]"
|
|
>
|
|
<span class="flex-1">{{ toast.message }}</span>
|
|
<button
|
|
class="text-current opacity-50 hover:opacity-100 text-lg leading-none"
|
|
@click="removeToast(toast.id)"
|
|
>×</button>
|
|
</div>
|
|
</TransitionGroup>
|
|
</div>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.toast-enter-active {
|
|
transition: all 0.3s ease-out;
|
|
}
|
|
.toast-leave-active {
|
|
transition: all 0.2s ease-in;
|
|
}
|
|
.toast-enter-from {
|
|
opacity: 0;
|
|
transform: translateX(40px);
|
|
}
|
|
.toast-leave-to {
|
|
opacity: 0;
|
|
transform: translateX(40px);
|
|
}
|
|
</style>
|