组件的封装

这个项目封装了哪些"组件层级"

  • **基础 UI 组件层**:`src/components/ui/*`(`button`/`dialog`/`select`/`popover`...),偏"设计系统",稳定、复用广。

  • **业务通用组件层**:`src/components/shared/*`(`ConfirmDialog`、`ChatInputShell`、`StableUserAvatar`...),跨页面复用。

  • **页面/模块组件层**

  • **Dashboard**:`DashboardPage`、`DashboardTopBar`、`DashboardWorkspaceListPanel`

  • **Workspace(核心)**:`ChatPanel/*`、`CanvasPanel/*`、`FileSystem/*`、`PreviewPanel/*`、`SkillBuilder/*`


我觉得最"牛"的:**资产槽位系统(Asset Slot System)+ `AssetSlotPanel`**

它不是单纯 UI 封装。它是**配置驱动的"输入协议"**。解决一个很真实的问题:不同模型/工具对素材输入的**角色、数量、类型**都不一样。

  • **你要的"插槽"在这里是业务插槽**:首帧、尾帧、参考图、参考视频、音频等。

  • **你要的"通信"在这里是跨组件状态协作**:工具切换、素材引用、上传、交换、校验、发送。

关键点 1:把"工具差异"收敛成配置

  • **配置文件**:`src/components/Toolbox/constants/assetSlots.ts`

  • **UI 组件**:`src/components/Workspace/ChatPanel/AssetSlotPanel.tsx`(统一渲染/上传/交换/删除)

  • **状态层**:`src/components/Workspace/stores/uiStore.ts`(槽位化引用 + 扁平引用同步)

关键点 2:封装后如何保证 API 兼容性(这里是最能讲的)

这个项目用的是**双轨兼容**:

  • **新 API(槽位化)**:`slottedReferences: Record<slotId, nodeId[]>`

  • **旧 API(扁平)**:`referencedNodeIds: nodeId[]`

所有增删改都保证两者同步。旧逻辑不用改,也能继续跑;新逻辑逐步迁移即可。

最关键的一段就是 `uiStore.addReference`:在 tool 模式下优先进槽位;否则进扁平数组。

```251:302:c:\Users\派大鑫\Desktop\新建文件夹\loop\src\components\Workspace\stores\uiStore.ts

// ---------- 引用 ----------

referencedNodeIds: [],

slottedReferences: {},

addReference(refId) {

set((s) => {

const { activeToolId, interactionMode } = useToolStore.getState();

// ... 解析 refType ...

if (interactionMode === 'tool' && activeToolId && refType) {

const config = getToolAssetSlotConfig(activeToolId);

if (config) {

for (const slot of config.slots) {

if (slot.acceptType === refType) {

const current = s.slottedReferences[slot.slotId] || [];

if (current.length < slot.max && !current.includes(refId)) {

if (!s.slottedReferences[slot.slotId]) {

s.slottedReferences[slot.slotId] = [];

}

s.slottedReferences[slot.slotId].push(refId);

s.referencedNodeIds = Object.values(

s.slottedReferences

).flat();

return;

}

}

}

return;

}

}

if (!s.referencedNodeIds.includes(refId)) {

s.referencedNodeIds.push(refId);

}

});

},

```

**这就是"封装组件后 API 兼容性"的硬核答案**:

  • **不删旧接口**,而是用"兼容层"桥接。

  • **状态单一事实来源**在 store 内部维护,外部调用者感知最小。


面试官怎么讲(建议用 60 秒版本)

  • **问题**:不同 AI 工具对素材输入要求不同,原来会写很多 if/else,工具一多就爆炸;切换工具还会丢素材或校验混乱。

  • **做法**:做了"资产槽位系统"。用配置描述每个工具的输入槽位(类型/最小/最大/可交换)。UI 用一个通用组件渲染。store 负责分配、交换、迁移、校验。

  • **兼容**:保留旧的扁平引用 `referencedNodeIds`,新增槽位化 `slottedReferences`,在 store 内同步,保证旧链路不改也能跑。

  • **收益**:新增工具的素材输入适配从"改 UI + 改校验 + 改拼参"收敛为"加一份配置";减少重复代码与回归风险。


你说的"通信 + 插槽"对吗?

  • **对,但要区分两种"插槽"**:

  • **业务插槽**:上面这个资产槽位(首帧/尾帧/参考图)。这是本项目的核心亮点。

  • **React 插槽**:`children`/render props 这种组件组合方式。这里当然也用,但面试价值没"业务插槽系统"高。

  • **通信方式(你可以直接说)**:Zustand store 做"模块间总线"。

  • `toolStore` 提供当前工具与模式

  • `uiStore` 管引用与槽位

  • `AssetSlotPanel` 只做交互与展示,不自己写规则


简历可直接写的关键词与表述

  • **关键词**:React、TypeScript、Zustand、配置驱动(Config-driven UI)、Backward Compatibility、状态同步、模块解耦、可扩展输入协议、复杂表单/素材引用系统

  • **表述句式**(不编数字版):

  • "设计并落地配置驱动的资产槽位系统,将不同模型的素材输入差异抽象为统一协议(slotId/acceptType/min/max),并实现工具切换时的自动迁移与校验。"

  • "通过双轨兼容(slottedReferences + referencedNodeIds)构建兼容层,保障旧调用方无感升级,降低重构风险。"

如果你愿意,我也可以把这套"60 秒版本"再压缩成面试口播稿(更像真实对话)。

相关推荐
香山上的麻雀10083 分钟前
由 Rust 开发的能大幅降低LLM token消耗的高性能 CLI 代理工具 rtk
开发语言·后端·rust
Fleshy数模3 分钟前
玩转 Python:多线程、装饰器、视觉检测与正则匹配实战
开发语言·python·视觉检测
薛定猫AI4 分钟前
【深度解析】Qwen 3.6 Max Preview:面向智能体编码、视觉推理与 Three.js 前端生成的能力拆解
开发语言·前端·javascript
❆VE❆6 分钟前
python实战(一):对接AI大模型并应用
开发语言·人工智能·python·ai
格林威11 分钟前
堡盟Baumer VCX系列工业相机供电与触发:网口(GigE) vs USB3.0
开发语言·人工智能·数码相机·计算机视觉·视觉检测·工业相机·高速相机
HashTang11 分钟前
我的开源项目帮独立开发者和 OPC 省掉的,不只是刷信息的时间
前端·ai编程·aiops
掘金者阿豪14 分钟前
Spring Data JPA 接入金仓数据库:少写代码,多干活
前端·后端
Moment18 分钟前
AI 时代,为什么全栈项目越来越离不开 Monorepo 和 TypeScript
前端·javascript·后端
wuyoula21 分钟前
尹之盾企业版网络验证
服务器·开发语言·javascript·c++·人工智能·ui·c#
Via_Neo26 分钟前
区间dp算法
开发语言·javascript·算法