探讨
This commit is contained in:
8
.eslintrc.json
Normal file
8
.eslintrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals",
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "warn"
|
||||
}
|
||||
}
|
||||
|
||||
140
README.md
140
README.md
@@ -1,3 +1,137 @@
|
||||
# yanshi2
|
||||
|
||||
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
|
||||
|
||||
|
||||
28
middleware.ts
Normal file
28
middleware.ts
Normal 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
6
next-env.d.ts
vendored
Normal 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
20
next.config.ts
Normal 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
1
openapi.json
Normal file
File diff suppressed because one or more lines are too long
10152
package-lock.json
generated
Normal file
10152
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
64
package.json
Normal file
64
package.json
Normal 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
20
tailwind.config.ts
Normal 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
35
tsconfig.json
Normal 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"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user