人物系统
创建和管理小说角色,包括背景、性格、能力和角色关系
📖 系统概述
人物系统提供完整的角色管理能力,包括角色档案创建、性格能力设定、角色关系图谱等功能。系统还提供预设角色模板,帮助作者快速创建标准化角色。
🎯 功能特性
1. 角色档案
基本信息:
| 字段 | 说明 |
|---|---|
| 姓名 | 角色名称 |
| 年龄 | 角色年龄 |
| 性别 | 男/女/其他 |
| 外貌 | 外观描述 |
| 背景故事 | 角色的历史和经历 |
性格能力:
| 字段 | 说明 |
|---|---|
| MBTI | 性格类型(如 INTJ、ENFP) |
| 性格描述 | 详细的性格特点 |
| 特殊能力 | 角色的特殊技能或能力 |
| 优点 | 角色的优势 |
| 缺点 | 角色的弱点 |
2. 角色分类
角色可以分为两种类型:
| 类型 | 说明 | 使用场景 |
|---|---|---|
| 项目独有 | 属于特定项目的角色 | 只在该项目中使用 |
| 共享人设 | 不绑定项目的角色 | 可在多个项目中复用 |
Character
│
├── project_id = 1 → 项目独有角色(只属于项目1)
│
└── project_id = null → 共享人设(可分配给任意项目)3. 角色关系图谱
支持定义角色之间的关系:
┌─────────┐ 朋友 ┌─────────┐
│ 角色A │ ─────────────→ │ 角色B │
└─────────┘ └─────────┘
│ │
│ 师徒 │ 宿敌
↓ ↓
┌─────────┐ ┌─────────┐
│ 角色C │ │ 角色D │
└─────────┘ └─────────┘关系类型示例:
- 亲属:父母、兄弟、姐妹、子女
- 社会:朋友、同事、上司、下属
- 情感:恋人、前任、暧昧
- 对立:敌人、宿敌、竞争对手
- 特殊:师徒、主仆、盟友
4. 角色模板系统
预设常用角色模板,快速创建标准化角色:
| 模板类型 | 示例 |
|---|---|
| 主角模板 | 热血少年、冷酷王者、平凡觉醒者 |
| 配角模板 | 忠诚伙伴、神秘导师、喜剧担当 |
| 反派模板 | 终极BOSS、复仇者、堕落天使 |
| 特殊模板 | 人工智能、灵体、变形者 |
🗄️ 数据模型
Character 模型
python
class Character(models.Model):
id = fields.IntField(pk=True)
project_id = fields.IntField(null=True) # 所属项目(null=共享人设)
name = fields.CharField(max_length=100) # 姓名
age = fields.IntField(null=True) # 年龄
gender = fields.CharField(max_length=20, null=True) # 性别
appearance = fields.TextField(null=True) # 外貌描述
background = fields.TextField(null=True) # 背景故事
personality = fields.TextField(null=True) # 性格描述
mbti = fields.CharField(max_length=10, null=True) # MBTI类型
abilities = fields.TextField(null=True) # 特殊能力
strengths = fields.TextField(null=True) # 优点
weaknesses = fields.TextField(null=True) # 缺点
avatar = fields.CharField(max_length=500, null=True) # 头像URL
created_at = fields.DatetimeField(auto_now_add=True)
updated_at = fields.DatetimeField(auto_now=True)
class Meta:
table = "characters"CharacterRelation 模型
python
class CharacterRelation(models.Model):
id = fields.IntField(pk=True)
from_character_id = fields.IntField() # 关系发起角色
to_character_id = fields.IntField() # 关系目标角色
relation_type = fields.CharField(max_length=50) # 关系类型
description = fields.TextField(null=True) # 关系描述
is_bidirectional = fields.BooleanField(default=False) # 是否双向
created_at = fields.DatetimeField(auto_now_add=True)
class Meta:
table = "character_relations"CharacterTemplate 模型
python
class CharacterTemplate(models.Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=100) # 模板名称
category = fields.CharField(max_length=50) # 模板分类
description = fields.TextField(null=True) # 模板描述
template_data = fields.JSONField() # 模板数据
is_system = fields.BooleanField(default=False) # 是否系统模板
created_at = fields.DatetimeField(auto_now_add=True)
class Meta:
table = "character_templates"🔌 API 接口
基础路径
/api/character接口列表
| 方法 | 路径 | 说明 |
|---|---|---|
GET | / | 获取角色列表(支持筛选) |
POST | / | 创建角色 |
GET | /{character_id} | 获取角色详情 |
PUT | /{character_id} | 更新角色 |
DELETE | /{character_id} | 删除角色 |
GET | /project/{project_id} | 获取项目角色 |
POST | /from-template/{template_id} | 从模板创建角色 |
角色关系接口
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /relations/{character_id} | 获取角色的所有关系 |
POST | /relations | 创建角色关系 |
PUT | /relations/{relation_id} | 更新关系 |
DELETE | /relations/{relation_id} | 删除关系 |
GET | /relations/graph/{project_id} | 获取项目关系图谱数据 |
模板接口
| 方法 | 路径 | 说明 |
|---|---|---|
GET | /templates | 获取模板列表 |
GET | /templates/{template_id} | 获取模板详情 |
POST | /templates | 创建自定义模板 |
请求/响应示例
创建角色
请求:
json
POST /api/character
{
"project_id": 1,
"name": "李明",
"age": 25,
"gender": "male",
"appearance": "身高180cm,短发,戴眼镜",
"background": "普通大学生,意外获得超能力",
"personality": "外表冷静,内心热血",
"mbti": "INTJ",
"abilities": "时间暂停能力",
"strengths": "冷静分析,快速学习",
"weaknesses": "不善社交,过于自信"
}响应:
json
{
"id": 1,
"project_id": 1,
"name": "李明",
"age": 25,
"gender": "male",
...
"created_at": "2026-01-04T12:00:00Z"
}创建角色关系
请求:
json
POST /api/character/relations
{
"from_character_id": 1,
"to_character_id": 2,
"relation_type": "朋友",
"description": "大学同学,共同经历冒险后成为挚友",
"is_bidirectional": true
}获取关系图谱
请求:
GET /api/character/relations/graph/1响应:
json
{
"nodes": [
{"id": 1, "name": "李明", "avatar": "..."},
{"id": 2, "name": "王芳", "avatar": "..."}
],
"edges": [
{
"source": 1,
"target": 2,
"relation_type": "朋友",
"is_bidirectional": true
}
]
}🖥️ 用户交互
角色列表页面
布局结构:
┌─────────────────────────────────────────────────────┐
│ 角色管理 [新建角色] [从模板创建] [关系图谱] │
├─────────────────────────────────────────────────────┤
│ 筛选: [全部▼] [项目角色] [共享人设] 搜索: [____] │
├─────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 头像 │ │ 头像 │ │ 头像 │ │
│ │ 李明 │ │ 王芳 │ │ 张伟 │ │
│ │ INTJ │ │ ENFP │ │ ISTP │ │
│ │ 项目A │ │ 共享 │ │ 项目A │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────┘角色详情/编辑页面
布局结构:
┌─────────────────────────────────────────────────────┐
│ ← 返回 李明 [编辑] [删除] │
├──────────────────┬──────────────────────────────────┤
│ │ │
│ [头像] │ 基本信息 │
│ │ 姓名: 李明 │
│ INTJ / 25岁 │ 年龄: 25 │
│ │ 性别: 男 │
│ │ │
├──────────────────┴──────────────────────────────────┤
│ 外貌描述 │
│ 身高180cm,短发,戴眼镜... │
├─────────────────────────────────────────────────────┤
│ 背景故事 │
│ 普通大学生,意外获得超能力... │
├─────────────────────────────────────────────────────┤
│ 角色关系 │
│ ├── 王芳 (朋友) │
│ └── 张伟 (宿敌) │
└─────────────────────────────────────────────────────┘关系图谱页面
可视化展示:
- 使用力导向图展示角色关系
- 节点:角色(显示头像和名称)
- 边:关系(显示关系类型)
- 支持拖拽、缩放、点击查看详情
交互操作
| 操作 | 方式 | 说明 |
|---|---|---|
| 创建角色 | 点击按钮 | 打开创建表单 |
| 从模板创建 | 选择模板 | 使用模板数据预填表单 |
| 编辑角色 | 点击编辑 | 修改角色信息 |
| 添加关系 | 关系管理 | 选择目标角色和关系类型 |
| 查看图谱 | 点击按钮 | 进入可视化图谱页面 |
⚙️ 技术实现
前端
路径: src/features/character/frontend/
| 文件 | 说明 |
|---|---|
api.ts | API 调用封装 |
pages/AllCharactersPage.tsx | 角色列表页 |
pages/CharacterDetailPage.tsx | 角色详情页 |
pages/CharacterEditPage.tsx | 角色编辑页 |
pages/RelationGraphPage.tsx | 关系图谱页 |
components/CharacterCard.tsx | 角色卡片组件 |
components/RelationEditor.tsx | 关系编辑组件 |
stores/characterStore.ts | 角色状态管理 |
后端
路径: src/features/character/backend/
| 文件 | 说明 |
|---|---|
models.py | 数据模型定义 |
schemas.py | Pydantic 验证模型 |
router.py | FastAPI 路由 |
services/character_service.py | 角色业务逻辑 |
services/relation_service.py | 关系管理服务 |
services/template_service.py | 模板服务 |
关系图谱实现
使用 D3.js 或 react-force-graph 实现力导向图:
typescript
// RelationGraph.tsx
import { ForceGraph2D } from 'react-force-graph'
const RelationGraph = ({ data }) => {
return (
<ForceGraph2D
graphData={data}
nodeLabel="name"
linkLabel="relation_type"
nodeCanvasObject={(node, ctx) => {
// 绘制头像和名称
}}
onNodeClick={(node) => {
// 跳转到角色详情
}}
/>
)
}