refactor:重构角色关系数据驱动,relationships字段改为从关系表动态生成,组织成员同理
This commit is contained in:
+193
-18
@@ -31,6 +31,90 @@ router = APIRouter(prefix="/characters", tags=["角色管理"])
|
|||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def _build_relationships_summary(character_id: str, project_id: str, db: AsyncSession) -> str:
|
||||||
|
"""从 character_relationships 表构建角色关系摘要文本"""
|
||||||
|
from sqlalchemy import or_
|
||||||
|
|
||||||
|
# 查询该角色参与的所有关系
|
||||||
|
rels_result = await db.execute(
|
||||||
|
select(CharacterRelationship).where(
|
||||||
|
CharacterRelationship.project_id == project_id,
|
||||||
|
or_(
|
||||||
|
CharacterRelationship.character_from_id == character_id,
|
||||||
|
CharacterRelationship.character_to_id == character_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
rels = rels_result.scalars().all()
|
||||||
|
|
||||||
|
if not rels:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 收集所有相关角色ID
|
||||||
|
related_ids = set()
|
||||||
|
for r in rels:
|
||||||
|
related_ids.add(r.character_from_id)
|
||||||
|
related_ids.add(r.character_to_id)
|
||||||
|
related_ids.discard(character_id)
|
||||||
|
|
||||||
|
if not related_ids:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 批量查询角色名称
|
||||||
|
chars_result = await db.execute(
|
||||||
|
select(Character.id, Character.name).where(Character.id.in_(related_ids))
|
||||||
|
)
|
||||||
|
name_map = {row.id: row.name for row in chars_result}
|
||||||
|
|
||||||
|
# 构建摘要
|
||||||
|
parts = []
|
||||||
|
for r in rels:
|
||||||
|
if r.character_from_id == character_id:
|
||||||
|
target_name = name_map.get(r.character_to_id, "未知")
|
||||||
|
rel_name = r.relationship_name or "相关"
|
||||||
|
else:
|
||||||
|
target_name = name_map.get(r.character_from_id, "未知")
|
||||||
|
rel_name = r.relationship_name or "相关"
|
||||||
|
parts.append(f"与{target_name}:{rel_name}")
|
||||||
|
|
||||||
|
return ";".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
async def _build_org_members_summary(character_id: str, db: AsyncSession) -> str:
|
||||||
|
"""从 organization_members 表构建组织成员摘要文本"""
|
||||||
|
# 先查找该角色对应的 Organization 记录
|
||||||
|
org_result = await db.execute(
|
||||||
|
select(Organization).where(Organization.character_id == character_id)
|
||||||
|
)
|
||||||
|
org = org_result.scalar_one_or_none()
|
||||||
|
if not org:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 查询该组织的所有成员
|
||||||
|
members_result = await db.execute(
|
||||||
|
select(OrganizationMember).where(OrganizationMember.organization_id == org.id)
|
||||||
|
)
|
||||||
|
members = members_result.scalars().all()
|
||||||
|
if not members:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 批量查询成员角色名称
|
||||||
|
member_char_ids = [m.character_id for m in members]
|
||||||
|
chars_result = await db.execute(
|
||||||
|
select(Character.id, Character.name).where(Character.id.in_(member_char_ids))
|
||||||
|
)
|
||||||
|
name_map = {row.id: row.name for row in chars_result}
|
||||||
|
|
||||||
|
# 构建摘要
|
||||||
|
parts = []
|
||||||
|
for m in members:
|
||||||
|
name = name_map.get(m.character_id, "未知")
|
||||||
|
position = m.position or "成员"
|
||||||
|
parts.append(f"{name}({position})")
|
||||||
|
|
||||||
|
return "、".join(parts)
|
||||||
|
|
||||||
|
|
||||||
@router.get("", response_model=CharacterListResponse, summary="获取角色列表")
|
@router.get("", response_model=CharacterListResponse, summary="获取角色列表")
|
||||||
async def get_characters(
|
async def get_characters(
|
||||||
project_id: str,
|
project_id: str,
|
||||||
@@ -56,9 +140,12 @@ async def get_characters(
|
|||||||
)
|
)
|
||||||
characters = result.scalars().all()
|
characters = result.scalars().all()
|
||||||
|
|
||||||
# 为组织类型的角色填充Organization表的额外字段,并添加职业信息
|
# 为角色填充关系摘要、组织额外字段、职业信息
|
||||||
enriched_characters = []
|
enriched_characters = []
|
||||||
for char in characters:
|
for char in characters:
|
||||||
|
# 从 character_relationships 表动态生成关系摘要
|
||||||
|
rel_summary = await _build_relationships_summary(char.id, project_id, db)
|
||||||
|
|
||||||
char_dict = {
|
char_dict = {
|
||||||
"id": char.id,
|
"id": char.id,
|
||||||
"project_id": char.project_id,
|
"project_id": char.project_id,
|
||||||
@@ -70,10 +157,10 @@ async def get_characters(
|
|||||||
"personality": char.personality,
|
"personality": char.personality,
|
||||||
"background": char.background,
|
"background": char.background,
|
||||||
"appearance": char.appearance,
|
"appearance": char.appearance,
|
||||||
"relationships": char.relationships,
|
"relationships": rel_summary,
|
||||||
"organization_type": char.organization_type,
|
"organization_type": char.organization_type,
|
||||||
"organization_purpose": char.organization_purpose,
|
"organization_purpose": char.organization_purpose,
|
||||||
"organization_members": char.organization_members,
|
"organization_members": await _build_org_members_summary(char.id, db) if char.is_organization else "",
|
||||||
"traits": char.traits,
|
"traits": char.traits,
|
||||||
"avatar_url": char.avatar_url,
|
"avatar_url": char.avatar_url,
|
||||||
"created_at": char.created_at,
|
"created_at": char.created_at,
|
||||||
@@ -130,9 +217,12 @@ async def get_project_characters(
|
|||||||
)
|
)
|
||||||
characters = result.scalars().all()
|
characters = result.scalars().all()
|
||||||
|
|
||||||
# 为组织类型的角色填充Organization表的额外字段,并添加职业信息
|
# 为角色填充关系摘要、组织额外字段、职业信息
|
||||||
enriched_characters = []
|
enriched_characters = []
|
||||||
for char in characters:
|
for char in characters:
|
||||||
|
# 从 character_relationships 表动态生成关系摘要
|
||||||
|
rel_summary = await _build_relationships_summary(char.id, project_id, db)
|
||||||
|
|
||||||
char_dict = {
|
char_dict = {
|
||||||
"id": char.id,
|
"id": char.id,
|
||||||
"project_id": char.project_id,
|
"project_id": char.project_id,
|
||||||
@@ -144,10 +234,10 @@ async def get_project_characters(
|
|||||||
"personality": char.personality,
|
"personality": char.personality,
|
||||||
"background": char.background,
|
"background": char.background,
|
||||||
"appearance": char.appearance,
|
"appearance": char.appearance,
|
||||||
"relationships": char.relationships,
|
"relationships": rel_summary,
|
||||||
"organization_type": char.organization_type,
|
"organization_type": char.organization_type,
|
||||||
"organization_purpose": char.organization_purpose,
|
"organization_purpose": char.organization_purpose,
|
||||||
"organization_members": char.organization_members,
|
"organization_members": await _build_org_members_summary(char.id, db) if char.is_organization else "",
|
||||||
"traits": char.traits,
|
"traits": char.traits,
|
||||||
"avatar_url": char.avatar_url,
|
"avatar_url": char.avatar_url,
|
||||||
"created_at": char.created_at,
|
"created_at": char.created_at,
|
||||||
@@ -198,7 +288,51 @@ async def get_character(
|
|||||||
user_id = getattr(request.state, 'user_id', None)
|
user_id = getattr(request.state, 'user_id', None)
|
||||||
await verify_project_access(character.project_id, user_id, db)
|
await verify_project_access(character.project_id, user_id, db)
|
||||||
|
|
||||||
return character
|
# 从 character_relationships 表动态生成关系摘要
|
||||||
|
rel_summary = await _build_relationships_summary(character.id, character.project_id, db)
|
||||||
|
|
||||||
|
char_dict = {
|
||||||
|
"id": character.id,
|
||||||
|
"project_id": character.project_id,
|
||||||
|
"name": character.name,
|
||||||
|
"age": character.age,
|
||||||
|
"gender": character.gender,
|
||||||
|
"is_organization": character.is_organization,
|
||||||
|
"role_type": character.role_type,
|
||||||
|
"personality": character.personality,
|
||||||
|
"background": character.background,
|
||||||
|
"appearance": character.appearance,
|
||||||
|
"relationships": rel_summary,
|
||||||
|
"organization_type": character.organization_type,
|
||||||
|
"organization_purpose": character.organization_purpose,
|
||||||
|
"organization_members": await _build_org_members_summary(character.id, db) if character.is_organization else "",
|
||||||
|
"traits": character.traits,
|
||||||
|
"avatar_url": character.avatar_url,
|
||||||
|
"created_at": character.created_at,
|
||||||
|
"updated_at": character.updated_at,
|
||||||
|
"power_level": None,
|
||||||
|
"location": None,
|
||||||
|
"motto": None,
|
||||||
|
"color": None,
|
||||||
|
"main_career_id": character.main_career_id,
|
||||||
|
"main_career_stage": character.main_career_stage,
|
||||||
|
"sub_careers": json.loads(character.sub_careers) if character.sub_careers else None
|
||||||
|
}
|
||||||
|
|
||||||
|
if character.is_organization:
|
||||||
|
org_result = await db.execute(
|
||||||
|
select(Organization).where(Organization.character_id == character.id)
|
||||||
|
)
|
||||||
|
org = org_result.scalar_one_or_none()
|
||||||
|
if org:
|
||||||
|
char_dict.update({
|
||||||
|
"power_level": org.power_level,
|
||||||
|
"location": org.location,
|
||||||
|
"motto": org.motto,
|
||||||
|
"color": org.color
|
||||||
|
})
|
||||||
|
|
||||||
|
return char_dict
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{character_id}", response_model=CharacterResponse, summary="更新角色")
|
@router.put("/{character_id}", response_model=CharacterResponse, summary="更新角色")
|
||||||
@@ -372,7 +506,9 @@ async def update_character(
|
|||||||
character.sub_careers = sub_careers_json if isinstance(sub_careers_json, str) else json.dumps(sub_careers_data, ensure_ascii=False)
|
character.sub_careers = sub_careers_json if isinstance(sub_careers_json, str) else json.dumps(sub_careers_data, ensure_ascii=False)
|
||||||
logger.info(f"更新副职业信息:{character.name}")
|
logger.info(f"更新副职业信息:{character.name}")
|
||||||
|
|
||||||
# 更新 Character 表字段
|
# 更新 Character 表字段(排除 relationships 和 organization_members,这些字段现在由结构化表驱动)
|
||||||
|
update_data.pop('relationships', None)
|
||||||
|
update_data.pop('organization_members', None)
|
||||||
for field, value in update_data.items():
|
for field, value in update_data.items():
|
||||||
setattr(character, field, value)
|
setattr(character, field, value)
|
||||||
|
|
||||||
@@ -403,7 +539,8 @@ async def update_character(
|
|||||||
|
|
||||||
logger.info(f"更新角色/组织成功:{character.name} (ID: {character_id})")
|
logger.info(f"更新角色/组织成功:{character.name} (ID: {character_id})")
|
||||||
|
|
||||||
# 构建响应,确保sub_careers是list类型
|
# 构建响应,从关系表动态生成 relationships
|
||||||
|
rel_summary = await _build_relationships_summary(character_id, character.project_id, db)
|
||||||
response_data = {
|
response_data = {
|
||||||
"id": character.id,
|
"id": character.id,
|
||||||
"project_id": character.project_id,
|
"project_id": character.project_id,
|
||||||
@@ -415,10 +552,10 @@ async def update_character(
|
|||||||
"personality": character.personality,
|
"personality": character.personality,
|
||||||
"background": character.background,
|
"background": character.background,
|
||||||
"appearance": character.appearance,
|
"appearance": character.appearance,
|
||||||
"relationships": character.relationships,
|
"relationships": rel_summary,
|
||||||
"organization_type": character.organization_type,
|
"organization_type": character.organization_type,
|
||||||
"organization_purpose": character.organization_purpose,
|
"organization_purpose": character.organization_purpose,
|
||||||
"organization_members": character.organization_members,
|
"organization_members": await _build_org_members_summary(character.id, db) if character.is_organization else "",
|
||||||
"traits": character.traits,
|
"traits": character.traits,
|
||||||
"avatar_url": character.avatar_url,
|
"avatar_url": character.avatar_url,
|
||||||
"created_at": character.created_at,
|
"created_at": character.created_at,
|
||||||
@@ -510,7 +647,7 @@ async def create_character(
|
|||||||
await verify_project_access(character_data.project_id, user_id, db)
|
await verify_project_access(character_data.project_id, user_id, db)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 创建角色
|
# 创建角色(不再写入 relationships 文本字段,关系统一由 character_relationships 表管理)
|
||||||
character = Character(
|
character = Character(
|
||||||
project_id=character_data.project_id,
|
project_id=character_data.project_id,
|
||||||
name=character_data.name,
|
name=character_data.name,
|
||||||
@@ -521,10 +658,8 @@ async def create_character(
|
|||||||
personality=character_data.personality,
|
personality=character_data.personality,
|
||||||
background=character_data.background,
|
background=character_data.background,
|
||||||
appearance=character_data.appearance,
|
appearance=character_data.appearance,
|
||||||
relationships=character_data.relationships,
|
|
||||||
organization_type=character_data.organization_type,
|
organization_type=character_data.organization_type,
|
||||||
organization_purpose=character_data.organization_purpose,
|
organization_purpose=character_data.organization_purpose,
|
||||||
organization_members=character_data.organization_members,
|
|
||||||
traits=character_data.traits,
|
traits=character_data.traits,
|
||||||
avatar_url=character_data.avatar_url,
|
avatar_url=character_data.avatar_url,
|
||||||
main_career_id=character_data.main_career_id,
|
main_career_id=character_data.main_career_id,
|
||||||
@@ -623,7 +758,49 @@ async def create_character(
|
|||||||
|
|
||||||
logger.info(f"🎉 成功手动创建角色/组织: {character.name}")
|
logger.info(f"🎉 成功手动创建角色/组织: {character.name}")
|
||||||
|
|
||||||
return character
|
# 构建响应(relationships 从关系表动态生成)
|
||||||
|
char_dict = {
|
||||||
|
"id": character.id,
|
||||||
|
"project_id": character.project_id,
|
||||||
|
"name": character.name,
|
||||||
|
"age": character.age,
|
||||||
|
"gender": character.gender,
|
||||||
|
"is_organization": character.is_organization,
|
||||||
|
"role_type": character.role_type,
|
||||||
|
"personality": character.personality,
|
||||||
|
"background": character.background,
|
||||||
|
"appearance": character.appearance,
|
||||||
|
"relationships": "",
|
||||||
|
"organization_type": character.organization_type,
|
||||||
|
"organization_purpose": character.organization_purpose,
|
||||||
|
"organization_members": await _build_org_members_summary(character.id, db) if character.is_organization else "",
|
||||||
|
"traits": character.traits,
|
||||||
|
"avatar_url": character.avatar_url,
|
||||||
|
"created_at": character.created_at,
|
||||||
|
"updated_at": character.updated_at,
|
||||||
|
"power_level": None,
|
||||||
|
"location": None,
|
||||||
|
"motto": None,
|
||||||
|
"color": None,
|
||||||
|
"main_career_id": character.main_career_id,
|
||||||
|
"main_career_stage": character.main_career_stage,
|
||||||
|
"sub_careers": json.loads(character.sub_careers) if character.sub_careers else None
|
||||||
|
}
|
||||||
|
|
||||||
|
if character.is_organization:
|
||||||
|
org_result = await db.execute(
|
||||||
|
select(Organization).where(Organization.character_id == character.id)
|
||||||
|
)
|
||||||
|
org = org_result.scalar_one_or_none()
|
||||||
|
if org:
|
||||||
|
char_dict.update({
|
||||||
|
"power_level": org.power_level,
|
||||||
|
"location": org.location,
|
||||||
|
"motto": org.motto,
|
||||||
|
"color": org.color
|
||||||
|
})
|
||||||
|
|
||||||
|
return char_dict
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"手动创建角色失败: {str(e)}")
|
logger.error(f"手动创建角色失败: {str(e)}")
|
||||||
@@ -878,7 +1055,7 @@ async def generate_character_stream(
|
|||||||
else:
|
else:
|
||||||
logger.warning(f"⚠️ AI返回的副职业名称未找到: {career_name}")
|
logger.warning(f"⚠️ AI返回的副职业名称未找到: {career_name}")
|
||||||
|
|
||||||
# 创建角色
|
# 创建角色(不再写入 relationships 文本字段,关系统一由 character_relationships 表管理)
|
||||||
character = Character(
|
character = Character(
|
||||||
project_id=request.project_id,
|
project_id=request.project_id,
|
||||||
name=character_data.get("name", request.name or "未命名角色"),
|
name=character_data.get("name", request.name or "未命名角色"),
|
||||||
@@ -889,10 +1066,8 @@ async def generate_character_stream(
|
|||||||
personality=character_data.get("personality", ""),
|
personality=character_data.get("personality", ""),
|
||||||
background=character_data.get("background", ""),
|
background=character_data.get("background", ""),
|
||||||
appearance=character_data.get("appearance", ""),
|
appearance=character_data.get("appearance", ""),
|
||||||
relationships=character_data.get("relationships_text", character_data.get("relationships", "")),
|
|
||||||
organization_type=character_data.get("organization_type") if is_organization else None,
|
organization_type=character_data.get("organization_type") if is_organization else None,
|
||||||
organization_purpose=character_data.get("organization_purpose") if is_organization else None,
|
organization_purpose=character_data.get("organization_purpose") if is_organization else None,
|
||||||
organization_members=json.dumps(character_data.get("organization_members", []), ensure_ascii=False) if is_organization else None,
|
|
||||||
traits=traits_json,
|
traits=traits_json,
|
||||||
main_career_id=main_career_id,
|
main_career_id=main_career_id,
|
||||||
main_career_stage=main_career_stage if main_career_id else None,
|
main_career_stage=main_career_stage if main_career_id else None,
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ interface CharacterFormValues {
|
|||||||
role_type?: string;
|
role_type?: string;
|
||||||
personality?: string;
|
personality?: string;
|
||||||
appearance?: string;
|
appearance?: string;
|
||||||
relationships?: string;
|
|
||||||
background?: string;
|
background?: string;
|
||||||
main_career_id?: string;
|
main_career_id?: string;
|
||||||
main_career_stage?: number;
|
main_career_stage?: number;
|
||||||
@@ -60,7 +59,6 @@ interface CharacterCreateData {
|
|||||||
role_type?: string;
|
role_type?: string;
|
||||||
personality?: string;
|
personality?: string;
|
||||||
appearance?: string;
|
appearance?: string;
|
||||||
relationships?: string;
|
|
||||||
background?: string;
|
background?: string;
|
||||||
main_career_id?: string;
|
main_career_id?: string;
|
||||||
main_career_stage?: number;
|
main_career_stage?: number;
|
||||||
@@ -82,7 +80,6 @@ interface CharacterUpdateData {
|
|||||||
role_type?: string;
|
role_type?: string;
|
||||||
personality?: string;
|
personality?: string;
|
||||||
appearance?: string;
|
appearance?: string;
|
||||||
relationships?: string;
|
|
||||||
background?: string;
|
background?: string;
|
||||||
main_career_id?: string;
|
main_career_id?: string;
|
||||||
main_career_stage?: number;
|
main_career_stage?: number;
|
||||||
@@ -271,7 +268,6 @@ export default function Characters() {
|
|||||||
createData.role_type = values.role_type || 'supporting';
|
createData.role_type = values.role_type || 'supporting';
|
||||||
createData.personality = values.personality;
|
createData.personality = values.personality;
|
||||||
createData.appearance = values.appearance;
|
createData.appearance = values.appearance;
|
||||||
createData.relationships = values.relationships;
|
|
||||||
createData.background = values.background;
|
createData.background = values.background;
|
||||||
|
|
||||||
// 职业字段
|
// 职业字段
|
||||||
@@ -288,7 +284,6 @@ export default function Characters() {
|
|||||||
// 组织字段
|
// 组织字段
|
||||||
createData.organization_type = values.organization_type;
|
createData.organization_type = values.organization_type;
|
||||||
createData.organization_purpose = values.organization_purpose;
|
createData.organization_purpose = values.organization_purpose;
|
||||||
createData.organization_members = values.organization_members;
|
|
||||||
createData.background = values.background;
|
createData.background = values.background;
|
||||||
createData.power_level = values.power_level;
|
createData.power_level = values.power_level;
|
||||||
createData.location = values.location;
|
createData.location = values.location;
|
||||||
@@ -1018,10 +1013,17 @@ export default function Characters() {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{/* 第三行:人际关系 */}
|
{/* 人际关系(只读,由关系管理页面维护) */}
|
||||||
<Form.Item label="人际关系" name="relationships" style={{ marginBottom: 12 }}>
|
{editingCharacter?.relationships && (
|
||||||
<Input placeholder="描述角色与其他角色的关系..." />
|
<Form.Item label="人际关系(由关系管理维护)" style={{ marginBottom: 12 }}>
|
||||||
</Form.Item>
|
<Input.TextArea
|
||||||
|
value={editingCharacter.relationships}
|
||||||
|
readOnly
|
||||||
|
autoSize={{ minRows: 1, maxRows: 3 }}
|
||||||
|
style={{ backgroundColor: '#f5f5f5', cursor: 'default' }}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 第四行:角色背景 */}
|
{/* 第四行:角色背景 */}
|
||||||
<Form.Item label="角色背景" name="background" style={{ marginBottom: 12 }}>
|
<Form.Item label="角色背景" name="background" style={{ marginBottom: 12 }}>
|
||||||
@@ -1182,19 +1184,32 @@ export default function Characters() {
|
|||||||
<Input placeholder="描述组织的宗旨和目标..." />
|
<Input placeholder="描述组织的宗旨和目标..." />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
{/* 第三行:主要成员、所在地、代表颜色 */}
|
{/* 第三行:主要成员(只读展示) */}
|
||||||
|
<Form.Item
|
||||||
|
label="主要成员"
|
||||||
|
name="organization_members"
|
||||||
|
style={{ marginBottom: 4 }}
|
||||||
|
tooltip="成员信息由组织管理模块维护,此处仅展示"
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
disabled
|
||||||
|
autoSize={{ minRows: 1, maxRows: 4 }}
|
||||||
|
placeholder="暂无成员,请在组织管理中添加"
|
||||||
|
style={{ color: '#333', backgroundColor: '#fafafa' }}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<div style={{ marginBottom: 12, fontSize: 12, color: '#8c8c8c' }}>
|
||||||
|
💡 请前往「组织管理」页面添加或管理组织成员
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 第四行:所在地、代表颜色 */}
|
||||||
<Row gutter={12}>
|
<Row gutter={12}>
|
||||||
<Col span={10}>
|
<Col span={12}>
|
||||||
<Form.Item label="主要成员" name="organization_members" style={{ marginBottom: 12 }}>
|
|
||||||
<Input placeholder="如:张三、李四" />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={8}>
|
|
||||||
<Form.Item label="所在地" name="location" style={{ marginBottom: 12 }}>
|
<Form.Item label="所在地" name="location" style={{ marginBottom: 12 }}>
|
||||||
<Input placeholder="总部位置" />
|
<Input placeholder="总部位置" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={12}>
|
||||||
<Form.Item label="代表颜色" name="color" style={{ marginBottom: 12 }}>
|
<Form.Item label="代表颜色" name="color" style={{ marginBottom: 12 }}>
|
||||||
<Input placeholder="如:金色" />
|
<Input placeholder="如:金色" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -1289,12 +1304,7 @@ export default function Characters() {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{/* 第三行:人际关系 */}
|
{/* 第三行:角色背景 */}
|
||||||
<Form.Item label="人际关系" name="relationships" style={{ marginBottom: 12 }}>
|
|
||||||
<Input placeholder="描述角色与其他角色的关系..." />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
{/* 第四行:角色背景 */}
|
|
||||||
<Form.Item label="角色背景" name="background" style={{ marginBottom: 12 }}>
|
<Form.Item label="角色背景" name="background" style={{ marginBottom: 12 }}>
|
||||||
<TextArea rows={2} placeholder="描述角色的背景故事..." />
|
<TextArea rows={2} placeholder="描述角色的背景故事..." />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -1454,19 +1464,14 @@ export default function Characters() {
|
|||||||
<Input placeholder="描述组织的宗旨和目标..." />
|
<Input placeholder="描述组织的宗旨和目标..." />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
{/* 第三行:主要成员、所在地、代表颜色 */}
|
{/* 第三行:所在地、代表颜色 */}
|
||||||
<Row gutter={12}>
|
<Row gutter={12}>
|
||||||
<Col span={10}>
|
<Col span={12}>
|
||||||
<Form.Item label="主要成员" name="organization_members" style={{ marginBottom: 12 }}>
|
|
||||||
<Input placeholder="如:张三、李四" />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
|
||||||
<Col span={8}>
|
|
||||||
<Form.Item label="所在地" name="location" style={{ marginBottom: 12 }}>
|
<Form.Item label="所在地" name="location" style={{ marginBottom: 12 }}>
|
||||||
<Input placeholder="总部位置" />
|
<Input placeholder="总部位置" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={12}>
|
||||||
<Form.Item label="代表颜色" name="color" style={{ marginBottom: 12 }}>
|
<Form.Item label="代表颜色" name="color" style={{ marginBottom: 12 }}>
|
||||||
<Input placeholder="如:金色" />
|
<Input placeholder="如:金色" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
Reference in New Issue
Block a user