commit d1416230702edcae210dd5d742b97535760078e6 Author: dekun Date: Wed Jun 10 19:59:27 2026 +0800 first commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..34050ab --- /dev/null +++ b/.env.example @@ -0,0 +1,25 @@ +# =========================================== +# 知命阁(zhimingge)环境变量 +# 复制为 .env.local 后填写实际值 +# cp .env.example .env.local +# =========================================== + +# AI 接口密钥(必填) +OPENAI_API_KEY= + +# AI 接口地址 +OPENAI_BASE_URL=https://op.bz121.com/v1 + +# AI 模型 +OPENAI_MODEL=huihui_ai/gemma-4-abliterated:e4b + +# 服务端口 +PORT=3000 + +# 运行环境 +NODE_ENV=production + +# 访问统计(可选,不需要可留空) +# UMAMI_ID= +# UMAMI_URL= +# UMAMI_DOMAINS= diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..4d765f2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals", "prettier"] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a60d49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# pm2 logs +/logs + +# typescript +*.tsbuildinfo +next-env.d.ts + +.idea diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..eeeb7be --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +pnpm-lock.yaml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ddbc1f8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2025 dekun + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..378048c --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# 知命阁(zhimingge) + +融合《周易》原文学习与 AI 智能解读的 Web 应用。 + +**代码仓库**:[https://git.bz121.com/dekun/zhimingge.git](https://git.bz121.com/dekun/zhimingge.git) + +## 功能模块 + +| 模块 | 路由 | 状态 | +|------|------|------| +| 易经学习 | `/learn` | 规划中 | +| 六爻算卦 | `/liuyao` | 已有基础(首页) | +| 生辰八字 | `/bazi` | 规划中 | +| 综合测算 | `/combined` | 规划中 | + +## 文档 + +- [产品说明文档(SPEC)](./docs/SPEC.md) — 功能规格、架构、实施分期 +- [Ubuntu 部署文档(DEPLOY)](./docs/DEPLOY.md) — PM2 部署至 `/opt/zhimingge` + +## 环境变量 + +复制 `.env.example` 为 `.env.local` 并填写: + +```env +OPENAI_API_KEY=你的密钥 +OPENAI_BASE_URL=https://op.bz121.com/v1 +OPENAI_MODEL=huihui_ai/gemma-4-abliterated:e4b +``` + +## 本地开发 + +```bash +git clone https://git.bz121.com/dekun/zhimingge.git +cd zhimingge +pnpm install +cp .env.example .env.local +pnpm run dev +``` + +访问 http://localhost:3000 + +## 生产部署(摘要) + +```bash +cd /opt/zhimingge +pnpm install --frozen-lockfile +pnpm run build +pm2 start ecosystem.config.cjs +pm2 save && pm2 startup +``` + +完整步骤见 [docs/DEPLOY.md](./docs/DEPLOY.md)。 + +## 目录说明 + +``` +zhimingge/ +├── app/ # Next.js 应用 +├── components/ # UI 组件 +├── content/zhouyi/ # 64 卦 Markdown 原文 +├── docs/ # 项目文档 +├── lib/ # 工具与数据 +├── ecosystem.config.cjs # PM2 配置 +└── scripts/deploy.sh # 服务器更新脚本 +``` + +## 技术栈 + +Next.js 15 · React 18 · Tailwind CSS · Vercel AI SDK · PM2 diff --git a/app/apple-icon.png b/app/apple-icon.png new file mode 100644 index 0000000..972131f Binary files /dev/null and b/app/apple-icon.png differ diff --git a/app/favicon.ico b/app/favicon.ico new file mode 100644 index 0000000..73a1f42 Binary files /dev/null and b/app/favicon.ico differ diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..0384f3d --- /dev/null +++ b/app/globals.css @@ -0,0 +1,109 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 60 9% 98%; + --foreground: 0 0% 32%; + + --card: 60 9% 98%; + --card-foreground: 0 0% 32%; + + --popover: 60 9% 98%; + --popover-foreground: 0 0% 32%; + + --primary: 0 0% 32%; + --primary-foreground: 60 9.1% 97.8%; + + --secondary: 60 5% 96%; + --secondary-foreground: 0 0% 32%; + + --muted: 60 4.8% 95.9%; + --muted-foreground: 25 5.3% 44.7%; + + --accent: 20 5.9% 94%; + --accent-foreground: 24 9.8% 10%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 60 9.1% 97.8%; + + --border: 20 5.9% 90%; + --input: 24 6% 85%; + --ring: 0 0% 32%; + + --radius: 0.5rem; + } + + .dark { + --background: 24 10% 10%; + --foreground: 60 9.1% 97.8%; + + --card: 24 10% 10%; + --card-foreground: 60 9.1% 97.8%; + + --popover: 24 10% 10%; + --popover-foreground: 60 9.1% 97.8%; + + --primary: 60 9.1% 97.8%; + --primary-foreground: 0 0% 32%; + + --secondary: 0 0% 20%; + --secondary-foreground: 60 9.1% 97.8%; + + --muted: 24 10% 10%; + --muted-foreground: 24 5.4% 66%; + + --accent: 0 0% 20%; + --accent-foreground: 60 9.1% 97.8%; + + --destructive: 0 74% 42%; + --destructive-foreground: 60 9.1% 97.8%; + + --border: 30 6% 25%; + --input: 33 5% 32%; + --ring: 20 6% 90%; + } +} + +@layer base { + * { + @apply border-border; + } + + body { + @apply gap flex flex-col bg-background text-foreground; + } + + body { + font-family: 'LXGW WenKai Screen'; + font-weight: normal; + } + + body, + html { + @apply h-full; + } + + footer { + padding-bottom: max(env(safe-area-inset-bottom), 8px); + } +} + +@layer utilities { + .gap { + @apply gap-4 sm:gap-6; + } +} + +@layer utilities { + ::-webkit-scrollbar { + --bar-width: 5px; + width: var(--bar-width); + height: var(--bar-width); + } + + ::-webkit-scrollbar-thumb { + @apply rounded-md bg-border; + } +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..36d1a76 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,53 @@ +import "./globals.css"; +import type { Metadata, Viewport } from "next"; +import React from "react"; +import Umami from "@/components/umami"; +import { ThemeProvider } from "next-themes"; + +export const metadata: Metadata = { + title: "AI 算卦 - 在线卜卦 GPT4 解读", + description: + "AI 算卦 - 通过进行六次硬币的随机卜筮,生成卦象,并使用 AI 对卦象进行分析|AI 算命、在线算命、在线算卦、周易易经64卦", + appleWebApp: { + title: "AI 算卦", + }, +}; + +export const viewport: Viewport = { + viewportFit: "cover", + width: "device-width", + initialScale: 1, + maximumScale: 1, + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#f5f5f4" }, + { media: "(prefers-color-scheme: dark)", color: "#333333" }, + ], +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + + + + {children} + + + + + ); +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..547f980 --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,13 @@ +import Header from "@/components/header"; +import Divination from "@/components/divination"; +import Footer from "@/components/footer"; + +export default function Home() { + return ( + <> +
+ +