唯杰地图 logo唯杰地图
VJMAP
EN

文件操作

vjcad/references/autodraw/file-operations.md 7.9 KB242 行
原文

打开、保存、导入导出图纸的完整指南。


概览

操作 命令方式 API 方式
从服务端打开 OPENFROMSERVER DrawingManagerService.openDrawing()
保存到服务端 SAVESERVER DrawingManagerService.saveDrawing()
从本地缓存打开 OPENFROMLOCAL localService.loadDrawingById()
保存到本地缓存 SAVELOCAL localService.saveDrawing()
导入 DWG IMPORTDWG service.uploadMap() + openDrawing()
导出 DWG EXPORTDWG drawingManager.exportToDwg()
快速保存 QSAVE 下载 WASM 压缩的 .vcad 文件(含 _meta.serverSource)
另存为 SAVEAS 下载 .vcad 文件(OPEN 同时接受 .vcad/.webcad;手工 JSON.stringify(toDb()) 得到的是未压缩 .webcad,不等价于 QSAVE)

命令方式(简单场景)

const { Engine } = vjcad;

await Engine.editor.executerWithOp('OPENFROMSERVER');   // 从服务端打开
await Engine.editor.executerWithOp('SAVESERVER');       // 保存到服务端
await Engine.editor.executerWithOp('OPENFROMLOCAL');    // 从本地缓存打开
await Engine.editor.executerWithOp('SAVELOCAL');        // 保存到本地缓存
await Engine.editor.executerWithOp('IMPORTDWG');        // 导入 DWG
await Engine.editor.executerWithOp('EXPORTDWG');        // 导出 DWG
await Engine.editor.executerWithOp('QSAVE');            // 快速保存
await Engine.editor.executerWithOp('SAVEAS');            // 另存为

服务端文件操作 API

从服务端打开图纸

const { DrawingManagerService, Engine } = vjcad;
const drawingManager = new DrawingManagerService();

const openResult = await drawingManager.openDrawing({
    type: 'imports',            // 'imports' | 'designs'
    mapid: 'drawing-123',
    version: 'v1',
    branch: 'main',
    patchId: 'base',           // 可选,不传则使用最新
    readOnly: false
});

if (openResult.success) {
    const virtualFile = new File(
        [openResult.webcadJson], 'drawing.webcad',
        { type: 'application/json' }
    );
    await Engine.view.openDbDoc(virtualFile, openResult.webcadData);

    // 保存来源信息(用于后续保存)
    Engine.currentDoc.serverSource = {
        type: 'imports',
        mapid: 'drawing-123',
        version: 'v1',
        branchName: 'main',
        lastPatchId: openResult.latestPatchId || 'base'
    };
    await Engine.currentDoc.setOriginalJson(openResult.webcadJson);
}

保存到服务端

const currentDoc = Engine.currentDoc;
const currentJson = JSON.stringify(currentDoc.toDb());
const originalJson = await currentDoc.getOriginalJson();
const src = currentDoc.serverSource;

const saveResult = await drawingManager.saveDrawing({
    type: src.type,
    mapid: src.mapid,
    version: src.version,
    branchName: src.branchName,
    originalJson: originalJson,
    currentJson: currentJson,
    parentId: src.lastPatchId,
    drawingName: '我的图纸',
    author: '作者名',
    remark: '修改说明'
});

if (saveResult.status && saveResult.patchId !== 'no_change') {   // 无变化时 patchId 为 'no_change',什么都不更新
    await currentDoc.setOriginalJson(currentJson);
    currentDoc.serverSource.lastPatchId = saveResult.patchId;
}
// 另需处理:saveResult.idMapping(服务端给新增实体重分配 id,须先更新本地实体 id 再存基准)、
// !saveResult.status && saveResult.conflict?.hasConflict(按 conflictingEntities 处理后带 conflictResolution 重存)。
// 推荐直接用 SAVESERVER 命令,详见 file/server.md

本地缓存操作 API

const { getLocalStorageService, Engine } = vjcad;
const localService = getLocalStorageService();

// 保存(serverSource 必填;新图先补 { type: 'designs', designPath: 'local/xxx' },否则抛错返回 success:false)
if (!Engine.currentDoc.serverSource) {
    Engine.currentDoc.serverSource = { type: 'designs', designPath: 'local/我的图纸' };
}
const saveResult = await localService.saveDrawing({
    serverSource: Engine.currentDoc.serverSource,
    webcadJson: JSON.stringify(Engine.currentDoc.toDb()),
    drawingName: '我的图纸'
});

// 列表
const drawings = await localService.listDrawings();

// 加载(打开后恢复 serverSource 时要带上 record.originalJsonCompressed,
// 且 record.type === 'tiles' 改回 'imports',否则之后 SAVESERVER 无基准、不做增量 diff)
const loadResult = await localService.loadDrawingById(drawingId);

// 删除
await localService.deleteDrawingById(drawingId);

// 统计
const stats = await localService.getStats();

导入 DWG/DXF

const { DrawingManagerService, MapOpenWay, openMapDarkStyle, Engine } = vjcad;

const input = document.createElement('input');
input.type = 'file';
input.accept = '.dwg,.dxf';

input.onchange = async (e) => {
    const file = e.target.files[0];
    if (!file) return;

    const drawingManager = new DrawingManagerService();
    const service = drawingManager.getService();

    // 上传文件
    const uploadResult = await service.uploadMap(file);
    if (uploadResult.error) return;

    // 解析 DWG
    const mapid = file.name.replace(/\.(dwg|dxf)$/i, '') + '_' + Date.now();
    const openResult = await service.openMap({
        mapid, fileid: uploadResult.fileid,
        uploadname: file.name,
        mapopenway: MapOpenWay.Memory,
        style: openMapDarkStyle()
    }, true);
    if (openResult.error) return;

    // 获取数据并加载
    const drawingResult = await drawingManager.openDrawing({
        type: 'imports',
        mapid: openResult.mapid,
        version: openResult.version,
        branch: 'main'
    });

    if (drawingResult.success) {
        const virtualFile = new File(
            [drawingResult.webcadJson], 'drawing.webcad',
            { type: 'application/json' }
        );
        await Engine.view.openDbDoc(virtualFile, drawingResult.webcadData);
    }
};

input.click();

导出 DWG

const { DrawingManagerService, Engine } = vjcad;

const drawingManager = new DrawingManagerService();
const service = drawingManager.getService();
const webcadJson = JSON.stringify(Engine.currentDoc.toDb());

const exportResult = await drawingManager.exportToDwg({
    type: 'imports',
    webcadJson: webcadJson,
    mapid: '你的图ID',
    version: '图纸版本'
});

// 实际返回 { status: true, path, filename, entityCount } 或 { status: false, error }
// 只返回服务端文件名/路径,不含二进制(没有 success / data 字段;d.ts 里的 downloadUrl 从不赋值)
if (exportResult.status) {
    console.log('已导出:', exportResult.filename, exportResult.path, '实体数:', exportResult.entityCount);
    // 下载需按服务端路径拼 URL(参考 EXPORTDWG 命令):
    // `${SystemConstants.SERVICE_ROOT_URL}<下载目录>/${exportResult.filename}?token=${SystemConstants.ACCESS_TOKEN}`
} else {
    console.error('导出失败:', exportResult.error);
}

新建文档

Engine.view.newDocument();
Engine.currentDoc.name = '新图纸';

增量保存说明

WebCAD 使用增量保存机制:

  1. 原始数据 — 通过 setOriginalJson() 保存的基准数据
  2. 当前数据 — 通过 toDb() 获取的当前文档数据
  3. Diff 计算 — 前端用 WASM createWebcadDiff 比较差异,只上传 patch;缺少原始数据时整图上传(不带 parentId,失去冲突检测)
  4. Patch 链 — 每次保存生成 Patch,形成版本历史
图纸类型 说明
imports 已导入的 DWG 图纸,支持增量 patch
designs 从零创建的设计图