- migrate frontend to TypeScript (vue-tsc strict in build), upgrade all deps to latest (Vite 8, Tailwind 4, daisyUI 5, Pinia 4, vue-router 5) - restructure frontend dirs (api/components/common/layouts/styles/types/views) - drop Element Plus, add daisyUI TagInput; main CSS 490KB->163KB, entry JS 618KB->1.3KB - rewrite Dockerfile(.cn): frontend/backend stages pinned to $BUILDPLATFORM, CGO_ENABLED=0 cross-compile, no QEMU in multi-arch builds; add .dockerignore - local dev: Vite /api proxy + make dev targets; go:embed all:dist with .gitkeep so backend runs without prior frontend build - fix latent bugs: Keys.vue users ref, Settings.vue undefined userStore, Login.vue Ref-as-error display, res.error misuse - add REFACTOR_PLAN.md (phased refactor log)
155 lines
6.7 KiB
Vue
155 lines
6.7 KiB
Vue
<template>
|
||
<div class="min-h-screen bg-base-100 text-base-content">
|
||
<div class="navbar fixed w-full top-0 z-50 backdrop-blur-sm bg-base-100/50">
|
||
<div class="container mx-auto flex justify-between items-center p-1 rounded-box">
|
||
<div class="flex items-center h-12 w-12 rounded-full text-l">
|
||
<img src="@/assets/logo.svg" alt="Logo" class="select-none">
|
||
<span class="hidden sm:flex text-xl font-bold">
|
||
<a href="/" class="text-base-content hover:no-underline">OpenTeam</a>
|
||
</span>
|
||
</div>
|
||
<div class="flex items-center">
|
||
<a href="https://github.com/mirrors2/opencatd-open" target="_blank" rel="noopener noreferrer"
|
||
class="btn btn-md h-10 min-h-10 px-3 md:flex bg-black text-white items-center justify-center whitespace-nowrap rounded-xl text-sm font-extralight ring-offset-background transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-black/90 flex gap-2">
|
||
<Icon icon="simple-icons:github" class="size-5" />
|
||
<span>Star on GitHub</span>
|
||
<Icon icon="mingcute:star-fill" class="size-5 text-yellow-500 mb-0.5" />
|
||
<div class="font-extralight">{{ star }}</div>
|
||
</a>
|
||
<a class="hidden btn btn-outline font-extralight btn-md h-10 min-h-10 hover:bg-black px-1 ml-2"
|
||
@click="$router.push('/dashboard')">Dashboard</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<main class="flex-grow flex flex-col justify-center items-center pt-16">
|
||
<div class="text-center">
|
||
<div class="flex items-center justify-center my-4 outline-none select-none">
|
||
<img src="@/assets/openteam.png" alt="Project Logo" class="h-40">
|
||
</div>
|
||
<h1 class="text-4xl font-bold mb-4">
|
||
<a class="text-gray-600" href="https://github.com/mirrors2/opencatd-open">OpenTeam</a>
|
||
</h1>
|
||
<p class="text-lg max-w-2xl mx-auto mb-8">
|
||
OpenTeam is an open-source, team-shared service. that is compatible with OpenAI API and can
|
||
be safely shared with others for API usage.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="mb-8 md:tooltip md:tooltip-left md:tooltip-open" data-tip="指向 OpenTeam 的 base_url">
|
||
<div class="join">
|
||
<input type="text" class="input input-bordered join-item grow focus:outline-none rounded-l-full"
|
||
v-model="url" />
|
||
<button class="hover:bg-black hover:text-white btn join-item rounded-r-full" @click="copyUrl">复制</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="w-full max-w-4xl mx-auto px-4 text-center">
|
||
<p class="text-sm mb-4">
|
||
👉Api-Keys: <a href="https://platform.openai.com/account/api-keys"
|
||
class="link">https://platform.openai.com/account/api-keys</a>
|
||
</p>
|
||
|
||
<div class="card mb-8">
|
||
<div class="card-body px-1 flex flex-col items-center">
|
||
<h2 class="card-title text-xl font-extralight justify-center flex mb-4 p-2 rounded-lg border-2 border-dotted hover:cursor-alias"
|
||
@click="$router.push('/dashboard')">开始使用</h2>
|
||
|
||
<p class="mb-0">使用OpenTeam 管理你的LLM API,仅需一个地址即可接入不同的大模型</p>
|
||
<LineSegmentFlow />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card backdrop-blur-sm shadow-xl mb-8">
|
||
<div class="card-body">
|
||
<p class="mb-2">欢迎加入我们的Telegram频道,获取最新动态和帮助</p>
|
||
<div class="flex justify-center mb-4">
|
||
<a href="https://t.me/OpenTeamLLM" target="_blank" class="tooltip tooltip-bottom backdrop-blur-0" data-tip="Telegram Channel">
|
||
<img src="@/assets/openteam_channel.jpg" alt="Telegram Group QR Code"
|
||
class="w-40 fill-current backdrop-blur-0 select-none">
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="footer footer-center text-base-content rounded p-10">
|
||
<nav>
|
||
<div class="grid grid-flow-col gap-4">
|
||
<a href="https://github.com/mirrors2/opencatd-open" target="_blank">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="fill-current">
|
||
<path
|
||
d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||
</svg>
|
||
</a>
|
||
</div>
|
||
</nav>
|
||
<aside>
|
||
<p>Copyright © {{ currentYear }} - All right reserved by <a href="https://github.com/mirrors2" target="_blank"
|
||
class="text-gray-600 hover:text-gray-800 transition duration-300">Mirrors2.</a> </p>
|
||
</aside>
|
||
</footer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import LineSegmentFlow from '@/components/common/LineSegmentFlow.vue';
|
||
import { Icon } from '@iconify/vue';
|
||
import { useToast } from '@/composables/toast';
|
||
|
||
const currentYear = ref('');
|
||
const url = ref('');
|
||
const { setToast } = useToast();
|
||
|
||
const copyUrl = async () => {
|
||
try {
|
||
await navigator.clipboard.writeText(url.value);
|
||
setToast('复制成功!', 'info');
|
||
} catch (err: any) {
|
||
setToast('复制失败,请手动复制。', 'error');
|
||
}
|
||
};
|
||
|
||
const star = ref(0);
|
||
const getGithubStars = async (): Promise<number> => {
|
||
const res = await fetch('https://ungh.cc/repos/mirrors2/openteam', { next: { revalidate: 3600 } } as RequestInit);
|
||
const data = await res.json();
|
||
return data.repo.stars;
|
||
};
|
||
|
||
onMounted(() => {
|
||
url.value = window.location.origin;
|
||
currentYear.value = new Date().getFullYear().toString();
|
||
|
||
getGithubStars().then((stars) => {
|
||
star.value = stars;
|
||
});
|
||
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
.toast {
|
||
transition: opacity 0.3s, visibility 0.3s;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
position: fixed;
|
||
top: 64px;
|
||
/* 调整这个值以匹配你的 header 高度 */
|
||
right: 1rem;
|
||
}
|
||
|
||
.toast.visible {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
}
|
||
|
||
blockquote {
|
||
padding: 0 1em;
|
||
border-left: 0.25em solid #838989aa;
|
||
}
|
||
</style> |