This commit is contained in:
2026-04-15 09:29:54 +00:00
parent 52973e9581
commit 4e3d0f28c4
10 changed files with 10471 additions and 3 deletions

8
.eslintrc.json Normal file
View File

@@ -0,0 +1,8 @@
{
"extends": "next/core-web-vitals",
"rules": {
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-explicit-any": "warn"
}
}

138
README.md
View File

@@ -1,3 +1,137 @@
# yanshi2 # 智能农业测试平台
基于 Next.js 14 (App Router) 和 PostgreSQL 的测试管理平台。
## 技术栈
- **前端框架**: Next.js 14+ (App Router)
- **语言**: TypeScript
- **样式**: Tailwind CSS
- **数据库**: PostgreSQL
- **ORM**: Prisma
- **认证**: NextAuth.js
- **表单**: React Hook Form + Zod
- **状态管理**: Zustand
## 项目结构
```
hm-smart-agri-test-platform/
├── src/ # 源代码目录
│ ├── app/ # Next.js App Router
│ │ ├── api/ # API 路由
│ │ ├── auth/ # 认证相关页面
│ │ ├── dashboard/ # 仪表板页面
│ │ ├── layout.tsx # 根布局
│ │ └── page.tsx # 首页
│ ├── components/ # 可复用组件
│ │ ├── ui/ # 基础 UI 组件
│ │ ├── forms/ # 表单组件
│ │ └── layout/ # 布局组件
│ ├── lib/ # 工具库
│ │ ├── db/ # 数据库配置
│ │ ├── utils/ # 工具函数
│ │ ├── services/ # 服务层
│ │ ├── middleware/ # 中间件
│ │ ├── auth/ # 认证相关
│ │ └── constants/ # 常量定义
│ ├── hooks/ # 自定义 Hooks
│ ├── types/ # TypeScript 类型定义
│ └── middleware.ts # Next.js 中间件
├── prisma/ # Prisma 相关
│ └── schema.prisma # 数据库模型
├── scripts/ # 脚本文件
├── tests/ # 测试文件
├── docs/ # 文档目录
└── public/ # 静态资源
```
## 快速开始
### 1. 安装依赖
```bash
npm install
# 或
yarn install
# 或
pnpm install
```
### 2. 配置环境变量
复制 `.env.example``.env.local` 并填写相应的配置:
```bash
cp .env.example .env.local
```
编辑 `.env.local` 文件,配置数据库连接和其他环境变量。
### 3. 设置数据库
```bash
# 生成 Prisma Client
npm run db:generate
# 推送数据库模式(开发环境)
npm run db:push
# 或使用迁移(生产环境推荐)
npm run db:migrate
```
### 4. 启动开发服务器
```bash
npm run dev
```
打开 [http://localhost:3000](http://localhost:3000) 查看应用。
## 可用脚本
- `npm run dev` - 启动开发服务器
- `npm run build` - 构建生产版本
- `npm run start` - 启动生产服务器
- `npm run lint` - 运行 ESLint
- `npm run format` - 格式化代码
- `npm run type-check` - TypeScript 类型检查
- `npm run db:generate` - 生成 Prisma Client
- `npm run db:push` - 推送数据库模式
- `npm run db:migrate` - 运行数据库迁移
- `npm run db:studio` - 打开 Prisma Studio
## 数据库设计
### 核心表
- **Users** - 用户表
- **Projects** - 项目表
- **ProjectMembers** - 项目成员表
- **TestCases** - 测试用例表
- **TestRuns** - 测试执行表
- **TestResults** - 测试结果表
详细设计请查看 `prisma/schema.prisma` 文件。
## 开发规范
- 使用 TypeScript 严格模式
- 遵循 ESLint 规则
- 使用 Prettier 格式化代码
- 组件使用 PascalCase
- 函数/变量使用 camelCase
- 常量使用 UPPER_SNAKE_CASE
## 下一步
1. 配置数据库连接
2. 运行数据库迁移
3. 实现用户认证功能
4. 开发核心业务功能
## 许可证
MIT
yanshi2

28
middleware.ts Normal file
View File

@@ -0,0 +1,28 @@
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
/**
* 中间件:主要用于 API 路由的认证检查
* 客户端的 token 验证在页面组件中处理(因为 middleware 无法访问 localStorage
*/
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl
// API 路由的认证检查在各自的 route.ts 中处理
// 页面路由的认证检查在客户端组件中处理(使用 useAuth hook
return NextResponse.next()
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
}

6
next-env.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

20
next.config.ts Normal file
View File

@@ -0,0 +1,20 @@
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
reactStrictMode: true,
poweredByHeader: false,
images: {
unoptimized: false,
},
async rewrites() {
return [
{
source: '/openapi.json',
destination: '/api/openapi',
},
]
},
}
export default nextConfig

1
openapi.json Normal file

File diff suppressed because one or more lines are too long

10152
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

64
package.json Normal file
View File

@@ -0,0 +1,64 @@
{
"name": "hm-smart-agri-test-platform",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"db:generate": "prisma generate",
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio",
"db:seed": "tsx prisma/seed.ts",
"format": "prettier --write .",
"type-check": "tsc --noEmit"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@hookform/resolvers": "^3.3.4",
"@prisma/client": "^5.16.0",
"@types/jsonwebtoken": "^9.0.10",
"bcryptjs": "^2.4.3",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"jsonwebtoken": "^9.0.3",
"next": "^16.0.10",
"next-auth": "^4.24.0",
"next-themes": "^0.4.6",
"prisma": "^5.16.0",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-hook-form": "^7.51.0",
"recharts": "^3.6.0",
"redis": "^5.10.0",
"swagger-parser": "^10.0.3",
"swagger-ui-react": "^5.31.0",
"tailwind-merge": "^2.4.0",
"xlsx": "^0.18.5",
"zod": "^3.23.0",
"zustand": "^4.5.0"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.7",
"@types/bcryptjs": "^2.4.6",
"@types/node": "^20.19.25",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/xlsx": "^0.0.35",
"autoprefixer": "^10.4.20",
"eslint": "^9",
"eslint-config-next": "^16.0.6",
"postcss": "^8.4.40",
"prettier": "^3.3.0",
"tailwindcss": "^3.4.0",
"tsx": "^4.21.0",
"typescript": "^5"
}
}

20
tailwind.config.ts Normal file
View File

@@ -0,0 +1,20 @@
import type { Config } from 'tailwindcss'
const config: Config = {
darkMode: 'class',
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
background: 'var(--background)',
foreground: 'var(--foreground)',
},
},
},
plugins: [require('@tailwindcss/forms')],
}
export default config

35
tsconfig.json Normal file
View File

@@ -0,0 +1,35 @@
{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
}