From 53733b39fcfd5b3ecef82b8eb346a424121b02c5 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Mon, 14 Sep 2026 14:00:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=A4=9A=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=8E=E7=94=A8=E6=88=B7=E7=BA=A7MCP=E9=9A=94?= =?UTF-8?q?=E7=A6=BB=EF=BC=8C=E4=BC=98=E5=8C=96=E6=B1=87=E6=80=BB=E8=AF=8A?= =?UTF-8?q?=E6=96=AD=E4=B8=8EUI=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 多用户支持:新增 user_mcp_tokens 表,实现按用户 Token 哈希隔离 MCP 查询 - 注册控制:支持 ALLOW_REGISTER 环境变量自适应开关多用户注册 - 前端同步:增加跨账号防脏提交安全拦截,优化登录/注册状态提示 - 汇总页优化:移除合计应得卡片冗余说明,诊断卡片新增「综合时薪诊断」 - 文档更新:同步更新 README.md 关于多用户、MCP 与部署说明 --- README.md | 12 ++-- index.html | 19 ++++-- server/adapters/d1.js | 58 +++++++++++++++++++ server/adapters/sqlite-node.js | 58 +++++++++++++++++++ server/core/api.js | 22 ++++--- server/core/mcp.js | 103 +++++++++++++++++++++++---------- server/core/schema.sql | 21 +++---- server/core/store.js | 9 ++- server/test/mcp.test.js | 49 +++++++++++++++- sync.js | 32 +++++++++- 10 files changed, 320 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 150a571..0ce8967 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,8 @@ 额度用尽后转纯后台轮询。技术日志仅输出到控制台(`[boot-guard]` 前缀)。 - `shared/payroll.js`:独立同构薪酬计算模块(包含时薪折算、截断规则、周期合并等 30+ 纯函数)。 - `sync.js`:本地优先增量同步适配层。 -- `server/`:轻量级 REST API 服务端(支持鉴权、版本同步、健康检查 `/api/health`), - 并内置只读 MCP 端点(`POST /mcp`):AI 客户端可查询出勤与薪酬,配置在页面「设置 → AI 接入 (MCP)」管理,开关/令牌即时生效。 +- `server/`:轻量级 REST API 服务端(支持多用户鉴权、版本同步、健康检查 `/api/health`), + 并内置只读 MCP 端点(`POST /mcp`):AI 客户端可查询出勤与薪酬。支持多用户独立 MCP 令牌隔离,配置在页面「设置 → AI 接入 (MCP)」管理,开关/令牌即时生效。 - `.build/`:Tailwind CSS 预编译工作区(只在开发机跑,产物是 `vendor/tailwind.css`,运行时不需要它)。 **改 `index.html` 里出现的新 Tailwind class 后必须重跑**:`cd .build && npx tailwindcss -i input.css -o ../vendor/tailwind.css --minify`, 否则新样式不在预编译产物里,页面静默丢样式(2026-09-13 MCP 开关按钮不可见即此因)。 @@ -103,7 +103,7 @@ systemctl enable --now work-hours-tracker.service ``` 单元文件关键内容(端口固定 9522:localStorage 按 origin 隔离,换端口 = 换 origin, -已有打卡数据会看不见,勿改): +已有打卡数据会看不见,勿改;如需开启多用户注册,可添加 `Environment=ALLOW_REGISTER=1`): ```ini [Unit] Description=Work Hours Tracker (Node: static + sync API) @@ -116,6 +116,7 @@ WorkingDirectory=/root/.openclaw/workspace/work-hours-tracker/server ExecStart=/usr/bin/node --disable-warning=ExperimentalWarning node-server.js Environment=PORT=9522 Environment=HOST=0.0.0.0 +# Environment=ALLOW_REGISTER=1 # 开放多用户自适应注册(首个用户创建后如需继续允许新账号注册可启用) Restart=always RestartSec=3 @@ -171,9 +172,10 @@ curl -s http://127.0.0.1:9522/api/health - **工具 7 个**(全部只读,不写库):`get_month_summary` / `get_shift_records` / `get_payroll_settings` / `get_penalty_details` / `simulate_leave` / `list_month_overview` / `get_business_rules` -- **配置存 DB**(`app_settings` 表),页面「设置 → AI 接入 (MCP)」可开关/生成/重置令牌,**即时生效无需重启** +- **配置存 DB**(`user_mcp_tokens` 表,用户级物理隔离),页面「设置 → AI 接入 (MCP)」可开关/生成/重置各自令牌,**即时生效无需重启** +- **多用户隔离**:各用户 AI 客户端凭借专属 Bearer Token 鉴权,仅查自身出勤打卡与薪酬概况,互不干扰 - `MCP_AUTH_TOKEN` 环境变量只做首启种子(库里从没有过令牌时迁入 DB),不设也行 - 状态语义:未配置 → `404`(端点视为不存在);已配置但关闭 → `503`;令牌错误 → `401` - 管理 API(登录态):`GET /api/mcp/status`(掩码)、`POST /api/mcp/token`(生成/重置,明文仅回一次)、 `GET /api/mcp/token`(复制用取回明文)、`POST /api/mcp/enabled` -- 测试:`cd server && node --disable-warning=ExperimentalWarning test/mcp.test.js`(39 项) +- 测试:`cd server && node --disable-warning=ExperimentalWarning test/mcp.test.js`(47 项,含多用户隔离验证) diff --git a/index.html b/index.html index d0fd844..45887c2 100644 --- a/index.html +++ b/index.html @@ -429,7 +429,6 @@ 合计应得 {{ money(earnedTotal) }} -

查获在本月只作记录(当前累计 {{ signed(monthStats.rawReview) }});须次月初组长审核、扣除漏查与其他扣款后提交定稿才算奖金。未定稿一律按 ¥0 计入应得,与未达 {{ settings.fullDays }} 天不计满勤奖同一个道理。

@@ -645,6 +644,10 @@

本月 {{ monthStats.missedCount }} 次漏查,将扣 {{ money(monthStats.missedPenalty) }},约等于白干 {{ fmt(monthStats.missedPenalty / settings.rate) }} 小时。

+

+ 综合时薪 ¥{{ effectiveHourly }} /h + (合计应得 {{ money(earnedTotal) }} ÷ 总工时 {{ fmt(monthStats.totalHours) }}h,含满勤奖与审核定稿) +

@@ -792,13 +795,14 @@ class="w-full text-xs text-slate-700 bg-slate-50 border border-slate-200 rounded-lg px-3 py-2 outline-none focus:border-indigo-500" />
- +

+