diff --git a/web/src/views/goauto/client-keys/index.vue b/web/src/views/goauto/client-keys/index.vue
index 03652ab..e170950 100644
--- a/web/src/views/goauto/client-keys/index.vue
+++ b/web/src/views/goauto/client-keys/index.vue
@@ -29,6 +29,7 @@
selectModule(m.key, value)">{{ m.title }}只读读写
独立动作:{{ actionName(action) }}
+
设为当前后,所有设备会提示更新
@@ -51,7 +52,7 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import { listClientKeys, clientKeyModules, createClientKey, editClientKey, disableClientKey } from '@/api/goauto/client-keys'
-const actionLabels = { sync: '立即同步', import: '导入', match: '匹配 / 确认', collect: '创建 / 重新采集', purchase: '创建 / 重试采购', writeback: '回写', delete: '删除', reparse: '重新解析', activate: '设置当前规则' }
+const actionLabels = { sync: '立即同步', import: '导入', match: '匹配 / 确认', collect: '创建 / 重新采集', purchase: '创建 / 重试采购', writeback: '回写', delete: '删除', reparse: '重新解析', activate: '设置当前规则', release_upload: '上传 Agent 版本', release_activate: '设置当前 Agent 版本' }
const snapshot = grants => JSON.stringify(Object.values(grants).map(g => ({ ...g, actions: [...g.actions].sort() })).sort((a, b) => a.module.localeCompare(b.module)))
const errorText = error => error.response?.data?.message || '请求失败,请检查网络后重试'
@@ -114,6 +115,7 @@ h2 { margin: 0 0 12px; }
.module-row { padding: 10px 0; border-top: 1px solid var(--el-border-color-lighter); }
.module-main { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.actions { padding: 4px 0 0 22px; }
+.risk { margin: 4px 0 0; padding-left: 22px; color: var(--el-color-warning); font-size: 13px; }
.notice, .el-pagination { margin: 16px 0; }
.validation { color: var(--el-color-danger); }
.secret { white-space: pre-wrap; overflow-wrap: anywhere; padding: 16px; background: var(--el-fill-color-light); }
diff --git a/web/tests/unit/client-keys.spec.js b/web/tests/unit/client-keys.spec.js
index a49dfd0..677c427 100644
--- a/web/tests/unit/client-keys.spec.js
+++ b/web/tests/unit/client-keys.spec.js
@@ -59,3 +59,8 @@ test('late creation response after navigation does not retain a secret', async()
resolve({ data: { secret: 'DEMO_ONLY_NOT_A_VALID_SECRET' }}); await pending
expect(p.secret).toBe(''); expect(p.secretOpen).toBe(false)
})
+test('agent release actions have distinct labels', () => {
+ const p = vm()
+ expect(p.actionName('release_upload')).toBe('上传 Agent 版本')
+ expect(p.actionName('release_activate')).toBe('设置当前 Agent 版本')
+})