service-basics
本文回答:
vjmap.Service的实例化、Token 管理、工作区切换、Key 管理。
一、实例化
const svc = new vjmap.Service(
"https://vjmap.com/server/api/v1", // 服务基地址
"eyJhbGciOi..." // Access Token
);
官方公测地址:https://vjmap.com/server/api/v1。私有化部署改为你的域名。
Token 在 vjmap 控制台 申请。生产环境不要硬编码在前端,推荐后端签发 short-lived token。
二、基本属性 / 方法
svc.baseUrl(); // 返回 baseUrl 字符串
svc.accessToken; // 当前 token
svc.styleVersion(); // 可用于 style.version
svc.glyphsUrl(); // 可用于 style.glyphs
svc.currentMapParam(); // 最近一次 openMap 的参数(含 mapid、version、bounds、drawBounds、darkMode)
svc.setCurrentMapParam({ darkMode: true, bounds: "[-1000,-1000,1000,1000]" });
// 适用于未 openMap 就需要 svc 参数的场景(空白图)
⚠️ 顶层
vjmap.accessToken是只读 getter(赋值会抛only a getter,d.ts 顶层亦未声明)——token 请在new Service(url, token)或 mapaccessTokenoption 里传,不要写顶层。
三、工作区(数据隔离)
不同工作区的数据互不可见,权限独立。
svc.switchWorkspace("工作区名"); // 空字符串为默认工作区
// 创建 / 修改工作区:云端管理平台 → 工作区管理;或 REST 接口
四、密钥管理
// 把明文密码转 secretKey(不要把 secretKey 暴露给外部)
const key = svc.pwdToSecretKey("mypassword");
// 添加 secretKey:对拥有 key 的图可跳过密码输入
svc.addSecretKey(key);
// 添加 accessKey:访问权限较小,允许读,不能删
svc.addAccessKey("akxxxxxxxxxxxxxxxx");
权限等级:superKey > secretKey > accessKey。详见 map-power。
五、REST 底层 HTTP 方法
用于调用未封装的接口:
svc.httpGet(url); // GET → resolve 包装对象 {status, response, data, xhr},业务 JSON 在 .data
svc.httpPost(url, data); // POST body
svc.httpDel(url); // DELETE
svc.serviceUrl("xxx"); // 拼 {serverUrl}service/xxx(即 …/api/v1/service/xxx);baseUrl() 则是去掉 api/v1 的站点根
例如:
const url = svc.serviceUrl("recognizer/detail?filenames=" + prefix);
const { data } = await svc.httpGet(url); // httpGet/httpPost/httpDel 不直接返回业务 JSON,要取 .data
六、常量枚举获取
一些后台生成的映射(图层、实体类型)在前端需用时可用:
const { entTypeIdMap } = await svc.getConstData();
// entTypeIdMap: { "1": "AcDbLine", "7": "AcDbCircle", ... }
// 逆向:Object.keys(m).find(k => m[k] === "AcDbLine");
其他有用的字段:
svc.getMapLayers():当前打开图的所有图层列表[{ name, index, ... }]。svc.metadata(mapid, version):某张图的元数据(bounds/drawBounds、layers、blockReferences、defaultlayer、layouts等)。
七、错误处理模板
HTTP 非 2xx 时 SDK 的 Promise 直接 reject(reject 值是 {status, response, data, xhr} 普通对象,不是 Error),这类失败不会出现在 res.error 里:
async function safeOpen() {
let res;
try {
res = await svc.openMap({ mapid, mapopenway: vjmap.MapOpenWay.GeomRender });
} catch (e) {
// e.status:403 = token 缺失/无效/过期(网关 body {code:7, msg:"Token is invalid"})或无权限;
// 404 = 图不存在({error:"map file is not exist"});400/500 = 打开失败;0 = 网络/CORS
let body = {};
try { body = JSON.parse(e.response); } catch (_) { /* 非 JSON */ }
if (e.status === 403 && body.code === 7) {
// token 失效,跳转登录
}
throw new Error(body.error ?? body.msg ?? `HTTP ${e.status}`);
}
// 带内错误(HTTP 200):如密码图未给/给错密码 {status:403, error:"no permission to access this map…"}
if (res.error) throw new Error(res.error);
return res;
}
八、常见坑
- 不同工作区的图 mapid 冲突:工作区是隔离的,同一 mapid 在不同工作区是两张图。调用前先
switchWorkspace。 - 跨域:vjmap 服务默认已返回
Access-Control-Allow-Origin: *(无 CORS 配置项);跨域报错多是前置 Nginx/网关改写或丢了头,见 trouble/token-cors。 - Token 失效(HTTP 403,body
{code:7};SDK 层是 reject 不是res.error):实际部署里通常用 2h/24h 的短 token,请注意自动续期。 - 并发 openMap:同一
svc对象不要并发openMap(会覆盖 currentMapParam)。 waitMapOpenFinish可能长时间挂起:tryTime/maxTryTimes参数不是快速轮询语义,自动化调用请自加Promise.race超时护栏。getStyleLayerName(mapid,version)返图层名串;getSliceCacheZoom({mapid,version})返{sliceCacheZoom};cmdSwitchLayers返{layerid}(键全小写);请求失败 reject 的值是普通对象不是Error(String(e)→[object Object];形如{status, response, data, xhr},没有e.message,消息在JSON.parse(e.response)的error/msg字段)。