cosmo/CELESTIAL_BODY_FIX_SUMMARY.md

4.8 KiB
Raw Blame History

天体管理功能修复总结

日期: 2025-12-10 状态: 代码修复完成,待用户重启后端验证


修复的三个问题

1. 生成轨道按钮显示逻辑

问题: 生成轨道按钮只在行星/矮行星显示,其他类型不显示

修复:

  • 所有天体类型都显示"生成轨道"按钮
  • 非行星/矮行星的按钮设置为 disabled={true} 置灰
  • 不同的 Tooltip 提示:
    • 可生成:"生成轨道"
    • 不可生成:"仅行星和矮行星可生成轨道"

代码位置: frontend/src/pages/admin/CelestialBodies.tsx:490-516

customActions={(record) => {
  const canGenerateOrbit = ['planet', 'dwarf_planet'].includes(record.type);
  return (
    <Popconfirm ...>
      <Tooltip title={canGenerateOrbit ? "生成轨道" : "仅行星和矮行星可生成轨道"}>
        <Button disabled={!canGenerateOrbit}>生成轨道</Button>
      </Tooltip>
    </Popconfirm>
  );
}}

2. 生成轨道确认弹窗

问题: 点击生成轨道直接执行,没有确认提示

修复:

  • 使用 Popconfirm 组件包裹按钮
  • 确认标题:"确认生成轨道"
  • 确认描述:显示天体中文名或英文名
  • 提示信息:"此操作可能需要一些时间"

代码位置: frontend/src/pages/admin/CelestialBodies.tsx:495-514


3. 轨道配置数据加载问题

问题: 编辑天体时,轨道周期和颜色字段为空

根本原因:

  1. 后端 API (/celestial/list) 没有返回 extra_data 字段
  2. 前端 TypeScript 接口缺少 extra_data 定义

修复方案:

后端修复 (backend/app/api/celestial_body.py:232)

bodies_list.append({
    "id": body.id,
    "name": body.name,
    # ... 其他字段 ...
    "extra_data": body.extra_data,  # ✅ 添加此行
    "resources": resources_by_type,
})

前端修复

1. 添加 TypeScript 接口定义 (CelestialBodies.tsx:16-39)

interface CelestialBody {
  // ... 其他字段 ...
  extra_data?: {
    orbit_period_days?: number;
    orbit_color?: string;
    [key: string]: any;
  };
}

2. 处理 extra_data 数据 (CelestialBodies.tsx:210-235)

const handleEdit = (record: CelestialBody) => {
  // 解析 extra_data可能是字符串
  let extraData = record.extra_data;
  if (typeof extraData === 'string') {
    try {
      extraData = JSON.parse(extraData);
    } catch (e) {
      console.error('Failed to parse extra_data:', e);
      extraData = {};
    }
  }

  // 设置表单值
  form.setFieldsValue({
    ...record,
    extra_data: extraData || {},
  });

  setIsModalOpen(true);
};

额外修复

DataTable 组件增强

文件: frontend/src/components/admin/DataTable.tsx

新增功能: 支持自定义操作按钮

interface DataTableProps<T> {
  // ... 其他 props ...
  customActions?: (record: T) => ReactNode;  // ✅ 新增
}

使用方式:

<DataTable
  customActions={(record) => (
    <Button>自定义操作</Button>
  )}
/>

数据库验证

已验证阋神星的数据在数据库中正确存储:

SELECT id, name_zh, extra_data FROM celestial_bodies WHERE id = '136199';

结果:

{
  "id": "136199",
  "name_zh": "阋神星",
  "extra_data": {
    "orbit_color": "#E0E0E0",
    "orbit_period_days": 203500.0
  }
}

待用户操作

1. 重启后端服务器

后端代码已修改,需要重启以应用更改:

# 停止后端
lsof -ti:8000 | xargs kill

# 启动后端
cd /Users/jiliu/WorkSpace/cosmo/backend
PYTHONPATH=/Users/jiliu/WorkSpace/cosmo/backend \
  uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

2. 刷新前端页面

重启后端后,刷新浏览器页面以获取最新数据。

3. 验证功能

  • 编辑阋神星,确认轨道周期显示 203500
  • 确认轨道颜色显示 #E0E0E0
  • 点击"生成轨道"按钮,确认弹出确认框
  • 查看恒星、卫星等类型,确认"生成轨道"按钮置灰

修改文件列表

后端

  • backend/app/api/celestial_body.py - 添加 extra_data 到 API 响应

前端

  • frontend/src/pages/admin/CelestialBodies.tsx - 添加接口定义和数据处理
  • frontend/src/components/admin/DataTable.tsx - 支持自定义操作按钮

技术细节

为什么需要处理字符串类型?

PostgreSQL 的 JSONB 字段在某些情况下可能被序列化为字符串,特别是在使用不同的 ORM 或序列化库时。代码添加了兼容性处理:

if (typeof extraData === 'string') {
  extraData = JSON.parse(extraData);
}

这确保了无论后端返回对象还是 JSON 字符串,前端都能正确处理。


完成状态: 代码修复完成,等待后端重启验证