@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/README.md +36 -5
- package/dist/index.cjs.js +49 -25
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.esm.js +49 -25
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/skills/beisen-ehr/SKILL.md +58 -0
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3507
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: '
|
|
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
|
-
|
|
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
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
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
|
-
|
|
3628
|
+
log(`[BEISEN] ❌ 提交失败:${error.message}`);
|
|
3605
3629
|
return {
|
|
3606
3630
|
content: [{ type: "text", text: `❌ 提交失败:${error.message}` }],
|
|
3607
3631
|
isError: true,
|