diff --git a/app/src/components/records/RecordDetailDialog.tsx b/app/src/components/records/RecordDetailDialog.tsx
index f92ba1a..efadab4 100644
--- a/app/src/components/records/RecordDetailDialog.tsx
+++ b/app/src/components/records/RecordDetailDialog.tsx
@@ -131,7 +131,7 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
- {/* 徽章行 */}
+ {/* 徽章行:类型 · 级别 · 奖等 · 角色 · 状态 · 名次 */}
{d.type_name}
@@ -142,15 +142,69 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
{d.rank != null && 第 {d.rank} 名}
- {/* 基本信息网格 */}
-
-
-
- {d.group_id && }
- {d.parent_id != null && }
-
-
-
+ {/* 事项要素:时间/组织方 + 类型专属字段(按模板定义顺序 = 重要性顺序) */}
+
+
+
+
+ {fields.map(f => )}
+
+
+
+ {/* 附件佐证 */}
+ {(d.attachments?.length ?? 0) > 0 && (
+
+ {atts.length ? (
+
+ {images.length > 0 && (
+
+ {images.map(a => (
+
+ ))}
+
+ )}
+ {docs.length > 0 && (
+
+ {docs.map(a => (
+
+ ))}
+
+ )}
+
点击图片 / 文件可在线预览(图片 · PDF · 文本 · Word · Excel · 音视频)
+
+ ) : (
+ 暂无佐证附件
+ )}
+
+ )}
{d.description && (
@@ -164,14 +218,6 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
)}
- {fields.length > 0 && (
-
-
- {fields.map(f => )}
-
-
- )}
-
{(d.metrics && Object.keys(d.metrics).length > 0) && (
@@ -197,57 +243,13 @@ export function RecordDetailDialog({ open, onClose, footprintId, onEdit }: {
)}
-
- {atts.length ? (
-
- {images.length > 0 && (
-
- {images.map(a => (
-
- ))}
-
- )}
- {docs.length > 0 && (
-
- {docs.map(a => (
-
- ))}
-
- )}
-
点击图片 / 文件可在线预览(图片 · PDF · 文本 · Word · Excel · 音视频)
-
- ) : (
- 暂无佐证附件
- )}
-
+ {/* 系统信息(最末位) */}
+
+ 创建于 {fmtDateTime(d.created_at)}
+ 更新于 {fmtDateTime(d.updated_at)}
+ {d.group_id && 事件组 {d.group_id}}
+ {d.parent_id != null && 上级 #{d.parent_id}}
+
)}
diff --git a/app/src/components/records/RecordEditorDialog.tsx b/app/src/components/records/RecordEditorDialog.tsx
index a56bb00..40ec1b6 100644
--- a/app/src/components/records/RecordEditorDialog.tsx
+++ b/app/src/components/records/RecordEditorDialog.tsx
@@ -11,6 +11,7 @@ import { Button, Dialog, Field, Input, Select, Textarea, useToast } from '@/comp
import { TagInput } from '@/components/common/TagInput';
import { DynamicForm, type TaxonomyOptionsMap } from '@/components/common/DynamicForm';
import { AttachmentPicker, fileToPending, type PendingAtt } from '@/components/common/AttachmentPicker';
+import { getTypeProfile } from '@/lib/typeProfiles';
interface FormState {
type_id: number | null;
@@ -83,6 +84,7 @@ export function RecordEditorDialog({ open, onClose, footprintId, onSaved }: {
() => typesQ.data?.items.find(t => t.id === form.type_id),
[typesQ.data, form.type_id]
);
+ const profile = getTypeProfile(selectedType?.name);
const parentQ = useQuery({
queryKey: ['parent-candidates', form.type_id],
@@ -182,6 +184,38 @@ export function RecordEditorDialog({ open, onClose, footprintId, onSaved }: {
onSuccess: () => void qc.invalidateQueries({ queryKey: ['attachments', footprintId] })
});
+ const renderCoreField = (key: string) => {
+ if (key === 'organizer') return (
+
+ set('organizer', e.target.value)} placeholder="如:中国工业与应用数学学会" />
+
+ );
+ if (key === 'role') return (
+
+
+ );
+ if (key === 'level') return (
+
+
+ );
+ if (key === 'award_grade') return (
+
+
+ );
+ if (key === 'rank') return (
+
+ set('rank', e.target.value)} placeholder="如 2" />
+
+ );
+ return null;
+ };
+
return (