diff --git a/Dockerfile b/Dockerfile index b26bde7..ed4e615 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,16 @@ -FROM node:latest AS builder +FROM node:lts-alpine AS builder RUN mkdir -p /workspace WORKDIR /workspace +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories +RUN apk update && apk add git RUN npm config set registry https://registry.npmmirror.com RUN git clone https://github.com/setube/ogame-vue-ts.git RUN mv ./ogame-vue-ts/* . ; rm -rf ./ogame-vue-ts/ RUN npm install -g pnpm ; pnpm install; -RUN pnpm build +RUN pnpm run build -# --- 第二阶段:Nginx --- FROM nginx:alpine COPY nginx.conf /etc/nginx/conf.d/default.conf diff --git a/package.json b/package.json index 6b0a664..a7a48a2 100644 --- a/package.json +++ b/package.json @@ -23,18 +23,16 @@ "@tailwindcss/vite": "^4.1.17", "@tanstack/vue-table": "^8.21.3", "@vueuse/core": "^14.1.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", "crypto-js": "^4.2.0", "file-saver": "^2.0.5", "finalhandler": "^2.1.1", "lucide-vue-next": "^0.556.0", "marked": "^17.0.1", + "motion-v": "^1.7.4", "pinia": "^3.0.4", "pinia-plugin-persistedstate": "^4.7.1", "reka-ui": "^2.6.1", "serve-static": "^2.2.0", - "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.17", "vue": "^3.5.24", "vue-router": "4", @@ -46,10 +44,13 @@ "@types/node": "^24.10.2", "@vitejs/plugin-vue": "^6.0.1", "@vue/tsconfig": "^0.8.1", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "cross-env": "^7.0.3", "electron": "^39.2.7", "electron-builder": "^26.0.12", "electron-vite": "^5.0.0", + "tailwind-merge": "^3.4.0", "tw-animate-css": "^1.4.0", "typescript": "~5.9.3", "vite": "npm:rolldown-vite@7.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df85f50..e633e4d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,6 @@ importers: '@vueuse/core': specifier: ^14.1.0 version: 14.1.0(vue@3.5.25(typescript@5.9.3)) - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 crypto-js: specifier: ^4.2.0 version: 4.2.0 @@ -41,6 +35,9 @@ importers: marked: specifier: ^17.0.1 version: 17.0.1 + motion-v: + specifier: ^1.7.4 + version: 1.7.4(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) pinia: specifier: ^3.0.4 version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) @@ -53,9 +50,6 @@ importers: serve-static: specifier: ^2.2.0 version: 2.2.0 - tailwind-merge: - specifier: ^3.4.0 - version: 3.4.0 tailwindcss: specifier: ^4.1.17 version: 4.1.17 @@ -84,6 +78,12 @@ importers: '@vue/tsconfig': specifier: ^0.8.1 version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -96,6 +96,9 @@ importers: electron-vite: specifier: ^5.0.0 version: 5.0.0(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1)) + tailwind-merge: + specifier: ^3.4.0 + version: 3.4.0 tw-animate-css: specifier: ^1.4.0 version: 1.4.0 @@ -2103,6 +2106,20 @@ packages: resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} + framer-motion@12.23.12: + resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} @@ -2244,6 +2261,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -2772,6 +2792,18 @@ packages: engines: {node: '>=10'} hasBin: true + motion-dom@12.23.12: + resolution: {integrity: sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==} + + motion-utils@12.23.6: + resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + + motion-v@1.7.4: + resolution: {integrity: sha512-YNDUAsany04wfI7YtHxQK3kxzNvh+OdFUk9GpA3+hMt7j6P+5WrVAAgr8kmPPoVza9EsJiAVhqoN3YYFN0Twrw==} + peerDependencies: + '@vueuse/core': '>=10.0.0' + vue: '>=3.0.0' + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -6027,6 +6059,12 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + framer-motion@12.23.12: + dependencies: + motion-dom: 12.23.12 + motion-utils: 12.23.6 + tslib: 2.8.1 + fresh@2.0.0: {} fs-extra@10.1.0: @@ -6208,6 +6246,8 @@ snapshots: dependencies: function-bind: 1.1.2 + hey-listen@1.0.8: {} + hookable@5.5.3: {} hosted-git-info@4.1.0: @@ -6694,6 +6734,24 @@ snapshots: mkdirp@1.0.4: {} + motion-dom@12.23.12: + dependencies: + motion-utils: 12.23.6 + + motion-utils@12.23.6: {} + + motion-v@1.7.4(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)): + dependencies: + '@vueuse/core': 14.1.0(vue@3.5.25(typescript@5.9.3)) + framer-motion: 12.23.12 + hey-listen: 1.0.8 + motion-dom: 12.23.12 + vue: 3.5.25(typescript@5.9.3) + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - react + - react-dom + ms@2.1.3: {} muggle-string@0.4.1: {} diff --git a/src/App.vue b/src/App.vue index f2182b4..c093067 100644 --- a/src/App.vue +++ b/src/App.vue @@ -327,9 +327,30 @@
-
- -
+ +
+ + + +
+ + +
+
+
@@ -453,6 +474,8 @@ import { toast } from 'vue-sonner' import { migrateGameData } from '@/utils/migration' import { checkLatestVersion } from '@/utils/versionCheck' + import {StarsBackground} from "@/components/ui/bg-stars"; + import {ParticlesBg} from "@/components/ui/particles-bg"; // 执行数据迁移(在 store 初始化之前) migrateGameData() diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..3deaa42 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,92 @@ +@custom-variant dark (&:is(.dark *)); + +:root { + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.21 0.006 285.885); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --destructive-foreground: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.705 0.015 286.067); + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); +} + +.dark { + --background: oklch(0.141 0.005 285.823); + --foreground: oklch(0.985 0 0); + --card: oklch(0.141 0.005 285.823); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.141 0.005 285.823); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.985 0 0); + --primary-foreground: oklch(0.21 0.006 285.885); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.396 0.141 25.723); + --destructive-foreground: oklch(0.637 0.237 25.331); + --border: oklch(0.274 0.006 286.033); + --input: oklch(0.274 0.006 286.033); + --ring: oklch(0.442 0.017 285.786); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} + +html { + color-scheme: light dark; +} +html.dark { + color-scheme: dark; +} +html.light { + color-scheme: light; +} diff --git a/src/components/ui/bg-stars/StarsBackground.vue b/src/components/ui/bg-stars/StarsBackground.vue new file mode 100644 index 0000000..ccec34b --- /dev/null +++ b/src/components/ui/bg-stars/StarsBackground.vue @@ -0,0 +1,176 @@ + + + diff --git a/src/components/ui/bg-stars/index.ts b/src/components/ui/bg-stars/index.ts new file mode 100644 index 0000000..205c143 --- /dev/null +++ b/src/components/ui/bg-stars/index.ts @@ -0,0 +1 @@ +export { default as StarsBackground } from "./StarsBackground.vue"; diff --git a/src/components/ui/particles-bg/ParticlesBg.vue b/src/components/ui/particles-bg/ParticlesBg.vue new file mode 100644 index 0000000..13607db --- /dev/null +++ b/src/components/ui/particles-bg/ParticlesBg.vue @@ -0,0 +1,250 @@ + + + diff --git a/src/components/ui/particles-bg/index.ts b/src/components/ui/particles-bg/index.ts new file mode 100644 index 0000000..e544838 --- /dev/null +++ b/src/components/ui/particles-bg/index.ts @@ -0,0 +1 @@ +export { default as ParticlesBg } from "./ParticlesBg.vue"; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 2aec90c..c66a9d9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,7 +1,7 @@ -import type { ClassValue } from 'clsx' -import { clsx } from 'clsx' -import { twMerge } from 'tailwind-merge' +import type { ClassValue } from "clsx" +import { clsx } from "clsx" +import { twMerge } from "tailwind-merge" -export const cn = (...inputs: ClassValue[]) => { +export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } diff --git a/src/style.css b/src/style.css index b518455..d1b0bc8 100644 --- a/src/style.css +++ b/src/style.css @@ -1,5 +1,6 @@ @import "tailwindcss"; @import "tw-animate-css"; +@import "@/assets/main.css"; @custom-variant dark (&:is(.dark *));