智能灯箱插件示例教程
本文以酷大师官方提供的”智能灯箱“插件为例,说明如何利用酷大师插件官方定义消息,向酷大师方案中插入插件自定义的3d模型。
一、插件前端
下面分三个用户流程,分别解释插件和酷大师进行消息发送/响应的流程,以及示例代码。包括:
- 插件3d模型插入到酷大师画布
- 更新画布中已插入的插件3d模型(调整参数)
- 取消插入插件3d模型
流程1:插件中的模型如何插入到酷大师画布中

注意:下面的代码示例都会用到一个自定义的postMessage公共方法,它是对window.postMessage的封装。插件开发者应直接使用window.postMessage,或完成自己的封装。
消息发送的格式,需以酷大师插件官方定义消息中定义的格式为准。
postMessage 封装示例代码: postMessage公共方法
export function postMessage<CMD extends keyof ToMainMessageTypes>(data: {
    cmd: CMD
} & ToMainMessageTypes[CMD]) {
    const { cmd, modelIndex } = data;
 
    if (!_config.AppKey || !_config.ModelType) {
        throw new Error('Config not provided');
    }
 
    const params: any = {
        resource: modelIndex,
        type: _config.ModelType,
        appKey: _config.AppKey
    };
    switch (cmd) {
        case 'insert_model':
            params.bbox = (data as ToMainMessageTypes['insert_model'] & {
                cmd: CMD
            }).bbox;
            break;
        case 'update_model':
            params.bbox = (data as ToMainMessageTypes['update_model']&{
                cmd: CMD
            }).bbox;
            break;
        case 'cancel_insert':
            break;
    }
    parent.postMessage({
        cmd,
        params
    }, '*');
}
插入外部模型示例代码: 插件代码示例
insertModel(): any {
                // 获取拖拽的智能灯箱模型模板
                const { draggedItem } = (yield ModelListManager.state) as ModelListState;
                if (draggedItem && draggedItem.id) {
                    yield put(ModelListManager.actions.setDraggedItem({}));
                    const { id } = draggedItem;
                    // 请求插件后端创建一个智能灯箱模型实例,获取其modelIndex
                    const { resData, success } = yield call(request({
                        url: '/geom/api/model/3dtext/modelindex/create',
                        method: 'post',
                        headers: {
                            Accept: '*/*',
                        },
                    }), {
                        familySymbolId: id,
                        parameters: {}
                    });
                    if (success) {
                        cacheModelInfo = {
                            modelIndex: resData,
                            familyId: id
                        };
                        yield put(ModelListManager.mergeStateAction({ currentModelIndex: undefined}));
                        yield put(StateInstance.mergeStateAction({ instanceViewData: undefined }));
                        // 向酷大师发送'insert_model'消息
                        postMessage({
                            cmd: 'insert_model',
                            modelIndex: resData,
                            bbox: undefined
                        });
                    }
                }
            },
流程2:更新画布中已插入的插件3d模型(调整参数)

更新外部模型示例代码: 插件代码示例
updateParams(): any {
                const { currentModelIndex, } = (yield ModelListManager.state) as ModelListState;
                const { instanceViewData } = (yield StateInstance.state) as FunctionPanelState;
                if (currentModelIndex && instanceViewData) {
                    const instance = instanceViewData.getKElement();
                    instance.updateVersionAndRefreshView(UpdateFlag.All);
                    const parameters: any = {};
                    instance.getParameters(true).forEach(param => {
                        parameters[param.name] = param.value;
                    });
                    // 根据调整后的参数,请求插件后端重新生成3d 模型
                    yield call(request({
                        url: '/geom/api/model/3dtext/modelindex/update',
                        method: 'post',
                        headers: {
                            Accept: '*/*',
                        },
                    }), {
                        id: currentModelIndex,
                        modelControlData: {
                            familySymbolId: instance.familySymbolId,
                            parameters
                        }
                    });
                    // 向酷大师发送 'update_model'消息
                    postMessage({
                        cmd: 'update_model',
                        modelIndex: currentModelIndex,
                        bbox: {}
                    });
                }
            },
流程3:如何取消插入模型

取消插入示例代码: 插件代码示例
leaveTool(): any {
    const { currentModelIndex } = yield ModelListManager.state;
    postMessage({
        cmd: 'cancel_insert',
        modelIndex: currentModelIndex
    });
    yield putResolve(ModelListManager.mergeStateAction({ currentModelIndex: undefined }));
    yield putResolve(StateInstance.mergeStateAction({ instanceViewData: undefined }));
}
二、插件后端
智能灯箱插件后端主要是实现了一系列WebHook API,供酷大师在特定时刻来获取、复制、删除灯箱的3d模型
WebHook API的实现方式可以参考 酷大师插件后端开发指南