docs: 添加项目文档和 AgentSkills
- 添加架构文档 (ARCHITECTURE.md) - 添加 API 文档 (API.md) - 添加文档索引 (docs/README.md) - 添加部署技能 (skills/city-manual-deploy/SKILL.md) - 添加测试技能 (skills/city-manual-test/SKILL.md) - 添加内容管理技能 (skills/city-manual-content/SKILL.md)
This commit is contained in:
541
city-manual/docs/API.md
Normal file
541
city-manual/docs/API.md
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
# 城市手册 - API 文档
|
||||||
|
|
||||||
|
## 1. API 概述
|
||||||
|
|
||||||
|
### 1.1 基础信息
|
||||||
|
|
||||||
|
- **Base URL:** `http://localhost:8000/api`
|
||||||
|
- **认证方式:** JWT Bearer Token
|
||||||
|
- **数据格式:** JSON
|
||||||
|
- **GraphQL 端点:** `http://localhost:8000/graphql/`
|
||||||
|
|
||||||
|
### 1.2 认证
|
||||||
|
|
||||||
|
所有需要认证的接口需要在 Header 中携带 JWT Token:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer <access_token>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": "ERROR_CODE",
|
||||||
|
"message": "错误描述",
|
||||||
|
"details": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 用户认证 API
|
||||||
|
|
||||||
|
### 2.1 用户注册
|
||||||
|
|
||||||
|
**POST** `/api/users/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"password": "string",
|
||||||
|
"phone": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"phone": "string",
|
||||||
|
"role": "user",
|
||||||
|
"created_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 用户登录
|
||||||
|
|
||||||
|
**POST** `/api/auth/token/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "string",
|
||||||
|
"password": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
||||||
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 刷新令牌
|
||||||
|
|
||||||
|
**POST** `/api/auth/token/refresh/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"access": "eyJ0eXAiOiJKV1QiLCJhbGc..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 获取当前用户信息
|
||||||
|
|
||||||
|
**GET** `/api/users/me/`
|
||||||
|
|
||||||
|
**Headers:**
|
||||||
|
```
|
||||||
|
Authorization: Bearer <access_token>
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"phone": "string",
|
||||||
|
"role": "user",
|
||||||
|
"avatar": "url",
|
||||||
|
"created_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 更新用户信息
|
||||||
|
|
||||||
|
**PUT** `/api/users/me/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"phone": "string",
|
||||||
|
"avatar": "url"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 版块管理 API
|
||||||
|
|
||||||
|
### 3.1 获取版块列表
|
||||||
|
|
||||||
|
**GET** `/api/regions/`
|
||||||
|
|
||||||
|
**查询参数:**
|
||||||
|
- `level` - 版块级别(province/city/county/town/village)
|
||||||
|
- `parent` - 上级版块 ID
|
||||||
|
- `search` - 搜索关键词
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"count": 100,
|
||||||
|
"next": "url",
|
||||||
|
"previous": "url",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "广东省",
|
||||||
|
"level": "province",
|
||||||
|
"parent": null,
|
||||||
|
"children": [],
|
||||||
|
"moderator_count": 5,
|
||||||
|
"article_count": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 获取版块详情
|
||||||
|
|
||||||
|
**GET** `/api/regions/{id}/`
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "深圳市",
|
||||||
|
"level": "city",
|
||||||
|
"parent": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "广东省"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{"id": 2, "name": "南山区"},
|
||||||
|
{"id": 3, "name": "福田区"}
|
||||||
|
],
|
||||||
|
"description": "description",
|
||||||
|
"moderator_count": 3,
|
||||||
|
"article_count": 50,
|
||||||
|
"service_count": 20,
|
||||||
|
"created_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 创建版块
|
||||||
|
|
||||||
|
**POST** `/api/regions/`
|
||||||
|
|
||||||
|
**权限:** 管理员
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "string",
|
||||||
|
"level": "city",
|
||||||
|
"parent": 1,
|
||||||
|
"description": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 内容管理 API
|
||||||
|
|
||||||
|
### 4.1 获取文章列表
|
||||||
|
|
||||||
|
**GET** `/api/articles/`
|
||||||
|
|
||||||
|
**查询参数:**
|
||||||
|
- `region` - 版块 ID
|
||||||
|
- `category` - 分类(history/culture/practical/life)
|
||||||
|
- `status` - 状态(draft/pending/published/rejected)
|
||||||
|
- `search` - 搜索关键词
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"count": 100,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "深圳历史",
|
||||||
|
"region": {"id": 1, "name": "深圳市"},
|
||||||
|
"category": "history",
|
||||||
|
"author": {"id": 1, "username": "author"},
|
||||||
|
"status": "published",
|
||||||
|
"view_count": 1000,
|
||||||
|
"like_count": 50,
|
||||||
|
"comment_count": 10,
|
||||||
|
"created_at": "2026-04-12T00:00:00Z",
|
||||||
|
"updated_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 获取文章详情
|
||||||
|
|
||||||
|
**GET** `/api/articles/{id}/`
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "深圳历史",
|
||||||
|
"content": "markdown content",
|
||||||
|
"region": {"id": 1, "name": "深圳市"},
|
||||||
|
"category": "history",
|
||||||
|
"author": {"id": 1, "username": "author"},
|
||||||
|
"status": "published",
|
||||||
|
"view_count": 1000,
|
||||||
|
"like_count": 50,
|
||||||
|
"comment_count": 10,
|
||||||
|
"tags": ["历史", "文化"],
|
||||||
|
"created_at": "2026-04-12T00:00:00Z",
|
||||||
|
"updated_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 创建文章
|
||||||
|
|
||||||
|
**POST** `/api/articles/`
|
||||||
|
|
||||||
|
**权限:** 认证用户
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "string",
|
||||||
|
"content": "markdown content",
|
||||||
|
"region": 1,
|
||||||
|
"category": "history",
|
||||||
|
"tags": ["tag1", "tag2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 更新文章
|
||||||
|
|
||||||
|
**PUT** `/api/articles/{id}/`
|
||||||
|
|
||||||
|
**权限:** 作者或版主或管理员
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "string",
|
||||||
|
"content": "markdown content",
|
||||||
|
"category": "history",
|
||||||
|
"tags": ["tag1", "tag2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.5 删除文章
|
||||||
|
|
||||||
|
**DELETE** `/api/articles/{id}/`
|
||||||
|
|
||||||
|
**权限:** 作者或版主或管理员
|
||||||
|
|
||||||
|
## 5. 特色服务 API
|
||||||
|
|
||||||
|
### 5.1 获取特色服务列表
|
||||||
|
|
||||||
|
**GET** `/api/services/`
|
||||||
|
|
||||||
|
**查询参数:**
|
||||||
|
- `region` - 版块 ID
|
||||||
|
- `category` - 分类(clothing/food/accommodation/transportation/entertainment/tourism/culture)
|
||||||
|
- `status` - 状态
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"count": 100,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "深圳湾公园",
|
||||||
|
"region": {"id": 1, "name": "深圳市"},
|
||||||
|
"category": "tourism",
|
||||||
|
"description": "description",
|
||||||
|
"rating": 4.5,
|
||||||
|
"rating_count": 100,
|
||||||
|
"status": "published",
|
||||||
|
"created_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 获取特色服务详情
|
||||||
|
|
||||||
|
**GET** `/api/services/{id}/`
|
||||||
|
|
||||||
|
**响应:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "深圳湾公园",
|
||||||
|
"description": "description",
|
||||||
|
"region": {"id": 1, "name": "深圳市"},
|
||||||
|
"category": "tourism",
|
||||||
|
"address": "地址",
|
||||||
|
"contact": "联系方式",
|
||||||
|
"images": ["url1", "url2"],
|
||||||
|
"rating": 4.5,
|
||||||
|
"rating_count": 100,
|
||||||
|
"status": "published",
|
||||||
|
"author": {"id": 1, "username": "author"},
|
||||||
|
"created_at": "2026-04-12T00:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 创建特色服务
|
||||||
|
|
||||||
|
**POST** `/api/services/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "string",
|
||||||
|
"description": "string",
|
||||||
|
"region": 1,
|
||||||
|
"category": "tourism",
|
||||||
|
"address": "string",
|
||||||
|
"contact": "string",
|
||||||
|
"images": ["url1", "url2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 互动功能 API
|
||||||
|
|
||||||
|
### 6.1 评论
|
||||||
|
|
||||||
|
**GET** `/api/comments/`
|
||||||
|
|
||||||
|
查询参数:
|
||||||
|
- `object_type` - 对象类型(article/service)
|
||||||
|
- `object_id` - 对象 ID
|
||||||
|
|
||||||
|
**POST** `/api/comments/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "string",
|
||||||
|
"object_type": "article",
|
||||||
|
"object_id": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 评分
|
||||||
|
|
||||||
|
**POST** `/api/ratings/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"score": 5,
|
||||||
|
"object_type": "service",
|
||||||
|
"object_id": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 点赞
|
||||||
|
|
||||||
|
**POST** `/api/likes/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"object_type": "article",
|
||||||
|
"object_id": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.4 收藏
|
||||||
|
|
||||||
|
**POST** `/api/favorites/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"object_type": "region",
|
||||||
|
"object_id": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**GET** `/api/favorites/`
|
||||||
|
|
||||||
|
获取当前用户的收藏列表
|
||||||
|
|
||||||
|
## 7. 版主管理 API
|
||||||
|
|
||||||
|
### 7.1 申请版主
|
||||||
|
|
||||||
|
**POST** `/api/moderator-applications/`
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"region": 1,
|
||||||
|
"reason": "申请理由"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 获取版主申请列表
|
||||||
|
|
||||||
|
**GET** `/api/moderator-applications/`
|
||||||
|
|
||||||
|
**权限:** 管理员
|
||||||
|
|
||||||
|
### 7.3 审核版主申请
|
||||||
|
|
||||||
|
**POST** `/api/moderator-applications/{id}/review/`
|
||||||
|
|
||||||
|
**权限:** 管理员
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "approved",
|
||||||
|
"reason": "审核意见"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.4 获取版主权限
|
||||||
|
|
||||||
|
**GET** `/api/moderator-permissions/`
|
||||||
|
|
||||||
|
**权限:** 版主
|
||||||
|
|
||||||
|
## 8. GraphQL API
|
||||||
|
|
||||||
|
### 8.1 查询示例
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
query {
|
||||||
|
region(id: 1) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
level
|
||||||
|
children {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
articles {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
author {
|
||||||
|
username
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 变更示例
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
mutation {
|
||||||
|
createArticle(input: {
|
||||||
|
title: "深圳历史"
|
||||||
|
content: "内容"
|
||||||
|
region: 1
|
||||||
|
category: HISTORY
|
||||||
|
}) {
|
||||||
|
article {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. 错误码
|
||||||
|
|
||||||
|
| 错误码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `AUTH_FAILED` | 认证失败 |
|
||||||
|
| `PERMISSION_DENIED` | 权限不足 |
|
||||||
|
| `NOT_FOUND` | 资源不存在 |
|
||||||
|
| `VALIDATION_ERROR` | 参数验证错误 |
|
||||||
|
| `DUPLICATE` | 重复资源 |
|
||||||
|
| `INVALID_STATUS` | 无效状态 |
|
||||||
|
|
||||||
|
## 10. 速率限制
|
||||||
|
|
||||||
|
- 未认证用户:100 请求/小时
|
||||||
|
- 认证用户:1000 请求/小时
|
||||||
|
- 管理员:无限制
|
||||||
|
|
||||||
|
## 11. 版本控制
|
||||||
|
|
||||||
|
当前 API 版本:`v1`
|
||||||
|
|
||||||
|
版本格式:`/api/v1/`
|
||||||
278
city-manual/docs/ARCHITECTURE.md
Normal file
278
city-manual/docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
# 城市手册 - 系统架构文档
|
||||||
|
|
||||||
|
## 1. 系统概述
|
||||||
|
|
||||||
|
城市手册是一个地方志兼本地生活服务平台,采用前后端分离架构。
|
||||||
|
|
||||||
|
## 2. 技术架构
|
||||||
|
|
||||||
|
### 2.1 整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||||
|
│ 用户浏览器 │ ──→ │ Nginx │ ──→ │ React │
|
||||||
|
│ │ ←── │ 反向代理 │ ←── │ 前端应用 │
|
||||||
|
└─────────────┘ └──────────────┘ └─────────────┘
|
||||||
|
│
|
||||||
|
│
|
||||||
|
↓
|
||||||
|
┌──────────────┐
|
||||||
|
│ Django │
|
||||||
|
│ 后端 API │
|
||||||
|
└──────────────┘
|
||||||
|
│
|
||||||
|
↓
|
||||||
|
┌──────────────┐
|
||||||
|
│ PostgreSQL │
|
||||||
|
│ 数据库 │
|
||||||
|
└──────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 技术栈
|
||||||
|
|
||||||
|
**前端:**
|
||||||
|
- React 18
|
||||||
|
- MobX(状态管理)
|
||||||
|
- styled-components(CSS-in-JS)
|
||||||
|
- React Router(路由)
|
||||||
|
|
||||||
|
**后端:**
|
||||||
|
- Django 4.2
|
||||||
|
- Django REST Framework
|
||||||
|
- JWT 认证
|
||||||
|
- GraphQL (Graphene)
|
||||||
|
- PostgreSQL
|
||||||
|
|
||||||
|
**部署:**
|
||||||
|
- Docker & Docker Compose
|
||||||
|
- Nginx(反向代理)
|
||||||
|
- Gunicorn(WSGI 服务器)
|
||||||
|
|
||||||
|
## 3. 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
city-manual/
|
||||||
|
├── frontend/ # React 前端
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── components/ # React 组件
|
||||||
|
│ │ ├── stores/ # MobX 状态管理
|
||||||
|
│ │ ├── services/ # API 服务
|
||||||
|
│ │ ├── styles/ # 全局样式
|
||||||
|
│ │ └── utils/ # 工具函数
|
||||||
|
│ └── public/
|
||||||
|
├── backend/ # Django 后端
|
||||||
|
│ ├── config/ # 项目配置
|
||||||
|
│ ├── apps/
|
||||||
|
│ │ ├── users/ # 用户管理
|
||||||
|
│ │ ├── regions/ # 版块管理
|
||||||
|
│ │ ├── articles/ # 内容管理
|
||||||
|
│ │ ├── services/ # 特色服务
|
||||||
|
│ │ └── interactions/ # 互动功能
|
||||||
|
│ └── static/ # 静态文件
|
||||||
|
├── docs/ # 项目文档
|
||||||
|
├── skills/ # AgentSkills
|
||||||
|
└── scripts/ # 部署脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 核心模块
|
||||||
|
|
||||||
|
### 4.1 用户模块 (users)
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 用户注册/登录
|
||||||
|
- JWT 认证
|
||||||
|
- 个人中心
|
||||||
|
- 角色管理(普通用户/版主/管理员)
|
||||||
|
|
||||||
|
**数据表:**
|
||||||
|
- `users_user` - 用户表
|
||||||
|
|
||||||
|
### 4.2 版块模块 (regions)
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 省→市→县→乡镇→村 五级层级管理
|
||||||
|
- 版块 CRUD
|
||||||
|
- 版主申请
|
||||||
|
|
||||||
|
**数据表:**
|
||||||
|
- `regions_region` - 版块表
|
||||||
|
- `regions_moderatorapplication` - 版主申请表
|
||||||
|
- `regions_moderatorpermission` - 版主权限表
|
||||||
|
|
||||||
|
### 4.3 内容模块 (articles)
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 文章管理
|
||||||
|
- 内容审核(版主初审 + AI 审核)
|
||||||
|
- 发布流程
|
||||||
|
|
||||||
|
**数据表:**
|
||||||
|
- `articles_article` - 文章表
|
||||||
|
|
||||||
|
### 4.4 特色服务模块 (services)
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 特色服务管理(衣食住行娱乐旅游文化)
|
||||||
|
- 服务审核
|
||||||
|
- 服务展示
|
||||||
|
|
||||||
|
**数据表:**
|
||||||
|
- `services_featuredservice` - 特色服务表
|
||||||
|
|
||||||
|
### 4.5 互动模块 (interactions)
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 评论
|
||||||
|
- 评分
|
||||||
|
- 点赞
|
||||||
|
- 收藏
|
||||||
|
|
||||||
|
**数据表:**
|
||||||
|
- `interactions_comment` - 评论表
|
||||||
|
- `interactions_rating` - 评分表
|
||||||
|
- `interactions_like` - 点赞表
|
||||||
|
- `interactions_favorite` - 收藏表
|
||||||
|
|
||||||
|
## 5. API 设计
|
||||||
|
|
||||||
|
### 5.1 REST API
|
||||||
|
|
||||||
|
| 端点 | 方法 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `/api/users/` | GET, POST | 用户管理 |
|
||||||
|
| `/api/users/me/` | GET, PUT, PATCH | 当前用户 |
|
||||||
|
| `/api/auth/token/` | POST | 登录 |
|
||||||
|
| `/api/auth/token/refresh/` | POST | 刷新令牌 |
|
||||||
|
| `/api/regions/` | GET, POST | 版块管理 |
|
||||||
|
| `/api/articles/` | GET, POST | 文章管理 |
|
||||||
|
| `/api/services/` | GET, POST | 特色服务 |
|
||||||
|
| `/api/comments/` | GET, POST | 评论 |
|
||||||
|
| `/api/ratings/` | GET, POST | 评分 |
|
||||||
|
| `/api/likes/` | GET, POST | 点赞 |
|
||||||
|
| `/api/favorites/` | GET, POST | 收藏 |
|
||||||
|
|
||||||
|
### 5.2 GraphQL API
|
||||||
|
|
||||||
|
端点:`/graphql/`
|
||||||
|
|
||||||
|
**Query 类型:**
|
||||||
|
- `user(id: ID!)` - 获取用户
|
||||||
|
- `region(id: ID!)` - 获取版块
|
||||||
|
- `article(id: ID!)` - 获取文章
|
||||||
|
- `featuredService(id: ID!)` - 获取特色服务
|
||||||
|
|
||||||
|
**Mutation 类型:**
|
||||||
|
- `createArticle(input: ArticleInput!)` - 创建文章
|
||||||
|
- `updateArticle(id: ID!, input: ArticleInput!)` - 更新文章
|
||||||
|
- `deleteArticle(id: ID!)` - 删除文章
|
||||||
|
|
||||||
|
## 6. 审核流程
|
||||||
|
|
||||||
|
### 6.1 内容审核
|
||||||
|
|
||||||
|
```
|
||||||
|
用户提交 → 版主初审 → AI 审核 → 发布
|
||||||
|
↓ ↓
|
||||||
|
拒绝 拒绝
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 版主申请
|
||||||
|
|
||||||
|
```
|
||||||
|
用户申请 → 征集支持 → 管理员审核 → 授予权限
|
||||||
|
↓
|
||||||
|
支持不足(自动取消)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. 权限控制
|
||||||
|
|
||||||
|
### 7.1 角色权限
|
||||||
|
|
||||||
|
| 角色 | 权限 |
|
||||||
|
|------|------|
|
||||||
|
| 普通用户 | 浏览、评论、评分、点赞、收藏、申请版主 |
|
||||||
|
| 版主 | 管辖范围内内容初审、申请创建版块 |
|
||||||
|
| 管理员 | 全局管理、版主审核、权限管理 |
|
||||||
|
|
||||||
|
### 7.2 版主审核权限
|
||||||
|
|
||||||
|
版主只能审核其管辖范围内的内容:
|
||||||
|
- 省级版主 → 全省内容
|
||||||
|
- 市级版主 → 全市内容
|
||||||
|
- 县级版主 → 全县内容
|
||||||
|
- 以此类推
|
||||||
|
|
||||||
|
## 8. 部署架构
|
||||||
|
|
||||||
|
### 8.1 生产环境
|
||||||
|
|
||||||
|
```
|
||||||
|
用户 → Nginx (80/443) → Gunicorn (8000) → Django
|
||||||
|
↓
|
||||||
|
PostgreSQL (5432)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 Docker 服务
|
||||||
|
|
||||||
|
- `web` - Django 后端
|
||||||
|
- `frontend` - React 前端(Nginx)
|
||||||
|
- `db` - PostgreSQL
|
||||||
|
- `redis` - 缓存(可选)
|
||||||
|
|
||||||
|
## 9. 安全考虑
|
||||||
|
|
||||||
|
### 9.1 认证安全
|
||||||
|
- JWT 令牌认证
|
||||||
|
- 令牌有效期控制
|
||||||
|
- 刷新令牌机制
|
||||||
|
|
||||||
|
### 9.2 数据安全
|
||||||
|
- 密码加密存储(PBKDF2)
|
||||||
|
- SQL 注入防护(Django ORM)
|
||||||
|
- XSS 防护
|
||||||
|
|
||||||
|
### 9.3 访问控制
|
||||||
|
- CORS 配置
|
||||||
|
- 权限验证
|
||||||
|
- 速率限制
|
||||||
|
|
||||||
|
## 10. 性能优化
|
||||||
|
|
||||||
|
### 10.1 数据库优化
|
||||||
|
- 索引设计
|
||||||
|
- 查询优化
|
||||||
|
- 连接池
|
||||||
|
|
||||||
|
### 10.2 缓存策略
|
||||||
|
- Redis 缓存
|
||||||
|
- 页面缓存
|
||||||
|
- API 响应缓存
|
||||||
|
|
||||||
|
### 10.3 前端优化
|
||||||
|
- 代码分割
|
||||||
|
- 懒加载
|
||||||
|
- 资源压缩
|
||||||
|
|
||||||
|
## 11. 监控和日志
|
||||||
|
|
||||||
|
### 11.1 应用监控
|
||||||
|
- 错误追踪
|
||||||
|
- 性能监控
|
||||||
|
- 用户行为分析
|
||||||
|
|
||||||
|
### 11.2 日志管理
|
||||||
|
- Django 日志
|
||||||
|
- Nginx 日志
|
||||||
|
- 系统日志
|
||||||
|
|
||||||
|
## 12. 扩展性设计
|
||||||
|
|
||||||
|
### 12.1 水平扩展
|
||||||
|
- 无状态服务设计
|
||||||
|
- 数据库读写分离
|
||||||
|
- 负载均衡
|
||||||
|
|
||||||
|
### 12.2 功能扩展
|
||||||
|
- 插件化设计
|
||||||
|
- API 版本控制
|
||||||
|
- 微服务拆分预留
|
||||||
286
city-manual/docs/README.md
Normal file
286
city-manual/docs/README.md
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
# 城市手册 - 项目文档
|
||||||
|
|
||||||
|
## 文档索引
|
||||||
|
|
||||||
|
### 核心文档
|
||||||
|
|
||||||
|
| 文档 | 说明 | 路径 |
|
||||||
|
|------|------|------|
|
||||||
|
| 📖 需求文档 | 项目需求说明 | [城市手册需求文档.md](../城市手册需求文档.md) |
|
||||||
|
| 🏗️ 架构文档 | 系统架构设计 | [ARCHITECTURE.md](./ARCHITECTURE.md) |
|
||||||
|
| 🔌 API 文档 | API 接口说明 | [API.md](./API.md) |
|
||||||
|
| 📝 实施计划 | 需求实施进度 | [REQUIREMENTS_IMPLEMENTATION.md](../REQUIREMENTS_IMPLEMENTATION.md) |
|
||||||
|
|
||||||
|
### 开发文档
|
||||||
|
|
||||||
|
| 文档 | 说明 | 路径 |
|
||||||
|
|------|------|------|
|
||||||
|
| 💻 开发指南 | 开发环境配置 | [DEVELOPMENT_SUMMARY.md](../DEVELOPMENT_SUMMARY.md) |
|
||||||
|
| 🚀 部署指南 | 生产环境部署 | [DEPLOYMENT.md](../DEPLOYMENT.md) |
|
||||||
|
| 🧪 测试指南 | 测试方法和用例 | [TESTING.md](../TESTING.md) |
|
||||||
|
| 🤖 AI 助手 | AI 协作指南 | [AI_AGENT.md](../AI_AGENT.md) |
|
||||||
|
|
||||||
|
### 技能文档
|
||||||
|
|
||||||
|
| 技能 | 说明 | 路径 |
|
||||||
|
|------|------|------|
|
||||||
|
| 📦 部署技能 | 自动化部署 | [skills/city-manual-deploy/SKILL.md](../skills/city-manual-deploy/SKILL.md) |
|
||||||
|
| 🧪 测试技能 | 测试和验证 | [skills/city-manual-test/SKILL.md](../skills/city-manual-test/SKILL.md) |
|
||||||
|
| 📝 内容技能 | 内容管理 | [skills/city-manual-content/SKILL.md](../skills/city-manual-content/SKILL.md) |
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 开发环境
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆项目
|
||||||
|
git clone http://10.2.0.100:8989/mashen/chengshishouce.git
|
||||||
|
cd chengshishouce/city-manual
|
||||||
|
|
||||||
|
# 后端启动
|
||||||
|
cd backend
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python manage.py migrate
|
||||||
|
python manage.py runserver
|
||||||
|
|
||||||
|
# 前端启动
|
||||||
|
cd ../frontend
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生产部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用部署脚本
|
||||||
|
cd /root/.openclaw/workspace/city-manual
|
||||||
|
./deploy.sh
|
||||||
|
|
||||||
|
# 或使用 Docker
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
city-manual/
|
||||||
|
├── docs/ # 项目文档
|
||||||
|
│ ├── ARCHITECTURE.md # 架构文档
|
||||||
|
│ ├── API.md # API 文档
|
||||||
|
│ └── README.md # 文档索引
|
||||||
|
├── skills/ # AgentSkills
|
||||||
|
│ ├── city-manual-deploy/ # 部署技能
|
||||||
|
│ ├── city-manual-test/ # 测试技能
|
||||||
|
│ └── city-manual-content/# 内容技能
|
||||||
|
├── backend/ # Django 后端
|
||||||
|
│ ├── config/ # 项目配置
|
||||||
|
│ ├── apps/ # Django 应用
|
||||||
|
│ └── manage.py # Django 管理脚本
|
||||||
|
├── frontend/ # React 前端
|
||||||
|
│ ├── src/ # 源代码
|
||||||
|
│ └── package.json # 依赖配置
|
||||||
|
├── scripts/ # 脚本文件
|
||||||
|
│ ├── deploy.sh # 部署脚本
|
||||||
|
│ └── gunicorn_start.sh # Gunicorn 启动脚本
|
||||||
|
└── test_api.py # API 测试脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
### 后端
|
||||||
|
- **框架:** Django 4.2
|
||||||
|
- **API:** Django REST Framework + GraphQL
|
||||||
|
- **认证:** JWT
|
||||||
|
- **数据库:** PostgreSQL
|
||||||
|
|
||||||
|
### 前端
|
||||||
|
- **框架:** React 18
|
||||||
|
- **状态管理:** MobX
|
||||||
|
- **样式:** styled-components
|
||||||
|
- **路由:** React Router
|
||||||
|
|
||||||
|
### 部署
|
||||||
|
- **容器:** Docker & Docker Compose
|
||||||
|
- **服务器:** Nginx + Gunicorn
|
||||||
|
- **监控:** 健康检查 + 日志
|
||||||
|
|
||||||
|
## 核心功能
|
||||||
|
|
||||||
|
### 用户系统
|
||||||
|
- ✅ 用户注册/登录
|
||||||
|
- ✅ JWT 认证
|
||||||
|
- ✅ 个人中心
|
||||||
|
- ✅ 角色管理
|
||||||
|
|
||||||
|
### 版块管理
|
||||||
|
- ✅ 省→市→县→乡镇→村 五级层级
|
||||||
|
- ✅ 版块 CRUD
|
||||||
|
- ✅ 版主申请
|
||||||
|
|
||||||
|
### 内容管理
|
||||||
|
- ✅ 文章管理
|
||||||
|
- ✅ 特色服务
|
||||||
|
- ✅ 内容审核(版主 + AI)
|
||||||
|
|
||||||
|
### 互动功能
|
||||||
|
- ✅ 评论
|
||||||
|
- ✅ 评分
|
||||||
|
- ✅ 点赞
|
||||||
|
- ✅ 收藏
|
||||||
|
|
||||||
|
## 数据库设计
|
||||||
|
|
||||||
|
### 核心表
|
||||||
|
|
||||||
|
| 表名 | 说明 | 主要字段 |
|
||||||
|
|------|------|----------|
|
||||||
|
| `users_user` | 用户表 | username, email, role |
|
||||||
|
| `regions_region` | 版块表 | name, level, parent |
|
||||||
|
| `articles_article` | 文章表 | title, content, region, category |
|
||||||
|
| `services_featuredservice` | 特色服务表 | name, description, category |
|
||||||
|
| `interactions_comment` | 评论表 | content, object_type, object_id |
|
||||||
|
| `interactions_rating` | 评分表 | score, object_type, object_id |
|
||||||
|
| `interactions_like` | 点赞表 | object_type, object_id |
|
||||||
|
| `interactions_favorite` | 收藏表 | object_type, object_id |
|
||||||
|
|
||||||
|
## API 端点
|
||||||
|
|
||||||
|
### REST API
|
||||||
|
|
||||||
|
- `GET /api/users/` - 用户列表
|
||||||
|
- `POST /api/auth/token/` - 登录
|
||||||
|
- `GET /api/regions/` - 版块列表
|
||||||
|
- `GET /api/articles/` - 文章列表
|
||||||
|
- `GET /api/services/` - 特色服务列表
|
||||||
|
|
||||||
|
### GraphQL API
|
||||||
|
|
||||||
|
- `POST /graphql/` - GraphQL 端点
|
||||||
|
- `GET /graphql/?graphiql` - GraphQL Playground
|
||||||
|
|
||||||
|
## 开发规范
|
||||||
|
|
||||||
|
### 代码风格
|
||||||
|
|
||||||
|
**Python:**
|
||||||
|
- 遵循 PEP 8
|
||||||
|
- 使用 Black 格式化
|
||||||
|
- 类型注解
|
||||||
|
|
||||||
|
**JavaScript:**
|
||||||
|
- 使用 ESLint
|
||||||
|
- 使用 Prettier
|
||||||
|
- ES6+ 语法
|
||||||
|
|
||||||
|
### Git 工作流
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建功能分支
|
||||||
|
git checkout -b feature/feature-name
|
||||||
|
|
||||||
|
# 提交代码
|
||||||
|
git add .
|
||||||
|
git commit -m "feat: add new feature"
|
||||||
|
|
||||||
|
# 推送分支
|
||||||
|
git push origin feature/feature-name
|
||||||
|
|
||||||
|
# 创建 Pull Request
|
||||||
|
```
|
||||||
|
|
||||||
|
### 提交信息规范
|
||||||
|
|
||||||
|
- `feat:` 新功能
|
||||||
|
- `fix:` 修复 bug
|
||||||
|
- `docs:` 文档更新
|
||||||
|
- `style:` 代码格式
|
||||||
|
- `refactor:` 重构
|
||||||
|
- `test:` 测试
|
||||||
|
- `chore:` 构建/工具
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
### 运行测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 后端测试
|
||||||
|
cd backend
|
||||||
|
python manage.py test
|
||||||
|
|
||||||
|
# 前端测试
|
||||||
|
cd frontend
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# API 测试
|
||||||
|
python test_api.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 测试覆盖率
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 后端覆盖率
|
||||||
|
coverage run --source='.' manage.py test
|
||||||
|
coverage report
|
||||||
|
coverage html
|
||||||
|
```
|
||||||
|
|
||||||
|
## 监控和维护
|
||||||
|
|
||||||
|
### 健康检查
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查服务状态
|
||||||
|
curl http://127.0.0.1:8000/admin/
|
||||||
|
curl http://127.0.0.1/
|
||||||
|
|
||||||
|
# 检查数据库
|
||||||
|
psql -h 10.2.0.100 -U coder -d cssc -c "SELECT 1"
|
||||||
|
|
||||||
|
# 检查日志
|
||||||
|
tail -f /var/log/nginx/error.log
|
||||||
|
tail -f gunicorn.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志管理
|
||||||
|
|
||||||
|
- **Django 日志:** `backend/logs/`
|
||||||
|
- **Nginx 日志:** `/var/log/nginx/`
|
||||||
|
- **Gunicorn 日志:** `gunicorn.log`
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q: 如何重置数据库?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
python manage.py flush
|
||||||
|
python manage.py migrate
|
||||||
|
python manage.py createsuperuser
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 如何重置管理员密码?
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
python manage.py changepassword admin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 如何查看 API 文档?
|
||||||
|
|
||||||
|
访问:http://localhost:8000/graphql/?graphiql
|
||||||
|
|
||||||
|
### Q: 如何部署到生产环境?
|
||||||
|
|
||||||
|
参考 [DEPLOYMENT.md](../DEPLOYMENT.md)
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
- **项目仓库:** http://10.2.0.100:8989/mashen/chengshishouce.git
|
||||||
|
- **在线访问:** http://cssc.datalibstar.com/
|
||||||
|
- **Admin:** http://cssc.datalibstar.com/admin/
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT License
|
||||||
282
city-manual/skills/city-manual-content/SKILL.md
Normal file
282
city-manual/skills/city-manual-content/SKILL.md
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
# Skill: city-manual-content
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
城市手册内容管理技能。用于管理城市内容、文章和特色服务。
|
||||||
|
|
||||||
|
## Location
|
||||||
|
|
||||||
|
`/root/.openclaw/workspace/city-manual/skills/city-manual-content/`
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
- 创建和编辑文章
|
||||||
|
- 管理特色服务
|
||||||
|
- 内容审核
|
||||||
|
- 版块管理
|
||||||
|
- 内容导入导出
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
当用户提到以下关键词时激活此技能:
|
||||||
|
- "创建文章"
|
||||||
|
- "编辑内容"
|
||||||
|
- "管理特色服务"
|
||||||
|
- "内容审核"
|
||||||
|
- "版块管理"
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
### 文章表 (articles_article)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE articles_article (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
title VARCHAR(200) NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
region_id INTEGER REFERENCES regions_region(id),
|
||||||
|
category VARCHAR(50),
|
||||||
|
author_id INTEGER REFERENCES users_user(id),
|
||||||
|
moderator_id INTEGER REFERENCES users_user(id),
|
||||||
|
status VARCHAR(20),
|
||||||
|
view_count INTEGER DEFAULT 0,
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 特色服务表 (services_featuredservice)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE services_featuredservice (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(200) NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
region_id INTEGER REFERENCES regions_region(id),
|
||||||
|
category VARCHAR(50),
|
||||||
|
address VARCHAR(500),
|
||||||
|
contact VARCHAR(200),
|
||||||
|
rating DECIMAL(3,2),
|
||||||
|
status VARCHAR(20),
|
||||||
|
author_id INTEGER REFERENCES users_user(id),
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Content Categories
|
||||||
|
|
||||||
|
### 文章分类
|
||||||
|
|
||||||
|
- `history` - 历史
|
||||||
|
- `culture` - 文化
|
||||||
|
- `practical` - 实用信息
|
||||||
|
- `life` - 生活指南
|
||||||
|
|
||||||
|
### 特色服务分类
|
||||||
|
|
||||||
|
- `clothing` - 衣
|
||||||
|
- `food` - 食
|
||||||
|
- `accommodation` - 住
|
||||||
|
- `transportation` - 行
|
||||||
|
- `entertainment` - 娱乐
|
||||||
|
- `tourism` - 旅游
|
||||||
|
- `culture` - 文化
|
||||||
|
|
||||||
|
## Workflows
|
||||||
|
|
||||||
|
### 内容创建流程
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 用户创建内容
|
||||||
|
↓
|
||||||
|
2. 保存到数据库(status=draft)
|
||||||
|
↓
|
||||||
|
3. 提交审核(status=pending)
|
||||||
|
↓
|
||||||
|
4. 版主初审
|
||||||
|
↓
|
||||||
|
5. AI 审核
|
||||||
|
↓
|
||||||
|
6. 发布(status=published)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 内容审核规则
|
||||||
|
|
||||||
|
**版主审核权限:**
|
||||||
|
- 版主只能审核管辖范围内的内容
|
||||||
|
- 上级版主可以审核下级版块内容
|
||||||
|
- 管理员可以审核所有内容
|
||||||
|
|
||||||
|
**AI 审核规则:**
|
||||||
|
- 检查敏感词
|
||||||
|
- 检查内容质量
|
||||||
|
- 检查重复内容
|
||||||
|
- 检查违规信息
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### 创建文章
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/.openclaw/workspace/city-manual/backend
|
||||||
|
python manage.py shell
|
||||||
|
|
||||||
|
>>> from apps.articles.models import Article
|
||||||
|
>>> article = Article.objects.create(
|
||||||
|
... title="文章标题",
|
||||||
|
... content="文章内容",
|
||||||
|
... region_id=1,
|
||||||
|
... category="history",
|
||||||
|
... author_id=1,
|
||||||
|
... status="draft"
|
||||||
|
... )
|
||||||
|
```
|
||||||
|
|
||||||
|
### 批量导入内容
|
||||||
|
|
||||||
|
```python
|
||||||
|
import json
|
||||||
|
|
||||||
|
with open('content.json', 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
for item in data:
|
||||||
|
Article.objects.create(
|
||||||
|
title=item['title'],
|
||||||
|
content=item['content'],
|
||||||
|
region_id=item['region_id'],
|
||||||
|
category=item['category'],
|
||||||
|
status='published'
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 内容审核
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 版主审核
|
||||||
|
article = Article.objects.get(id=1)
|
||||||
|
article.moderator_id = 1
|
||||||
|
article.moderator_reviewed_at = timezone.now()
|
||||||
|
article.moderator_status = 'approved'
|
||||||
|
article.status = 'pending_ai'
|
||||||
|
article.save()
|
||||||
|
|
||||||
|
# AI 审核
|
||||||
|
article.ai_status = 'approved'
|
||||||
|
article.ai_reviewed_at = timezone.now()
|
||||||
|
article.status = 'published'
|
||||||
|
article.save()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 内容导出
|
||||||
|
|
||||||
|
```python
|
||||||
|
import json
|
||||||
|
from django.core.serializers import serialize
|
||||||
|
|
||||||
|
articles = Article.objects.filter(status='published')
|
||||||
|
data = serialize('python', articles)
|
||||||
|
|
||||||
|
with open('articles_export.json', 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Content Templates
|
||||||
|
|
||||||
|
### 城市信息模板
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# {城市名称}
|
||||||
|
|
||||||
|
## 基础信息
|
||||||
|
- 地理位置:
|
||||||
|
- 人口:
|
||||||
|
- 气候:
|
||||||
|
- 行政区划:
|
||||||
|
|
||||||
|
## 历史
|
||||||
|
{城市历史介绍}
|
||||||
|
|
||||||
|
## 文化
|
||||||
|
- 方言:
|
||||||
|
- 习俗:
|
||||||
|
- 节庆:
|
||||||
|
- 特色小吃:
|
||||||
|
|
||||||
|
## 实用信息
|
||||||
|
- 交通:
|
||||||
|
- 教育:
|
||||||
|
- 医疗:
|
||||||
|
- 商业:
|
||||||
|
|
||||||
|
## 生活推荐
|
||||||
|
- 餐厅:
|
||||||
|
- 景点:
|
||||||
|
- 活动:
|
||||||
|
- 攻略:
|
||||||
|
```
|
||||||
|
|
||||||
|
### 特色服务模板
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# {服务名称}
|
||||||
|
|
||||||
|
## 基本信息
|
||||||
|
- 分类:
|
||||||
|
- 地址:
|
||||||
|
- 联系方式:
|
||||||
|
- 营业时间:
|
||||||
|
|
||||||
|
## 介绍
|
||||||
|
{服务详细介绍}
|
||||||
|
|
||||||
|
## 特色
|
||||||
|
{服务特色}
|
||||||
|
|
||||||
|
## 评价
|
||||||
|
{用户评价摘要}
|
||||||
|
|
||||||
|
## 图片
|
||||||
|
[图片链接]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quality Guidelines
|
||||||
|
|
||||||
|
### 内容质量标准
|
||||||
|
|
||||||
|
1. **准确性**
|
||||||
|
- 信息真实可靠
|
||||||
|
- 数据来源可查
|
||||||
|
- 及时更新
|
||||||
|
|
||||||
|
2. **完整性**
|
||||||
|
- 关键信息不缺失
|
||||||
|
- 结构清晰
|
||||||
|
- 分类正确
|
||||||
|
|
||||||
|
3. **可读性**
|
||||||
|
- 语言流畅
|
||||||
|
- 格式规范
|
||||||
|
- 排版美观
|
||||||
|
|
||||||
|
4. **实用性**
|
||||||
|
- 对用户有价值
|
||||||
|
- 信息可操作
|
||||||
|
- 本地化特色
|
||||||
|
|
||||||
|
### 审核检查清单
|
||||||
|
|
||||||
|
- [ ] 标题准确反映内容
|
||||||
|
- [ ] 内容无错别字
|
||||||
|
- [ ] 分类正确
|
||||||
|
- [ ] 图片清晰
|
||||||
|
- [ ] 联系方式有效
|
||||||
|
- [ ] 无违规内容
|
||||||
|
- [ ] 无敏感信息
|
||||||
|
- [ ] 格式规范
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [API.md](../../docs/API.md)
|
||||||
|
- [ARCHITECTURE.md](../../docs/ARCHITECTURE.md)
|
||||||
156
city-manual/skills/city-manual-deploy/SKILL.md
Normal file
156
city-manual/skills/city-manual-deploy/SKILL.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# Skill: city-manual-deploy
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
城市手册项目部署技能。用于自动化部署城市手册项目到生产环境。
|
||||||
|
|
||||||
|
## Location
|
||||||
|
|
||||||
|
`/root/.openclaw/workspace/city-manual/skills/city-manual-deploy/`
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
- 检查部署环境
|
||||||
|
- 配置 Nginx 反向代理
|
||||||
|
- 启动 Gunicorn 服务
|
||||||
|
- 数据库迁移
|
||||||
|
- 静态文件收集
|
||||||
|
- 服务健康检查
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
当用户提到以下关键词时激活此技能:
|
||||||
|
- "部署城市手册"
|
||||||
|
- "deploy city manual"
|
||||||
|
- "上线项目"
|
||||||
|
- "生产环境配置"
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
### deploy.sh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# 城市手册部署脚本
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PROJECT_DIR="/root/.openclaw/workspace/city-manual"
|
||||||
|
VENV_DIR="$PROJECT_DIR/backend/venv"
|
||||||
|
GUNICORN_SOCKET="$PROJECT_DIR/gunicorn.sock"
|
||||||
|
GUNICORN_LOG="$PROJECT_DIR/gunicorn.log"
|
||||||
|
|
||||||
|
echo "=== 城市手册部署开始 ==="
|
||||||
|
|
||||||
|
# 1. 激活虚拟环境
|
||||||
|
source $VENV_DIR/bin/activate
|
||||||
|
|
||||||
|
# 2. 数据库迁移
|
||||||
|
cd $PROJECT_DIR/backend
|
||||||
|
python manage.py migrate
|
||||||
|
|
||||||
|
# 3. 收集静态文件
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
# 4. 重启 Gunicorn
|
||||||
|
pkill -f gunicorn || true
|
||||||
|
sleep 2
|
||||||
|
cd $PROJECT_DIR
|
||||||
|
./gunicorn_start.sh
|
||||||
|
|
||||||
|
# 5. 检查服务状态
|
||||||
|
sleep 3
|
||||||
|
if pgrep -f gunicorn > /dev/null; then
|
||||||
|
echo "✅ Gunicorn 启动成功"
|
||||||
|
else
|
||||||
|
echo "❌ Gunicorn 启动失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. Nginx 配置检查
|
||||||
|
nginx -t
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
systemctl reload nginx
|
||||||
|
echo "✅ Nginx 重载成功"
|
||||||
|
else
|
||||||
|
echo "❌ Nginx 配置错误"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== 部署完成 ==="
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### 环境变量
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# .env 文件
|
||||||
|
DJANGO_SETTINGS_MODULE=config.settings.production
|
||||||
|
DJANGO_SECRET_KEY=your-secret-key
|
||||||
|
DATABASE_URL=postgres://user:pass@localhost:5432/cssc
|
||||||
|
ALLOWED_HOSTS=cssc.datalibstar.com,127.0.0.1
|
||||||
|
DEBUG=False
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nginx 配置
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name cssc.datalibstar.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
alias /root/.openclaw/workspace/city-manual/backend/static/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /media/ {
|
||||||
|
alias /root/.openclaw/workspace/city-manual/backend/media/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Health Check
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查 Gunicorn
|
||||||
|
curl http://127.0.0.1:8000/admin/
|
||||||
|
|
||||||
|
# 检查数据库
|
||||||
|
psql -h localhost -U coder -d cssc -c "SELECT 1"
|
||||||
|
|
||||||
|
# 检查 Nginx
|
||||||
|
curl http://cssc.datalibstar.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Gunicorn 启动失败
|
||||||
|
|
||||||
|
1. 检查端口占用:`lsof -i :8000`
|
||||||
|
2. 查看日志:`tail -f gunicorn.log`
|
||||||
|
3. 检查虚拟环境:`source backend/venv/bin/activate`
|
||||||
|
|
||||||
|
### 数据库连接失败
|
||||||
|
|
||||||
|
1. 检查 PostgreSQL 服务:`systemctl status postgresql`
|
||||||
|
2. 验证连接:`psql -h localhost -U coder -d cssc`
|
||||||
|
3. 检查 .env 配置
|
||||||
|
|
||||||
|
### 静态文件 404
|
||||||
|
|
||||||
|
1. 重新收集:`python manage.py collectstatic --noinput`
|
||||||
|
2. 检查 Nginx 配置路径
|
||||||
|
3. 重载 Nginx:`systemctl reload nginx`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [DEPLOYMENT.md](../../DEPLOYMENT.md)
|
||||||
|
- [scripts/deploy.sh](../../deploy.sh)
|
||||||
|
- [scripts/gunicorn_start.sh](../../gunicorn_start.sh)
|
||||||
229
city-manual/skills/city-manual-test/SKILL.md
Normal file
229
city-manual/skills/city-manual-test/SKILL.md
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
# Skill: city-manual-test
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
城市手册项目测试技能。用于运行项目测试和 API 验证。
|
||||||
|
|
||||||
|
## Location
|
||||||
|
|
||||||
|
`/root/.openclaw/workspace/city-manual/skills/city-manual-test/`
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
- 运行 Django 测试
|
||||||
|
- API 端点测试
|
||||||
|
- 数据库连接测试
|
||||||
|
- 前端构建测试
|
||||||
|
- 性能测试
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
当用户提到以下关键词时激活此技能:
|
||||||
|
- "测试城市手册"
|
||||||
|
- "run tests"
|
||||||
|
- "API 测试"
|
||||||
|
- "验证功能"
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
### test_api.py
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
城市手册 API 测试脚本
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
BASE_URL = "http://127.0.0.1:8000/api"
|
||||||
|
|
||||||
|
def test_auth():
|
||||||
|
"""测试认证 API"""
|
||||||
|
print("=== 测试认证 API ===")
|
||||||
|
|
||||||
|
# 登录
|
||||||
|
response = requests.post(f"{BASE_URL}/auth/token/", json={
|
||||||
|
"username": "demo",
|
||||||
|
"password": "demo123"
|
||||||
|
})
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
token = response.json()["access"]
|
||||||
|
print("✅ 登录成功")
|
||||||
|
return token
|
||||||
|
else:
|
||||||
|
print(f"❌ 登录失败:{response.status_code}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def test_users(token):
|
||||||
|
"""测试用户 API"""
|
||||||
|
print("\n=== 测试用户 API ===")
|
||||||
|
|
||||||
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
# 获取当前用户
|
||||||
|
response = requests.get(f"{BASE_URL}/users/me/", headers=headers)
|
||||||
|
if response.status_code == 200:
|
||||||
|
print(f"✅ 获取用户信息成功:{response.json()['username']}")
|
||||||
|
else:
|
||||||
|
print(f"❌ 获取用户信息失败:{response.status_code}")
|
||||||
|
|
||||||
|
def test_regions(token):
|
||||||
|
"""测试版块 API"""
|
||||||
|
print("\n=== 测试版块 API ===")
|
||||||
|
|
||||||
|
# 获取版块列表
|
||||||
|
response = requests.get(f"{BASE_URL}/regions/")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f"✅ 获取版块列表成功:共 {data['count']} 个版块")
|
||||||
|
if data['results']:
|
||||||
|
print(f" 第一个版块:{data['results'][0]['name']}")
|
||||||
|
else:
|
||||||
|
print(f"❌ 获取版块列表失败:{response.status_code}")
|
||||||
|
|
||||||
|
def test_articles(token):
|
||||||
|
"""测试文章 API"""
|
||||||
|
print("\n=== 测试文章 API ===")
|
||||||
|
|
||||||
|
# 获取文章列表
|
||||||
|
response = requests.get(f"{BASE_URL}/articles/")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f"✅ 获取文章列表成功:共 {data['count']} 篇文章")
|
||||||
|
else:
|
||||||
|
print(f"❌ 获取文章列表失败:{response.status_code}")
|
||||||
|
|
||||||
|
def test_services(token):
|
||||||
|
"""测试特色服务 API"""
|
||||||
|
print("\n=== 测试特色服务 API ===")
|
||||||
|
|
||||||
|
# 获取特色服务列表
|
||||||
|
response = requests.get(f"{BASE_URL}/services/")
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()
|
||||||
|
print(f"✅ 获取特色服务列表成功:共 {data['count']} 个服务")
|
||||||
|
else:
|
||||||
|
print(f"❌ 获取特色服务列表失败:{response.status_code}")
|
||||||
|
|
||||||
|
def test_database():
|
||||||
|
"""测试数据库连接"""
|
||||||
|
print("\n=== 测试数据库连接 ===")
|
||||||
|
|
||||||
|
import psycopg2
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = psycopg2.connect(
|
||||||
|
host="10.2.0.100",
|
||||||
|
port=5432,
|
||||||
|
database="cssc",
|
||||||
|
user="coder",
|
||||||
|
password="825670wl"
|
||||||
|
)
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute("SELECT 1")
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
print("✅ 数据库连接成功")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 数据库连接失败:{e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("城市手册 API 测试开始\n")
|
||||||
|
|
||||||
|
# 测试数据库
|
||||||
|
test_database()
|
||||||
|
|
||||||
|
# 测试认证
|
||||||
|
token = test_auth()
|
||||||
|
if not token:
|
||||||
|
print("\n❌ 认证失败,停止测试")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 测试各 API
|
||||||
|
test_users(token)
|
||||||
|
test_regions(token)
|
||||||
|
test_articles(token)
|
||||||
|
test_services(token)
|
||||||
|
|
||||||
|
print("\n=== 测试完成 ===")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### 运行 Django 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/.openclaw/workspace/city-manual/backend
|
||||||
|
python manage.py test
|
||||||
|
```
|
||||||
|
|
||||||
|
### 运行 API 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/.openclaw/workspace/city-manual
|
||||||
|
python test_api.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 运行前端测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/.openclaw/workspace/city-manual/frontend
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据库连接测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -h 10.2.0.100 -U coder -d cssc -c "SELECT 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Health Check
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查所有服务
|
||||||
|
curl http://127.0.0.1:8000/admin/
|
||||||
|
curl http://127.0.0.1/
|
||||||
|
psql -h 10.2.0.100 -U coder -d cssc -c "SELECT 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Cases
|
||||||
|
|
||||||
|
### 用户认证测试
|
||||||
|
1. 正常登录
|
||||||
|
2. 错误密码
|
||||||
|
3. 令牌刷新
|
||||||
|
4. 令牌过期
|
||||||
|
|
||||||
|
### 版块管理测试
|
||||||
|
1. 获取版块列表
|
||||||
|
2. 获取版块详情
|
||||||
|
3. 创建版块(管理员)
|
||||||
|
4. 版块层级查询
|
||||||
|
|
||||||
|
### 内容管理测试
|
||||||
|
1. 获取文章列表
|
||||||
|
2. 获取文章详情
|
||||||
|
3. 创建文章
|
||||||
|
4. 更新文章
|
||||||
|
5. 删除文章
|
||||||
|
6. 文章审核流程
|
||||||
|
|
||||||
|
### 互动功能测试
|
||||||
|
1. 发表评论
|
||||||
|
2. 评分
|
||||||
|
3. 点赞
|
||||||
|
4. 收藏
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [TESTING.md](../../TESTING.md)
|
||||||
|
- [test_api.py](../../test_api.py)
|
||||||
Reference in New Issue
Block a user