
1С:Предприятие
直接从 1С 培训员工并分配课程:人事和部门数据自动同步到 LMS,培训任务回传到 1С,并通过签名链接免密码登录个人账户。
将 1С 接入 Brusnika.LMS 的指南
本说明面向自助接入:无需我们团队的协助。接入分为两部分。1С 开发人员在 1С 中创建并发布 HTTP 服务,LMS 管理员在设置中填写其地址和密钥。要启用自动同步,还需要 LMS 服务器管理员。
大致顺序:先在 1С 中创建服务并通过 curl 检查,然后在 LMS 中配置,最后设置计划任务和免密码登录。
准备工作
- Brusnika.LMS 处于 Standalone 模式(独立门户)。
- LMS 中的管理员权限:“系统管理”板块。
- 一名会添加配置扩展和 HTTP 服务的 1С 开发人员。
- 已发布在 Web 服务器上的 1С 信息库,其地址可通过 HTTPS 从 LMS 访问。
- 供 LMS 访问使用的 1С 信息库专用服务用户。
- 要启用自动同步——需要访问 LMS 服务器(服务器管理员)。
一个 LMS 门户可以容纳多个独立连接——例如,每个拥有自己 1С 库的法人实体一个连接。步骤 1–5 和 7 需要为每个库分别执行,而步骤 6 中的 cron 任务只需为整个门户配置一次。如果您只有一个库,创建一个连接即可。
1С 中的 HTTP 服务
开发人员按约定创建带有 /hs/lms 服务的扩展。
发布与检查
将服务发布到 Web 服务器,并使用 curl 命令检查。
在 LMS 中配置
管理员填写地址、路径和密钥,检查连接并启动同步。
自动同步
服务器管理员配置同步的定期调用。
免密登录
1С 生成签名链接,员工无需输入密码即可打开 LMS。
步骤 1. 在 1С 中创建 HTTP 服务
如果有多个库,需要在每个库上都创建该服务。服务应以配置扩展的形式实现,以免修改标准配置。服务的根 URL 为 lms,因此在 LMS 中其路径为 /hs/lms。也可以使用其他路径,只需在 LMS 设置中指定。
服务必须实现四个方法。所有响应均为 UTF-8 编码的 JSON。LMS 的每个请求都带有 X-API-Key 请求头。
| 方法 | 用途 |
|---|---|
GET /ping | 检查连接 |
GET /departments | 部门列表 |
GET /employees?limit=&offset= | 员工分页列表 |
POST /tasks | 创建、完成和删除培训任务 |
服务统计的是员工(自然人),而不是 1С 信息库的用户。请根据您配置中的人事数据提供员工。
GET /ping
返回任意不含 error 字段的有效 JSON。建议使用如下响应:
{ "ok": true }
GET /departments
部门树。id 字段是部门的稳定标识符(GUID),parent 是上级部门的标识符,根部门为空字符串。
{
"items": [
{ "id": "部门-guid", "name": "生产部", "parent": "上级-guid-或为空" }
]
}
GET /employees
员工分页列表。参数:limit(默认 100,最大 500)和 offset(默认 0)。如果还有下一页,请返回 "has_more": true。
{
"items": [
{
"id": "自然人-guid",
"tabNumber": "00123",
"lastName": "Иванов",
"firstName": "Иван",
"middleName": "Иванович",
"email": "ivanov@company.ru",
"position": "经理",
"departments": ["部门-guid"],
"active": true
}
],
"has_more": false
}
字段要求:
id——自然人的 GUID。它不应随时间变化,LMS 据此匹配员工。departments——来自/departments响应的标识符列表。active——在职员工为true,离职员工为false。要让 LMS 停用离职员工,请以active: false返回该员工。- 约定中没有“上级”字段。
- 每次同步 LMS 最多处理 5000 名员工。
POST /tasks
一个方法对应三种操作:action 字段取值为 add、complete 和 delete。
创建任务:
{
"action": "add",
"employee_id": "自然人-guid",
"title": "学习课程《劳动保护》",
"due_date": "2026-10-15",
"description": "...",
"url": "https://lms.company.ru/?programs=42"
}
对 add 请求,请返回所创建任务的标识符——LMS 会记住它:
{ "task_id": "1c-task-987" }
完成和删除任务:
{
"action": "complete",
"employee_id": "自然人-guid",
"task_id": "1c-task-987"
}
删除时,传入 "action": "delete" 及相同字段。
错误
如果请求无法执行,请返回带有 error 字段和清晰原因说明的 JSON。LMS 会向管理员显示操作失败。
步骤 2. 发布服务
- 使用 1С:Предприятие 平台的标准工具,将信息库发布到 Web 服务器(Apache 或 IIS)。
- 在发布文件
default.vrd中启用默认发布扩展:publishExtensionsByDefault="true"。 - 更新发布,并确认服务在如下地址响应:
https://<服务器>/<发布名称>/hs/lms/ping
该地址必须能从 LMS 所在的网络通过 HTTPS 访问。如果 1С 位于防火墙之后,请允许来自 LMS 服务器地址的访问。
步骤 3. 创建服务用户和密钥
- 在 1С 信息库中为集成创建专用用户。它必须是服务用户,而不是员工。
- 授予其使用 HTTP 服务
lms的权限。 - 设置访问密钥,服务会在
X-API-Key请求头中检查该密钥。您将在 LMS 中把它填为“API 密钥”。
请将密钥保存在安全的地方,不要发布在脚本和代码仓库中。
步骤 4. 使用 curl 命令检查服务
在配置 LMS 之前,请先确认服务正常运行。替换为您自己的地址和密钥:
curl -sS -H "X-API-Key: KEY" "https://<服务器>/<发布名称>/hs/lms/ping"
curl -sS -H "X-API-Key: KEY" "https://<服务器>/<发布名称>/hs/lms/departments"
curl -sS -H "X-API-Key: KEY" "https://<服务器>/<发布名称>/hs/lms/employees?limit=10&offset=0"
预期结果:
/ping返回无错误的有效 JSON;/departments在items字段中返回部门列表;/employees在items字段中返回前 10 名员工,其id、姓名和active均正确。
在这些请求得到响应之前,不建议继续在 LMS 中配置。
步骤 5. 在 LMS 中添加连接
- 打开设置 → 系统管理 → 集成 → 与 1С 集成,点击“添加连接”。
- 设置连接代码(slug)和公司名称。代码只能包含拉丁字母、数字、“-”和“_”,以字母或数字开头,例如
parnas。它会进入免密登录链接和内部寻址,因此创建后无法修改。 - 填写连接参数:
| 字段 | 填写内容 |
|---|---|
| 1С 发布地址 | 发布中的信息库地址,例如 https://1c.company.ru/zup |
| HTTP 服务路径 | 服务路径,默认为 /hs/lms |
| API 密钥 | 步骤 3 中服务用户的密钥 |
| SSO 密钥 | 用于签名该库登录链接的密钥(见步骤 7) |
- 点击“保存”,然后点击“检查”。如果连接正常,状态会变为“已连接”。
- 点击“同步”。结果中会显示计数:已创建、已更新、已停用,以及因席位上限而跳过的数量。
- 打开 LMS 用户列表,确认 1С 的员工和部门已加载。
- 对每家后续公司,重复步骤 1–4 以及本步骤。连接列表会同时显示所有公司及其配置状态。
密钥和 SSO 密钥保存后以隐藏形式显示。如需修改,请输入新值。
**整个门户共用的内容:**用户和档案、同一棵组织结构树以及套餐席位上限——所有公司共享一个席位池。
**每个连接独有的内容:**代码、地址、路径、API 密钥、SSO 密钥、“1С 员工 ↔ LMS 用户”的对应关系,以及在总组织结构树中的专属分支,因此不同公司的部门不会混合。
步骤 6. 启用自动同步
“同步”按钮用于手动为单个连接启动数据交换。要让人事数据自动更新,LMS 服务器管理员需配置定期调用。该调用为整个门户配置一次,而不是每家公司一次:一次调用会同步所有连接。
- 为计划任务生成密钥令牌:
openssl rand -hex 32
- 将其写入 LMS 服务器上的
include/onec.local.php文件。该文件依据模板include/onec.local.php.example创建:
<?php
return [
'ONEC_CRON_TOKEN' => '生成的令牌',
];
- 在计划任务(crontab)中添加每小时一次的调用。令牌通过
X-OneC-Cron-Token请求头传递:
0 * * * * curl -sS -X POST -H "X-OneC-Cron-Token: <令牌>" "https://<LMS主机>/api/onec-sync-cron"
如果令牌错误或未设置,LMS 会拒绝请求,同步不会启动。该令牌不是 1С 的 API 密钥:它是仅 LMS 服务器和计划任务知晓的独立密钥。
步骤 7. 配置免密登录
免密登录是反向工作的:链接由 1С 生成,而 LMS 使用链接中所指连接的密钥来验证其签名。
- 想出一个足够长的随机 SSO 密钥,并填入相应连接设置中的“SSO 密钥”字段。每个连接的密钥各不相同。
- 将相同的值交给对应 1С 库的开发人员。两端必须一致。
- 在 1С 一侧,按如下规则生成签名:
payload = connection + "|" + employee_id + "|" + ts
sig = HMAC-SHA256(payload, ssoSecret)
其中 connection 是步骤 5 中的连接代码,employee_id 是 /employees 响应中员工的 GUID,ts 是当前 Unix 时间(秒),sig 是十六进制字符串形式的签名。
- 拼装链接:
https://<LMS主机>/?onec=Y&connection=parnas&employee_id=自然人-guid&ts=1780000000&sig=<hex-hmac>
- 将链接放在员工打开培训的位置:表单、桌面或任务中。
需要注意:
- 连接代码是必填项,并包含在签名中,因此无法在不破坏签名的情况下将其替换为其他公司的代码。只有一个库时,它就是唯一创建的那个代码。
- 链接自时间
ts起有效期为 1 小时。请在员工打开链接时才生成,而不是提前生成。 - 1С 服务器和 LMS 服务器的时钟必须同步。
- 员工必须已通过该连接至少一次同步加载到 LMS 中,否则无法登录。
步骤 8. 1С 中的培训任务
任务无需单独设置。在“计划排期”板块为来自 1С 的员工分配课程时,LMS 会以 add 操作调用 POST /tasks,并记住返回的 task_id。如果有多个连接,LMS 会根据员工自行判断正确的库:同步时会为其打上连接标记,请求会发往该员工所来自的库。
在 1С 中实现该方法时的注意事项:
- 在 1С 中为指定
employee_id的员工创建任务,并在task_id字段中返回其标识符; - 并非来自 1С 的员工在此场景中会被跳过:课程分配不会中断;
- 请在服务中一并实现
complete和delete操作,尽管 LMS 目前不会自动调用它们。
结果验证
- 步骤 4 的三条 curl 命令返回正确的响应(每个库都要检查)。
- 每个连接的设置中状态为“已连接”,“检查”按钮通过。
- 点击“同步”后,“已创建”计数与预期员工数一致。
- 1С 的员工和部门在 LMS 中可见。
- 离职员工(
active: false)在下一次同步后被停用。 - 按计划的定期调用正常执行,“上次同步”时间已更新。
- 1С 生成的登录链接可打开员工的个人账户。
- 在计划排期中分配课程时,1С 中会出现任务。
常见问题排查
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| “检查”按钮报错 | 地址、路径或密钥错误;LMS 无法访问 1С | 检查发布地址、路径 /hs/lms 和密钥。在 LMS 服务器上执行 curl |
| 响应不是 JSON 格式 | 发布未加载扩展 | 检查 publishExtensionsByDefault="true" 并更新发布 |
| 员工列表为空 | 查询结果中没有员工,或服务用户没有数据权限 | 检查服务中的查询和用户权限 |
| 员工重复 | id 字段在调用之间发生变化 | 返回稳定的自然人 GUID |
| 员工未被停用 | 服务没有以 active: false 返回该员工 | 以 active: false 标志返回离职员工 |
| 部分员工未创建 | 套餐席位上限已用尽:它在整个门户内共用 | 查看“已跳过(席位上限)”计数并升级套餐 |
| 链接登录失败 | 密钥不一致、链接或签名中的连接代码错误、链接已过期、员工未同步 | 核对该连接的 SSO 密钥、connection、服务器时间,并执行同步 |
| 同一个人在 LMS 中出现两次 | 他同时登记在两个 1С 库中,每个库都创建了自己的账户 | 只在一个库中保留该员工 |
| 自动同步未启动 | 计划任务令牌未设置或错误 | 检查 ONEC_CRON_TOKEN 和 X-OneC-Cron-Token 请求头 |
| 同步未创建任务 | 员工并非来自 1С,或课程不是通过计划排期分配的 | 确认员工已通过同步加载,且课程是在“计划排期”中分配的 |