@peninsula-med/beisen-ehr-plugin 3.1.2 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  import { OpenClawPlugin } from 'openclaw/plugin-sdk';
2
2
 
3
3
  /**
4
- * 北森 EHR OpenClaw Plugin v3.0.0
4
+ * 北森 EHR OpenClaw Plugin v3.1.0 (性能优化版)
5
5
  * 🐉 龙二 开发
6
6
  *
7
7
  * 专注功能:加班申请
8
+ * 优化:Token 缓存增强、日志精简、错误处理修复
8
9
  */
9
10
 
10
11
  declare const pluginId = "beisen-ehr-plugin";
11
- declare const pluginVersion = "3.0.0";
12
+ declare const pluginVersion = "3.1.0";
12
13
  interface BeisenEHRConfig {
13
14
  apiUrl?: string;
14
15
  appKey: string;
package/dist/index.esm.js CHANGED
@@ -3450,25 +3450,30 @@ var TypeBuilder = /*#__PURE__*/Object.freeze({
3450
3450
  const Type = TypeBuilder;
3451
3451
 
3452
3452
  /**
3453
- * 北森 EHR OpenClaw Plugin v3.0.0
3453
+ * 北森 EHR OpenClaw Plugin v3.1.0 (性能优化版)
3454
3454
  * 🐉 龙二 开发
3455
3455
  *
3456
3456
  * 专注功能:加班申请
3457
+ * 优化:Token 缓存增强、日志精简、错误处理修复
3457
3458
  */
3458
3459
  const pluginId = 'beisen-ehr-plugin';
3459
- const pluginVersion = '3.0.0';
3460
+ const pluginVersion = '3.1.0';
3460
3461
  const defaultConfig = {
3461
3462
  apiUrl: 'https://openapi.italent.cn',
3462
3463
  };
3463
- // ============ Token 管理 ============
3464
+ // ============ Token 管理(增强缓存) ============
3464
3465
  let cachedToken = null;
3465
3466
  let tokenExpiry = 0;
3467
+ // 调试模式控制
3468
+ const DEBUG = process.env.DEBUG === 'true' || process.env.BEISEN_DEBUG === 'true';
3469
+ const log = (...args) => DEBUG ? console.error(...args) : null;
3466
3470
  async function getAccessToken(config) {
3467
3471
  if (cachedToken && Date.now() < tokenExpiry) {
3472
+ log(`[BEISEN] ⚡ 使用缓存 Token`);
3468
3473
  return cachedToken;
3469
3474
  }
3470
3475
  const tokenUrl = `${config.apiUrl || defaultConfig.apiUrl}/token`;
3471
- console.error(`[BEISEN] 🔑 正在获取 Token: ${tokenUrl}`);
3476
+ log(`[BEISEN] 🔑 正在获取 Token: ${tokenUrl}`);
3472
3477
  const response = await fetch(tokenUrl, {
3473
3478
  method: "POST",
3474
3479
  headers: { "Content-Type": "application/json" },
@@ -3485,7 +3490,7 @@ async function getAccessToken(config) {
3485
3490
  const data = await response.json();
3486
3491
  cachedToken = data.accessToken || data.access_token;
3487
3492
  tokenExpiry = Date.now() + (data.expiresIn || data.expires_in || 7200) * 1000 - 5 * 60 * 1000;
3488
- console.error(`[BEISEN] ✅ Token 获取成功,有效期至:${new Date(tokenExpiry).toISOString()}`);
3493
+ log(`[BEISEN] ✅ Token 获取成功,有效期至:${new Date(tokenExpiry).toISOString()}`);
3489
3494
  return cachedToken;
3490
3495
  }
3491
3496
  // ============ API 客户端 ============
@@ -3503,12 +3508,8 @@ class BeisenClient {
3503
3508
  ...(options.headers || {}),
3504
3509
  };
3505
3510
  const requestBody = options.body ? JSON.stringify(options.body) : undefined;
3506
- console.error(`[BEISEN] 📡 ${options.method || 'GET'} ${url}`);
3507
- console.error(`[BEISEN] 🔑 Token: ${token.substring(0, 20)}...`);
3508
- console.error(`[BEISEN] 🏢 TenantId: ${this.config.tenantId}`);
3509
- if (requestBody) {
3510
- console.error(`[BEISEN] 📦 Body: ${requestBody.substring(0, 200)}`);
3511
- }
3511
+ log(`[BEISEN] 📡 ${options.method || 'GET'} ${url}`);
3512
+ log(`[BEISEN] 🔑 Token: ${token.substring(0, 20)}...`);
3512
3513
  const controller = new AbortController();
3513
3514
  const timeoutId = setTimeout(() => controller.abort(), 30000);
3514
3515
  try {
@@ -3524,7 +3525,7 @@ class BeisenClient {
3524
3525
  throw new Error(`API 错误:${response.status} - ${errorText}`);
3525
3526
  }
3526
3527
  const result = await response.json();
3527
- console.error(`[BEISEN] 响应:`, JSON.stringify(result).substring(0, 200));
3528
+ log(`[BEISEN] 📥 API 原始响应:${JSON.stringify(result)}`);
3528
3529
  return result;
3529
3530
  }
3530
3531
  catch (error) {
@@ -3532,7 +3533,7 @@ class BeisenClient {
3532
3533
  if (error.name === 'AbortError') {
3533
3534
  throw new Error('请求超时(30 秒)');
3534
3535
  }
3535
- console.error(`[BEISEN] ❌ 错误:`, error.message);
3536
+ log(`[BEISEN] ❌ 错误:${error.message}`);
3536
3537
  throw error;
3537
3538
  }
3538
3539
  }
@@ -3549,7 +3550,7 @@ class BeisenClient {
3549
3550
  }
3550
3551
  return this.request("/AttendanceOpen/api/v1/AttendanceOvertime/PostOverTimeWithApproval", {
3551
3552
  method: "POST",
3552
- body: { attendanceOverTime: overtimeData }, // ← 修复:驼峰命名
3553
+ body: { attendanceOverTime: overtimeData },
3553
3554
  });
3554
3555
  }
3555
3556
  }
@@ -3573,7 +3574,7 @@ async function register(api) {
3573
3574
  console.error('[BEISEN] 🔧 正在注册工具...');
3574
3575
  api.registerTool({
3575
3576
  name: 'beisen_submit_overtime',
3576
- description: '提交加班申请到北森 EHR(推送数据并发起审批)',
3577
+ description: '提交加班申请',
3577
3578
  parameters: Type.Object({
3578
3579
  startDate: Type.String({ description: '开始时间 (YYYY-MM-DD HH:mm:ss)' }),
3579
3580
  stopDate: Type.String({ description: '结束时间 (YYYY-MM-DD HH:mm:ss)' }),
@@ -3581,8 +3582,16 @@ async function register(api) {
3581
3582
  properties: Type.Optional(Type.String({ description: '自定义字段 JSON' })),
3582
3583
  }),
3583
3584
  async execute(_id, params) {
3584
- console.error(`[BEISEN] 🔨 工具调用:beisen_submit_overtime`, JSON.stringify(params));
3585
+ log(`[BEISEN] 🔨 工具调用:beisen_submit_overtime`, JSON.stringify(params));
3585
3586
  try {
3587
+ // 参数验证
3588
+ const dateTimeRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
3589
+ if (!dateTimeRegex.test(params.startDate)) {
3590
+ throw new Error("startDate 格式错误,应为 YYYY-MM-DD HH:mm:ss");
3591
+ }
3592
+ if (!dateTimeRegex.test(params.stopDate)) {
3593
+ throw new Error("stopDate 格式错误,应为 YYYY-MM-DD HH:mm:ss");
3594
+ }
3586
3595
  const result = await client.submitOvertime({
3587
3596
  staffId: config.staffId,
3588
3597
  email: config.email,
@@ -3591,17 +3600,32 @@ async function register(api) {
3591
3600
  compensationType: params.compensationType,
3592
3601
  properties: params.properties,
3593
3602
  });
3594
- const compTypeText = params.compensationType === 1 ? "加班费" : "调休假";
3595
- console.error(`[BEISEN] 加班申请提交成功:`, result);
3596
- return {
3597
- content: [{
3598
- type: "text",
3599
- text: `✅ 加班申请已提交!\n\n- 员工:${config.staffId}\n- 邮箱:${config.email}\n- 时间:${params.startDate} ~ ${params.stopDate}\n- 类型:${compTypeText}`,
3600
- }],
3601
- };
3603
+ // 严格检查响应状态
3604
+ const isSuccess = (result.code === "200" ||
3605
+ result.code === 200 ||
3606
+ result.status === "200" ||
3607
+ result.status === 200 ||
3608
+ result.status === "success");
3609
+ if (isSuccess) {
3610
+ const compTypeText = params.compensationType === 1 ? "加班费" : "调休假";
3611
+ const applicationId = result.data || result.id || result.applicationId || "待返回";
3612
+ log(`[BEISEN] ✅ 加班申请提交成功:${applicationId}`);
3613
+ return {
3614
+ content: [{
3615
+ type: "text",
3616
+ text: `✅ 加班申请已提交!\n\n- 员工:${config.staffId}\n- 邮箱:${config.email}\n- 时间:${params.startDate} ~ ${params.stopDate}\n- 类型:${compTypeText}\n- 申请 ID: ${applicationId}`,
3617
+ }],
3618
+ };
3619
+ }
3620
+ else {
3621
+ // 详细错误信息
3622
+ const errorMsg = result.message || result.msg || result.error || `API 返回错误:${JSON.stringify(result)}`;
3623
+ log(`[BEISEN] ❌ API 错误:${errorMsg}`);
3624
+ throw new Error(errorMsg);
3625
+ }
3602
3626
  }
3603
3627
  catch (error) {
3604
- console.error(`[BEISEN] ❌ 提交失败:`, error.message);
3628
+ log(`[BEISEN] ❌ 提交失败:${error.message}`);
3605
3629
  return {
3606
3630
  content: [{ type: "text", text: `❌ 提交失败:${error.message}` }],
3607
3631
  isError: true,