初始化

This commit is contained in:
2026-03-05 21:27:11 +08:00
commit 130de0fd5d
140 changed files with 21972 additions and 0 deletions

138
docs/guides/style-guide.md Normal file
View File

@@ -0,0 +1,138 @@
# 📐 Code Style Guide
> 团队代码风格约定AI 在生成代码时自动遵循
---
## 通用
- 缩进: 2 spaces (前端) / 4 spaces (PHP)
- 行宽: 100 chars (前端) / 120 chars (PHP)
- 行尾: LF
- 文件末尾: 空行
- 字符编码: UTF-8
---
## TypeScript / Vue 3 前端
- 分号: 使用 (`;`)
- 引号: 单引号 (`'`)
- 尾逗号: 无 (`trailing comma: none`)
- 箭头函数参数: 始终括号 (`(x) => x`)
### 导入顺序
```typescript
// 1. Vue 运行时和内置组合式
import { ref, computed, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
// 2. 第三方库
// 管理端import { ElMessage } from 'element-plus'
// 用户端import { Dialog } from '@headlessui/vue'
import dayjs from 'dayjs'
// 3. 内部模块 (绝对路径)
import AppButton from '@/components/ui/AppButton.vue'
import { useUserStore } from '@/store/modules/user'
// 4. 相对路径
import { helper } from './utils'
// 5. JSDoc 类型引用JS 项目无需 import type
// @typedef {import('@/types').User} User
// 6. 样式
import './styles.css'
```
### 文件命名
| 类型 | 规范 | 示例 |
|------|------|------|
| 组件 | PascalCase | `UserProfile.vue` |
| Composable | camelCase + use | `useAuth.ts` |
| 工具函数 | kebab-case | `format-date.ts` |
| 常量 | kebab-case | `api-routes.ts` |
| 类型文件 | kebab-case | `user.types.ts` |
| 测试 | 同源 + .test | `UserProfile.test.ts` |
| Store | camelCase | `user.ts` (in store/modules/) |
| 指令 | camelCase | `auth.ts` (in directives/) |
| API | camelCase | `production.ts` (in api/) |
---
## PHP 后端 (PSR-12)
- 分号: 必须
- 引号: 单引号优先,含变量用双引号
- 缩进: 4 spaces
- 行宽: 120 chars
- 大括号: 类/方法 `{` 换行,控制流 `{` 同行
### PHP 命名规范
| 类型 | 规范 | 示例 |
|------|------|------|
| 类 | PascalCase | `OrderService` |
| 方法 | camelCase | `createOrder()` |
| 变量 | camelCase | `$orderData` |
| 常量 | SCREAMING_SNAKE | `MAX_RETRY_COUNT` |
| 数据库字段 | snake_case | `created_at` |
| 路由 | kebab-case 复数 | `/admin/production-orders` |
| 迁移文件 | snake_case 时间戳 | `2026_02_24_100000_create_orders_table.php` |
### PHP 文件结构
```php
<?php
declare(strict_types=1);
namespace App\Service\Production;
use App\Model\Production\ProductionOrder;
use App\Repository\Production\OrderRepository;
use Hyperf\Di\Annotation\Inject;
class OrderService
{
#[Inject]
protected OrderRepository $orderRepository;
public function create(array $data): ProductionOrder
{
// ...
}
}
```
### PHP 必须遵循
- `declare(strict_types=1);` — 所有 PHP 文件
- 类属性使用类型声明
- 方法参数和返回值使用类型声明
- 使用 PHPStan Level max 进行静态分析
- 使用 PHP CS Fixer 格式化代码
---
## Prettier 配置 (.prettierrc)
```json
{
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always",
"endOfLine": "lf",
"plugins": ["prettier-plugin-tailwindcss"]
}
```
---
*最后更新: 2026-02-24*

View File

@@ -0,0 +1,125 @@
# 🧪 Testing Strategy
> 测试策略指南AI 在编写测试时参考 (PHP Hyperf + Vue 3 双栈)
---
## 前端测试框架
| 类型 | 框架 | 配置文件 |
|------|------|----------|
| 单元测试 | Vitest | `vitest.config.ts` |
| 集成测试 | Vitest + MSW | — |
| E2E 测试 | Playwright | `playwright.config.ts` |
## 后端测试框架
| 类型 | 框架 | 配置文件 |
|------|------|----------|
| 单元测试 | PHPUnit | `phpunit.xml` |
| 功能测试 | PHPUnit (HTTP) | `phpunit.xml` |
| 静态分析 | PHPStan | `phpstan.neon` |
| 代码规范 | PHP CS Fixer | `.php-cs-fixer.php` |
---
## 测试金字塔目标
### 前端
- Unit: 70% (快速、大量)
- Integration: 20% (模块协作)
- E2E: 10% (关键用户路径)
### 后端
- Unit: 60% (Service、Repository、工具类)
- Integration: 30% (API 端点、数据库交互)
- Static Analysis: 持续 (PHPStan Level max)
---
## 覆盖率目标
| 维度 | 前端 | 后端 |
|------|------|------|
| 行覆盖 | ≥ 80% | ≥ 75% |
| 分支覆盖 | ≥ 75% | ≥ 70% |
| 关键路径 | 100% | 100% |
| Service 层 | — | 100% |
---
## 运行命令
### 前端
```bash
npm run test # 运行所有单元测试
npm run test:watch # 监听模式
npm run test:coverage # 覆盖率报告
npm run test:e2e # E2E 测试 (Playwright)
```
### 后端
```bash
composer test # PHPUnit 所有测试
composer test:unit # 仅单元测试
composer test:feature # 仅功能测试 (API)
composer test:coverage # PHPUnit + 覆盖率报告
composer analyse # PHPStan 静态分析
composer cs-fix # PHP CS Fixer 格式化
```
---
## 后端测试目录结构
```
tests/
├── Unit/ # 纯单元测试(不依赖框架)
│ ├── Service/
│ │ ├── OrderServiceTest.php
│ │ └── PaymentServiceTest.php
│ ├── Repository/
│ └── Utils/
├── Feature/ # 功能测试HTTP API 级别)
│ ├── Auth/
│ │ ├── LoginTest.php
│ │ └── PermissionTest.php
│ ├── Production/
│ │ └── OrderApiTest.php
│ └── System/
│ └── HealthCheckTest.php
├── bootstrap.php
└── phpunit.xml
```
---
## CI/CD 中的测试
```yaml
# .github/workflows/ci.yml 中双栈测试
jobs:
frontend-test:
steps:
- npm ci
- npm run lint
- npm run type-check
- npm run test:coverage
backend-test:
services:
mysql:
image: mysql:8
redis:
image: redis:7-alpine
steps:
- composer install
- composer analyse # PHPStan
- composer test # PHPUnit
```
---
*最后更新: 2026-02-24*

View File

@@ -0,0 +1,228 @@
# 🖥️ UI 规范 — 管理端Case-Database-Frontend-admin
> 管理端设计规范。AI 在 `Case-Database-Frontend-admin/` 中新建页面或组件时参考本文档。
> 核心原则:**桌面优先、功能完整、Element Plus 标准优先**
---
## 1. 设计系统
| 项目 | 选型 |
|---|---|
| UI 组件库 | Element Plus优先使用标准组件不自定义重复造轮子 |
| CSS 方案 | Tailwind CSS辅助布局不覆盖 Element Plus 样式) |
| 图标 | Element Plus Icons`@element-plus/icons-vue` |
| 字体 | 系统字体栈 |
| 布局框架 | 侧边导航 + 顶部栏 + 内容区(标准后台布局) |
---
## 2. 色彩系统
```css
:root {
/* 主色Element Plus 默认蓝) */
--el-color-primary: #409EFF;
/* 管理端背景层级 */
--admin-bg-sidebar: #001529; /* 深色侧边栏 */
--admin-bg-header: #FFFFFF; /* 白色顶栏 */
--admin-bg-content: #F0F2F5; /* 内容区浅灰 */
--admin-bg-card: #FFFFFF; /* 卡片/表格白 */
/* 状态色 */
--status-active: #52C41A; /* 启用/正常 */
--status-inactive: #D9D9D9; /* 停用/禁用 */
--status-pending: #FAAD14; /* 待处理 */
--status-danger: #FF4D4F; /* 危险/错误 */
}
```
Element Plus 主题色配置(`src/styles/element-vars.scss`
```scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': ('base': #409EFF),
)
);
```
---
## 3. 布局规范
### 整体框架
```
┌─────────────────────────────────────────────────────────┐
│ 顶栏60px 固定Logo + 面包屑 + 用户信息 + 通知 │
├──────────────┬──────────────────────────────────────────┤
│ │ 内容区padding: 16px
│ 侧边栏 │ ┌──────────────────────────────────────┐ │
220px │ │ 页面标题 + 操作按钮(顶部工具栏) │ │
│ │ ├──────────────────────────────────────┤ │
│ 折叠后 │ │ 主内容(表格/表单/卡片) │ │
│ → 64px │ │ │ │
│ │ └──────────────────────────────────────┘ │
└──────────────┴──────────────────────────────────────────┘
```
### 响应式
管理端以桌面端为主,但需支持:
- `≥ 1280px`:完整布局(侧边栏展开)
- `1024px ~ 1279px`侧边栏折叠64px 图标模式)
- `< 1024px`:侧边栏收起为抽屉(移动端兜底)
---
## 4. Element Plus 组件使用规范
### 数据表格el-table
```vue
<el-table
v-loading="loading"
:data="tableData"
stripe
border
highlight-current-row
style="width: 100%"
>
<!-- 数据列 -->
<el-table-column prop="id" label="ID" width="80" sortable />
<el-table-column prop="name" label="名称" min-width="180" show-overflow-tooltip />
<!-- 状态列Tag -->
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
{{ row.status === 1 ? '启用' : '停用' }}
</el-tag>
</template>
</el-table-column>
<!-- 操作列固定右侧 -->
<el-table-column label="操作" fixed="right" width="160">
<template #default="{ row }">
<el-button v-permission="'module:edit'" link type="primary" @click="handleEdit(row)">编辑</el-button>
<el-popconfirm title="确定删除?" @confirm="handleDelete(row.id)">
<template #reference>
<el-button v-permission="'module:delete'" link type="danger">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- 分页固定格式 -->
<el-pagination
v-model:current-page="query.page"
v-model:page-size="query.page_size"
:page-sizes="[10, 20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
class="mt-4 justify-end"
@change="fetchData"
/>
```
### 搜索表单
```vue
<!-- 搜索栏折叠设计超过 3 个条件可折叠 -->
<el-card class="mb-4" shadow="never">
<el-form :model="query" inline @keyup.enter="handleSearch">
<el-form-item label="关键词">
<el-input v-model="query.keyword" placeholder="请输入" clearable style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
```
### 弹窗表单
```vue
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑' : '新建'" width="600px" @close="handleDialogClose">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="submitting" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
```
规则:
- 弹窗宽度:简单表单 500px复杂表单 700-900px
- 弹窗关闭时必须调用 `formRef.value?.resetFields()`
- 提交按钮加 `:loading` 防重复提交
---
## 5. 页面标准结构
每个管理端页面遵循以下结构:
```vue
<template>
<div class="admin-page">
<!-- 页面头部标题 + 主要操作按钮 -->
<div class="mb-4 flex items-center justify-between">
<h2 class="text-lg font-semibold text-gray-800">页面标题</h2>
<el-button v-permission="'module:create'" type="primary" @click="handleCreate">
<el-icon><Plus /></el-icon> 新建
</el-button>
</div>
<!-- 搜索区 -->
<!-- 表格区 -->
<!-- 分页区 -->
<!-- 弹窗区 -->
</div>
</template>
<script setup>
// 1. 导入
// 2. 响应式状态
// 3. 表单/验证规则
// 4. 数据获取
// 5. 事件处理CRUD
// 6. 生命周期
</script>
```
---
## 6. 间距规范
| 场景 | 间距 |
|---|---|
| 内容区内边距 | `p-4`16px |
| 卡片间距 | `mb-4`16px |
| 表单项间距 | Element Plus 默认(`el-form` 管理) |
| 操作按钮间距 | `ml-2`8px同行按钮 |
---
## 7. 状态规范
| 状态 | 实现方式 |
|---|---|
| 加载中 | `v-loading="loading"``el-table``el-card` |
| 空状态 | `el-empty`(有描述、有图) |
| 错误状态 | `el-result` type="error"(提供重试按钮) |
| 操作成功 | `ElMessage.success('操作成功')` |
| 操作失败 | `ElMessage.error(error.message)` |
| 危险操作确认 | `el-popconfirm`(行内)/ `ElMessageBox.confirm`(批量) |
---
*最后更新: 2026-02-26*

View File

@@ -0,0 +1,157 @@
# 🎨 UI 规范 — 用户端Case-Database-Frontend-user
> 用户端设计规范。AI 在 `Case-Database-Frontend-user/` 中还原设计稿或新建页面时参考本文档。
> 核心原则:**移动优先、性能优先、品牌一致**
---
## 1. 设计系统
| 项目 | 选型 |
|---|---|
| CSS 方案 | Tailwind CSS v3 |
| 图标 | Lucide Icons`lucide-vue-next` |
| 字体 | 系统字体栈(中文优先)|
| 动效 | CSS Transition避免 JS 动画影响性能) |
---
## 2. 色彩系统
```css
:root {
/* 品牌主色 — 根据实际品牌替换 */
--color-primary: #3B82F6; /* blue-500 */
--color-primary-dark: #1D4ED8; /* blue-700hover */
--color-primary-light: #EFF6FF; /* blue-50背景 */
/* 功能色 */
--color-success: #10B981; /* green-500 */
--color-warning: #F59E0B; /* amber-500 */
--color-danger: #EF4444; /* red-500 */
--color-info: #6B7280; /* gray-500 */
/* 文本层级 */
--color-text-primary: #111827; /* gray-900 */
--color-text-secondary: #6B7280; /* gray-500 */
--color-text-disabled: #D1D5DB; /* gray-300 */
/* 背景 */
--color-bg-page: #F9FAFB; /* gray-50 */
--color-bg-card: #FFFFFF;
--color-border: #E5E7EB; /* gray-200 */
}
```
---
## 3. 字体规范
| 用途 | 大小 | 字重 | Tailwind 类 |
|---|---|---|---|
| 页面大标题 | 24px / 1.5rem | 700 | `text-2xl font-bold` |
| 卡片标题 | 18px / 1.125rem | 600 | `text-lg font-semibold` |
| 正文 | 14px / 0.875rem | 400 | `text-sm` |
| 辅助/标签 | 12px / 0.75rem | 400 | `text-xs` |
| 按钮文字 | 14px / 0.875rem | 500 | `text-sm font-medium` |
---
## 4. 间距系统4px 基准)
| 场景 | 间距 | Tailwind 类 |
|---|---|---|
| 行内元素间距 | 8px | `gap-2` / `space-x-2` |
| 卡片内边距 | 16px | `p-4` |
| 区块间间距 | 24px | `gap-6` / `mb-6` |
| 页面两侧边距 | 16px移动/ 24px桌面 | `px-4 md:px-6` |
| 页面顶部安全区 | 16px | `pt-4` |
---
## 5. 响应式断点(移动优先)
| 断点 | 最小宽度 | 典型设备 | 设计优先级 |
|---|---|---|---|
| `默认` | 375px | 手机(主力) | ⭐⭐⭐⭐⭐ |
| `sm` | 640px | 大屏手机 | ⭐⭐⭐⭐ |
| `md` | 768px | 平板竖屏 | ⭐⭐⭐ |
| `lg` | 1024px | 平板横屏/小桌面 | ⭐⭐ |
| `xl` | 1280px | 桌面 | ⭐ |
**断点使用顺序**(必须从小写起):
```html
<!-- ✅ 正确:移动端默认,再扩展 -->
<div class="w-full md:w-1/2 lg:w-1/3">
<!-- ❌ 错误:桌面优先写法 -->
<div class="w-1/3 lg:w-full">
```
---
## 6. 组件规范
### 按钮
```html
<!-- 主要操作 -->
<button class="w-full rounded-lg bg-primary py-3 text-sm font-medium text-white active:opacity-80">
立即购买
</button>
<!-- 次要操作 -->
<button class="w-full rounded-lg border border-gray-300 py-3 text-sm font-medium text-gray-700">
加入购物车
</button>
```
规则:
- 移动端主操作按钮通常 `w-full`,高度 ≥ 44px
- 按钮文字简短(≤ 6 字)
- 加载中禁用按钮并显示 Spinner
### 卡片
```html
<div class="rounded-xl bg-white p-4 shadow-sm">
<!-- 内容 -->
</div>
```
### 空状态 / 错误状态(必须实现)
```html
<!-- 空状态 -->
<div class="flex flex-col items-center py-16 text-gray-400">
<LucidePackageOpen class="mb-3 h-12 w-12" />
<p class="text-sm">暂无数据</p>
</div>
<!-- 骨架屏(优先于 Loading Spinner -->
<div class="animate-pulse rounded-xl bg-gray-100 h-24 w-full" />
```
---
## 7. 触摸交互规范
- 所有可点击元素最小尺寸:**44 × 44px**
- 相邻可点击元素间距 ≥ **8px**
- 列表项点击区域铺满整行
- 避免 hover 专属交互(移动端无 hover
---
## 8. 视觉还原流程
1. 识别所属前端(用户端 = 本文档)
2. 分析设计稿的色彩、间距(对齐上方规范)
3. 移动端布局先行,再添加 md/lg 断点适配
4. 使用 Tailwind 语义类(避免任意值 `w-[123px]`
5. 实现空状态、加载状态、错误状态
6. 验证触摸目标尺寸
---
*最后更新: 2026-02-26*

47
docs/guides/ui-specs.md Normal file
View File

@@ -0,0 +1,47 @@
# 🎨 UI Specifications
> 通用 UI 设计规范。具体以 `ui-specs-user.md`(用户端)和 `ui-specs-admin.md`(管理端)为准。
---
## 设计系统
| 维度 | 用户端 (Case-Database-Frontend-user/) | 管理端 (Case-Database-Frontend-admin/) |
|---|---|---|
| **组件方案** | Tailwind CSS + 自定义组件 | Element Plus + Tailwind CSS |
| **图标** | Lucide Icons | @element-plus/icons-vue |
| **字体** | 系统字体栈 (system-ui) | 系统字体栈 (system-ui) |
| **设计风格** | 品牌化、轻量、视觉吸引力 | 专业、实用、信息密度高 |
| **响应式** | 移动优先 (xs → xl) | 桌面优先 (≥ 1280px) |
## 间距
使用 Tailwind 默认间距 (4px 基准):
- 紧凑: `gap-2` (8px)
- 标准: `gap-4` (16px)
- 宽松: `gap-6` (24px)
- 区块: `gap-8` (32px)
## 响应式断点
| 断点 | 宽度 | 说明 |
|------|------|------|
| sm | 640px | 大手机 |
| md | 768px | 平板 |
| lg | 1024px | 小桌面 |
| xl | 1280px | 桌面 |
| 2xl | 1536px | 大屏 |
## 视觉还原流程
当提供设计稿截图时:
1. 确认目标前端(用户端 or 管理端)
2. 分析颜色、间距、字体
3. 识别组件层级
4. 用户端:使用 Tailwind CSS 还原;管理端:优先使用 Element Plus 组件
5. 注意细节: 阴影、圆角、边框
6. 如不确定,列出选项询问
---
*最后更新: 2026-02-26*