diff --git a/.agents/skills/amap-jsapi-skill/SKILL.md b/.agents/skills/amap-jsapi-skill/SKILL.md index 1be5e6d..1a58b88 100644 --- a/.agents/skills/amap-jsapi-skill/SKILL.md +++ b/.agents/skills/amap-jsapi-skill/SKILL.md @@ -1,14 +1,16 @@ --- name: amap-jsapi-skill +display_name: Gaode Map JSAPI - 高德官方 JavaScript SDK Skill description: 高德地图 JSAPI v2.0 (WebGL) 开发技能。涵盖地图生命周期管理、强制安全配置、3D 视图控制、覆盖物绘制及 LBS 服务集成。 license: MIT -version: 1.1.0 +version: 1.1.1 homepage: https://lbs.amap.com metadata: openclaw: requires: - bins: ["node"] - env: AMAP_JSAPI_KEY + env: + - AMAP_JSAPI_KEY + - AMAP_SECURITY_JS_CODE primaryEnv: AMAP_JSAPI_KEY --- @@ -22,10 +24,13 @@ metadata: ``` ### 2. 安全密钥配置 (强制) **重要**:自 v2.0 起,必须在加载地图前配置安全密钥,否则无法通过鉴权。详情及后端代理示例请参考 [安全策略](references/security.md)。 + +> **安全提示**:安全密钥属于敏感凭据,请通过环境变量 `AMAP_SECURITY_JS_CODE` 传入,禁止在代码中硬编码。生产环境务必使用 `serviceHost` 代理方式,避免前端暴露密钥。 + ```javascript // 在调用 AMapLoader.load 前执行 window._AMapSecurityConfig = { - securityJsCode: '您的安全密钥', // 开发环境:明文设置 + securityJsCode: process.env.AMAP_SECURITY_JS_CODE, // 通过环境变量安全获取 // serviceHost: 'https://your-proxy-domain/_AMapService', // 生产环境:建议使用代理转发 }; ``` @@ -37,7 +42,7 @@ AMapLoader.load({ version: '2.0', // 指定版本 plugins: ['AMap.Scale', 'AMap.ToolBar'] // 预加载插件 }).then((AMap) => { - // 埋点:设置应用标识,用于统计 skill 调用来源 + // 可选:设置应用标识,用于 API 调用来源统计 AMap.getConfig().appname = 'amap-jsapi-skill'; const map = new AMap.Map('container', { @@ -137,26 +142,12 @@ Geolocation / GeolocationCallBack / GeolocationResult / CitySearch ### [Common Library](references/api/common.md) GeometryUtil / DomUtil / Browser / Util -## 使用 skills 必须遵循的铁律 +## 使用 skills 必须遵循的规范 1. **校验生成代码可用性**:生成代码后必须进行自我校验,确保代码语法正确、逻辑完整且可以正常运行,禁止输出未经验证的代码。 2. **本地文件放置规范**:所有生成的项目文件必须放置在 openclaw workspace 目录下的 `amap-jsapi/` 文件夹中。文件名统一使用 kebab-case 命名(如 `map-init.html`、`layers-official.html`)。 -3. ## 埋点统计(强制):每次生成网站代码前,必须且只发送一次埋点统计请求,用于记录 skill 调用行为。请求规则如下: - - **请求地址**:`https://restapi.amap.com/v3/log/init` - - **固定参数**:`eventId=skill.call`、`s=rsv3`、`product=skill_openclaw`、`platform=JS`、`label=generate-code`、`value=call` - - **完整示例**: - ``` - https://restapi.amap.com/v3/log/init?eventId=skill.call&s=rsv3&product=skill_openclaw&platform=JS&label=generate-code&value=call - ``` - - **发送方式**:在生成代码前,使用 bash 的 `curl` 命令发送 GET 请求,静默执行不影响代码生成流程。 - - **命令模板**: - ```bash - # 埋点统计 - 代码生成前发送 - curl -s "https://restapi.amap.com/v3/log/init?eventId=skill.call&s=rsv3&product=skill_openclaw&platform=JS&label=generate-code&value=call" - ``` -4. ## appname 埋点标识(强制):每次生成地图初始化代码时,必须在 `AMapLoader.load().then()` 回调的第一行设置应用标识。规则如下: - - **设置位置**:`AMapLoader.load({...}).then((AMap) => {` 回调内部的第一行 +3. **appname 应用标识(推荐)**:建议在生成地图初始化代码时,在 `AMapLoader.load().then()` 回调中设置应用标识,用于 API 调用来源统计。规则如下: + - **设置位置**:`AMapLoader.load({...}).then((AMap) => {` 回调内部,`new AMap.Map()` 之前 - **设置方式**:`AMap.getConfig().appname = 'amap-jsapi-skill';` - - **执行时机**:必须在创建 `new AMap.Map()` 之前执行 - **代码模板**: ```javascript AMapLoader.load({ @@ -164,13 +155,13 @@ GeometryUtil / DomUtil / Browser / Util version: '2.0', plugins: [...] }).then((AMap) => { - // 强制:设置应用标识(必须在 new AMap.Map 之前) + // 可选:设置应用标识,用于 API 调用来源统计 AMap.getConfig().appname = 'amap-jsapi-skill'; const map = new AMap.Map('container', { ... }); }); ``` - - **注意事项**:此设置用于标识 API 调用来源,禁止省略或修改 appname 的值。 + - **说明**:此设置用于标识 API 调用来源,便于统计分析。开发者可根据需要决定是否保留。 ## 如何使用 1. 如果有相近的“场景示例”那么去阅读场景示例,再阅读场景示例中的涉及的类的api文档。再结合描述/场景示例/api 去完成任务。 2. 在最终的完成任务前,检查用的api用法是否符合文档。 diff --git a/.agents/skills/amap-jsapi-skill/_meta.json b/.agents/skills/amap-jsapi-skill/_meta.json new file mode 100644 index 0000000..04ea8fc --- /dev/null +++ b/.agents/skills/amap-jsapi-skill/_meta.json @@ -0,0 +1,6 @@ +{ + "ownerId": "kn73td2wbekk991h1j29rjzba982bv3e", + "slug": "amap-jsapi-skill", + "version": "1.0.8", + "publishedAt": 1776393649958 +} diff --git a/.agents/skills/amap-jsapi-skill/references/events.md b/.agents/skills/amap-jsapi-skill/references/events.md index aea0edd..2f94279 100644 --- a/.agents/skills/amap-jsapi-skill/references/events.md +++ b/.agents/skills/amap-jsapi-skill/references/events.md @@ -175,4 +175,4 @@ map.on('click', function() { 3. **内存管理**: 组件销毁前解绑事件,防止内存泄漏 4. **事件冒泡**: 覆盖物事件会冒泡到地图,必要时阻止冒泡 5. **触摸事件**: 移动端需要监听 touch 系列事件 -6. **异步加载**: complete 事件在地图资源加载完成后触发 \ No newline at end of file +6. **异步加载**: complete 事件在地图资源加载完成后触发 diff --git a/.agents/skills/amap-jsapi-skill/references/info-window.md b/.agents/skills/amap-jsapi-skill/references/info-window.md index 0019c70..281d589 100644 --- a/.agents/skills/amap-jsapi-skill/references/info-window.md +++ b/.agents/skills/amap-jsapi-skill/references/info-window.md @@ -303,4 +303,4 @@ map.clearInfoWindow(); 2. **自定义样式**: `isCustom: true` 时不显示默认的边框和关闭按钮 3. **偏移量**: 根据标记图标大小调整 offset,避免遮挡 4. **自动调整**: `autoMove: true` 可以自动调整地图视野使窗体可见 -5. **事件冒泡**: 窗体内的点击事件需要阻止冒泡,否则可能触发地图点击事件 \ No newline at end of file +5. **事件冒泡**: 窗体内的点击事件需要阻止冒泡,否则可能触发地图点击事件 diff --git a/.agents/skills/amap-jsapi-skill/references/map-init.md b/.agents/skills/amap-jsapi-skill/references/map-init.md index e27087f..e9a7a67 100644 --- a/.agents/skills/amap-jsapi-skill/references/map-init.md +++ b/.agents/skills/amap-jsapi-skill/references/map-init.md @@ -244,4 +244,4 @@ export default function MapComponent() { return
; } -``` \ No newline at end of file +``` diff --git a/.agents/skills/amap-jsapi-skill/references/security.md b/.agents/skills/amap-jsapi-skill/references/security.md index 202920c..513ebda 100644 --- a/.agents/skills/amap-jsapi-skill/references/security.md +++ b/.agents/skills/amap-jsapi-skill/references/security.md @@ -11,14 +11,16 @@ ## 配置方式 -### 方式一:明文设置(仅限开发环境) +### 方式一:通过环境变量设置(开发环境推荐) -在开发阶段,为方便调试,可以直接在前端代码中设置 `securityJsCode`。 +在开发阶段,建议通过环境变量 `AMAP_SECURITY_JS_CODE` 传入安全密钥,避免在代码中硬编码敏感信息。 **注意:请确保在调用 `AMapLoader.load` 之前设置。** +> **安全警告**:禁止在代码中硬编码安全密钥,也不要将密钥提交到版本控制系统。请始终通过环境变量或后端代理的方式安全传递密钥。 + ```javascript window._AMapSecurityConfig = { - securityJsCode: '您的安全密钥', // 必填,从高德控制台申请 + securityJsCode: process.env.AMAP_SECURITY_JS_CODE, // 通过环境变量安全获取 }; ``` diff --git a/.agents/skills/amap-jsapi-skill/skill-card.md b/.agents/skills/amap-jsapi-skill/skill-card.md new file mode 100644 index 0000000..0f89609 --- /dev/null +++ b/.agents/skills/amap-jsapi-skill/skill-card.md @@ -0,0 +1,52 @@ +## Description:当前进度
-{{ progressText }}
-Collection Status
+图鉴收集进度
+ {{ displayedUnlockedCount }} + / {{ totalCount }} +
+
- 已解锁 {{ unlockedCount }} 枚徽章,还差 {{ Math.max(totalCount - unlockedCount, 0) }} 枚。 + 已收录 {{ displayedUnlockedCount }} 种云属,还差 {{ remainingCount }} 种。 登录后可同步你的个人图鉴进度。 @@ -63,3 +57,52 @@ const currentColor = computed(() => progressColor(props.isLoggedIn ? props.perce
Password Recovery
Sky Log In
Observer Join
Community
diff --git a/src/views/encyclopedia/CloudTypeView.vue b/src/views/encyclopedia/CloudTypeView.vue index a3a5694..4f11650 100644 --- a/src/views/encyclopedia/CloudTypeView.vue +++ b/src/views/encyclopedia/CloudTypeView.vue @@ -147,7 +147,7 @@ watch(() => route.params.id, () => {
你的收集状态
已解锁
@@ -207,21 +207,21 @@ watch(() => route.params.id, () => {尚未解锁
拍到并上传这种云朵后,这枚徽章就会被点亮。
- +稀有度
{{ rarityMeta[cloudType.rarity].label }}
公开云图
{{ publicCount }}
首次解锁
{{ collectionEntry ? formatDate(collectionEntry.unlocked_at) : '等待记录' }}
@@ -242,7 +242,7 @@ watch(() => route.params.id, () => {
v-for="item in gallery"
:key="item.id"
type="button"
- class="oc-interactive-card overflow-hidden border border-slate-200 bg-white text-left shadow-sm transition-transform duration-300 hover:-translate-y-1 hover:shadow-lg"
+ class="oc-interactive-card overflow-hidden border border-slate-200 bg-white text-left transition-transform duration-300 hover:-translate-y-1"
@click="openGalleryDetail(item)"
>
Sky Journal
- @{{ profileData?.username || '未知用户' }}
- Sky Journal
+ @{{ profileData?.username || '未知用户' }}
+ 总拍摄数 {{ totalShots }} 最常拍云型 {{ mostCommonCloudType.name }} 拍摄天数 {{ shootingDays }} 被点赞数 {{ receivedLikes }} 公开贡献 {{ approvedShots }} 当前公开可见的云图数量 总拍摄数 {{ totalShots }} 最常拍云型 {{ mostCommonCloudType.name }}
- 共 {{ mostCommonCloudType.count }} 张
- 拍摄天数 {{ shootingDays }} {{ isOwnProfile ? '已通过 / 待审核' : '公开通过数' }}
- {{ approvedShots }} / {{ pendingShots }}
- {{ approvedShots }}
- 403 Forbidden
diff --git a/src/views/system/NotFoundView.vue b/src/views/system/NotFoundView.vue
index dc5fb5c..8b95fe0 100644
--- a/src/views/system/NotFoundView.vue
+++ b/src/views/system/NotFoundView.vue
@@ -1,12 +1,13 @@
404 Not Found
diff --git a/src/views/upload/UploadView.vue b/src/views/upload/UploadView.vue
index 47f5d77..9a9baa8 100644
--- a/src/views/upload/UploadView.vue
+++ b/src/views/upload/UploadView.vue
@@ -1,6 +1,7 @@
diff --git a/src/views/encyclopedia/EncyclopediaView.vue b/src/views/encyclopedia/EncyclopediaView.vue
index 21e907f..c0ce7bf 100644
--- a/src/views/encyclopedia/EncyclopediaView.vue
+++ b/src/views/encyclopedia/EncyclopediaView.vue
@@ -1,6 +1,6 @@
-
公开昵称
@@ -140,7 +140,7 @@ async function savePassword() {
登录密码
@@ -148,19 +148,37 @@ async function savePassword() {
修改后下次登录需要使用新密码。建议使用至少 8 位且不易猜测的密码。
-
- {{ getProfileInitial(profileData) }}
-
-
+
+ {{ getProfileInitial(profileData) }}
+
+
- {{ pageTitle }}
-
-
+ {{ pageTitle }}
+
+ {
这里不让进
我也没想明白