@sokeai/cli 1.0.21 → 1.0.25
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 +470 -14
- package/package.json +1 -1
- package/scripts/e2e-test.sh +38 -0
- package/scripts/link-skills.sh +203 -0
- package/scripts/local-test.js +503 -0
- package/scripts/local-test.sh +225 -0
- package/scripts/push.sh +0 -10
- package/skills/soke-learning-profile/SKILL.md +223 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# soke-cli 本地测试脚本
|
|
4
|
+
# 用于本地开发测试:编译 -> 安装到全局 -> 验证功能
|
|
5
|
+
|
|
6
|
+
# 颜色输出
|
|
7
|
+
RED='\033[0;31m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
YELLOW='\033[1;33m'
|
|
10
|
+
BLUE='\033[0;34m'
|
|
11
|
+
NC='\033[0m'
|
|
12
|
+
|
|
13
|
+
echo -e "${BLUE}========================================${NC}"
|
|
14
|
+
echo -e "${BLUE} soke-cli 本地测试${NC}"
|
|
15
|
+
echo -e "${BLUE}========================================${NC}"
|
|
16
|
+
echo ""
|
|
17
|
+
|
|
18
|
+
# 步骤1: 编译
|
|
19
|
+
echo -e "${YELLOW}[1/4] 编译 soke-cli...${NC}"
|
|
20
|
+
if go build -o soke-cli main.go; then
|
|
21
|
+
echo -e "${GREEN}✓ 编译成功${NC}"
|
|
22
|
+
else
|
|
23
|
+
echo -e "${RED}✗ 编译失败${NC}"
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# 步骤2: 检查本地版本功能
|
|
29
|
+
echo -e "${YELLOW}[2/4] 检查本地版本功能...${NC}"
|
|
30
|
+
echo -e " 检查 learning-profile 模块..."
|
|
31
|
+
if ./soke-cli learning-profile --help &>/dev/null; then
|
|
32
|
+
echo -e "${GREEN} ✓ learning-profile 模块存在${NC}"
|
|
33
|
+
else
|
|
34
|
+
echo -e "${RED} ✗ learning-profile 模块不存在${NC}"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo -e " 检查 contact +search-dept 命令..."
|
|
39
|
+
if ./soke-cli contact +search-dept --help &>/dev/null; then
|
|
40
|
+
echo -e "${GREEN} ✓ contact +search-dept 命令存在${NC}"
|
|
41
|
+
else
|
|
42
|
+
echo -e "${RED} ✗ contact +search-dept 命令不存在${NC}"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
# 步骤3: 安装到全局
|
|
48
|
+
echo -e "${YELLOW}[3/4] 安装到全局...${NC}"
|
|
49
|
+
|
|
50
|
+
# 查找全局 CLI 路径
|
|
51
|
+
GLOBAL_CLI=$(which soke-cli 2>/dev/null)
|
|
52
|
+
if [ -z "$GLOBAL_CLI" ]; then
|
|
53
|
+
echo -e "${YELLOW} 未找到全局 soke-cli 安装${NC}"
|
|
54
|
+
echo -e "${YELLOW} 请先通过 npm 安装: npm install -g @sokeai/cli${NC}"
|
|
55
|
+
echo -e "${YELLOW} 跳过全局安装,仅测试本地版本${NC}"
|
|
56
|
+
SKIP_GLOBAL=true
|
|
57
|
+
else
|
|
58
|
+
echo -e " 全局 CLI 路径: ${BLUE}${GLOBAL_CLI}${NC}"
|
|
59
|
+
|
|
60
|
+
# 检查是否需要更新
|
|
61
|
+
NEED_UPDATE=false
|
|
62
|
+
if ! $GLOBAL_CLI learning-profile --help &>/dev/null; then
|
|
63
|
+
echo -e "${YELLOW} 全局版本不支持 learning-profile 模块${NC}"
|
|
64
|
+
NEED_UPDATE=true
|
|
65
|
+
elif ! $GLOBAL_CLI contact +search-dept --help &>/dev/null; then
|
|
66
|
+
echo -e "${YELLOW} 全局版本不支持 contact +search-dept 命令${NC}"
|
|
67
|
+
NEED_UPDATE=true
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [ "$NEED_UPDATE" = true ]; then
|
|
71
|
+
echo -e "${YELLOW} 需要更新全局安装${NC}"
|
|
72
|
+
echo ""
|
|
73
|
+
echo -e "${YELLOW} 是否要用本地版本覆盖全局安装? (y/n)${NC}"
|
|
74
|
+
read -r CONFIRM
|
|
75
|
+
|
|
76
|
+
if [ "$CONFIRM" = "y" ] || [ "$CONFIRM" = "Y" ]; then
|
|
77
|
+
# 备份原文件
|
|
78
|
+
BACKUP_FILE="${GLOBAL_CLI}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
79
|
+
echo -e " 备份原文件到: ${BACKUP_FILE}"
|
|
80
|
+
if sudo cp $GLOBAL_CLI $BACKUP_FILE; then
|
|
81
|
+
echo -e "${GREEN} ✓ 备份成功${NC}"
|
|
82
|
+
else
|
|
83
|
+
echo -e "${RED} ✗ 备份失败${NC}"
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# 安装新版本
|
|
88
|
+
echo -e " 安装新版本..."
|
|
89
|
+
if sudo cp ./soke-cli $GLOBAL_CLI; then
|
|
90
|
+
echo -e "${GREEN} ✓ 安装成功${NC}"
|
|
91
|
+
echo -e "${BLUE} 备份文件: ${BACKUP_FILE}${NC}"
|
|
92
|
+
else
|
|
93
|
+
echo -e "${RED} ✗ 安装失败${NC}"
|
|
94
|
+
echo -e "${YELLOW} 恢复备份...${NC}"
|
|
95
|
+
sudo cp $BACKUP_FILE $GLOBAL_CLI
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
SKIP_GLOBAL=false
|
|
99
|
+
else
|
|
100
|
+
echo -e "${YELLOW} 跳过全局安装${NC}"
|
|
101
|
+
SKIP_GLOBAL=true
|
|
102
|
+
fi
|
|
103
|
+
else
|
|
104
|
+
echo -e "${GREEN} ✓ 全局版本已是最新,无需更新${NC}"
|
|
105
|
+
SKIP_GLOBAL=false
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
echo ""
|
|
109
|
+
|
|
110
|
+
# 步骤3.5: 分发 Skills 到本地 Agent
|
|
111
|
+
echo -e "${YELLOW}[3.5/4] 分发 Skills 到本地 Agent...${NC}"
|
|
112
|
+
if [ "$SKIP_GLOBAL" = false ]; then
|
|
113
|
+
echo -e " 执行 scripts/install.js 同步 Skills..."
|
|
114
|
+
# 注入特殊环境变量或者直接调用 node 执行
|
|
115
|
+
# 我们只想要触发 syncSkillsToSokeclawWorkspace 和 syncSkillsToWorkclawRegistry
|
|
116
|
+
# 但原 install.js 会尝试下载二进制文件,所以我们新建一个临时脚本或修改调用方式
|
|
117
|
+
|
|
118
|
+
# 为了安全起见,这里直接使用 node 运行一小段脚本引入 install.js 中的逻辑
|
|
119
|
+
cat > ./scripts/sync-skills-local.js << 'EOF'
|
|
120
|
+
const fs = require('fs');
|
|
121
|
+
const path = require('path');
|
|
122
|
+
const installCode = fs.readFileSync(path.join(__dirname, 'install.js'), 'utf8');
|
|
123
|
+
|
|
124
|
+
// 提取需要的函数
|
|
125
|
+
const syncFn1Match = installCode.match(/function syncSkillsToSokeclawWorkspace\(\) \{[\s\S]*?\n\}/);
|
|
126
|
+
const syncFn2Match = installCode.match(/function syncSkillsToWorkclawRegistry\(\) \{[\s\S]*?\n\}/);
|
|
127
|
+
|
|
128
|
+
// 我们更推荐直接利用已经写好的 js 模块(如果它是通过 module.exports 导出的)
|
|
129
|
+
// 但因为 install.js 是直接执行的脚本,我们通过简单的 node 脚本手动拷贝
|
|
130
|
+
const os = require('os');
|
|
131
|
+
function copyDirRecursive(srcDir, destDir) {
|
|
132
|
+
if (!fs.existsSync(srcDir)) return;
|
|
133
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
134
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
137
|
+
const destPath = path.join(destDir, entry.name);
|
|
138
|
+
if (entry.isDirectory()) { copyDirRecursive(srcPath, destPath); continue; }
|
|
139
|
+
fs.copyFileSync(srcPath, destPath);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const homeDir = os.homedir();
|
|
144
|
+
const defaultSokeclawDir = path.join(homeDir, '.sokeclaw', 'openai-agents', 'workspaces', 'main', 'skills');
|
|
145
|
+
const packageRoot = path.join(__dirname, '..');
|
|
146
|
+
const packagedSkillsDir = path.join(packageRoot, 'skills');
|
|
147
|
+
|
|
148
|
+
if (fs.existsSync(packagedSkillsDir)) {
|
|
149
|
+
const skillNames = fs.readdirSync(packagedSkillsDir).filter(n => n.startsWith('soke-'));
|
|
150
|
+
if (fs.existsSync(defaultSokeclawDir)) {
|
|
151
|
+
for (const skillName of skillNames) {
|
|
152
|
+
const src = path.join(packagedSkillsDir, skillName);
|
|
153
|
+
const dest = path.join(defaultSokeclawDir, skillName);
|
|
154
|
+
copyDirRecursive(src, dest);
|
|
155
|
+
console.log(` ✓ 同步 ${skillName} 到 ${dest}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
EOF
|
|
160
|
+
node ./scripts/sync-skills-local.js
|
|
161
|
+
rm ./scripts/sync-skills-local.js
|
|
162
|
+
echo -e "${GREEN} ✓ Skills 同步完成${NC}"
|
|
163
|
+
else
|
|
164
|
+
echo -e "${YELLOW} 跳过全局安装,同时跳过 Skills 同步${NC}"
|
|
165
|
+
fi
|
|
166
|
+
echo ""
|
|
167
|
+
|
|
168
|
+
# 步骤4: 运行功能测试
|
|
169
|
+
echo -e "${YELLOW}[4/4] 运行功能测试...${NC}"
|
|
170
|
+
|
|
171
|
+
# 测试本地版本
|
|
172
|
+
echo -e " ${BLUE}测试本地版本:${NC}"
|
|
173
|
+
if ./soke-cli learning-profile +list --help &>/dev/null; then
|
|
174
|
+
echo -e "${GREEN} ✓ learning-profile +list 命令可用${NC}"
|
|
175
|
+
else
|
|
176
|
+
echo -e "${RED} ✗ learning-profile +list 命令不可用${NC}"
|
|
177
|
+
exit 1
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
if ./soke-cli contact +search-dept --help &>/dev/null; then
|
|
181
|
+
echo -e "${GREEN} ✓ contact +search-dept 命令可用${NC}"
|
|
182
|
+
else
|
|
183
|
+
echo -e "${RED} ✗ contact +search-dept 命令不可用${NC}"
|
|
184
|
+
exit 1
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
if ./soke-cli contact +search-user --help &>/dev/null; then
|
|
188
|
+
echo -e "${GREEN} ✓ contact +search-user 命令可用${NC}"
|
|
189
|
+
else
|
|
190
|
+
echo -e "${RED} ✗ contact +search-user 命令不可用${NC}"
|
|
191
|
+
exit 1
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
# 测试全局版本(如果已安装)
|
|
195
|
+
if [ "$SKIP_GLOBAL" = false ] && [ -n "$GLOBAL_CLI" ]; then
|
|
196
|
+
echo ""
|
|
197
|
+
echo -e " ${BLUE}测试全局版本:${NC}"
|
|
198
|
+
if $GLOBAL_CLI learning-profile +list --help &>/dev/null; then
|
|
199
|
+
echo -e "${GREEN} ✓ learning-profile +list 命令可用${NC}"
|
|
200
|
+
else
|
|
201
|
+
echo -e "${RED} ✗ learning-profile +list 命令不可用${NC}"
|
|
202
|
+
echo -e "${YELLOW} 提示: 全局安装可能未成功更新${NC}"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
if $GLOBAL_CLI contact +search-dept --help &>/dev/null; then
|
|
206
|
+
echo -e "${GREEN} ✓ contact +search-dept 命令可用${NC}"
|
|
207
|
+
else
|
|
208
|
+
echo -e "${RED} ✗ contact +search-dept 命令不可用${NC}"
|
|
209
|
+
echo -e "${YELLOW} 提示: 全局安装可能未成功更新${NC}"
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
if $GLOBAL_CLI contact +search-user --help &>/dev/null; then
|
|
213
|
+
echo -e "${GREEN} ✓ contact +search-user 命令可用${NC}"
|
|
214
|
+
else
|
|
215
|
+
echo -e "${RED} ✗ contact +search-user 命令不可用${NC}"
|
|
216
|
+
echo -e "${YELLOW} 提示: 全局安装可能未成功更新${NC}"
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
echo ""
|
|
220
|
+
|
|
221
|
+
# 完成
|
|
222
|
+
echo -e "${GREEN}========================================${NC}"
|
|
223
|
+
echo -e "${GREEN} 本地测试完成! ✓${NC}"
|
|
224
|
+
echo -e "${GREEN}========================================${NC}"
|
|
225
|
+
|
package/scripts/push.sh
CHANGED
|
@@ -236,13 +236,3 @@ fi
|
|
|
236
236
|
|
|
237
237
|
echo " - Aliyun (origin): master 分支已更新"
|
|
238
238
|
echo " - GitHub (github): master 和 main 分支已更新"
|
|
239
|
-
|
|
240
|
-
if [[ "$IS_RELEASE" == true ]]; then
|
|
241
|
-
echo ""
|
|
242
|
-
print_highlight "📦 下一步操作:"
|
|
243
|
-
echo " 1. 编译二进制文件: make build"
|
|
244
|
-
echo " 2. 发布到 NPM: npm publish"
|
|
245
|
-
echo " 3. 创建 GitHub Release (可选)"
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
echo ""
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: soke-learning-profile
|
|
3
|
+
summary: 学员学习档案查询
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
description: "学员学习档案查询:查询学员的完整学习记录,包括课程学习、考试成绩、证书获取、学分积分等。当用户需要查询学员学习档案、查看学员学习情况、统计学员学习数据、查询学员综合学习信息时使用。"
|
|
6
|
+
metadata:
|
|
7
|
+
requires:
|
|
8
|
+
bins: ["soke-cli"]
|
|
9
|
+
cliHelp: "soke-cli learning-profile --help"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md),其中包含认证、配置、权限处理**
|
|
13
|
+
|
|
14
|
+
## 核心概念
|
|
15
|
+
|
|
16
|
+
- **LearningProfile(学习档案)**: 学员的完整学习记录,包含课程、考试、证书、培训等多维度数据
|
|
17
|
+
- **DeptUser(部门用户)**: 企业内的学员,通过 `dept_user_id` 标识
|
|
18
|
+
- **Department(部门)**: 组织架构单元,通过 `dept_id` 标识
|
|
19
|
+
|
|
20
|
+
## 资源关系
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
LearningProfile (学习档案)
|
|
24
|
+
├── DeptUser (学员)
|
|
25
|
+
│ ├── dept_user_id (学员ID)
|
|
26
|
+
│ ├── dept_user_name (学员姓名)
|
|
27
|
+
│ └── dept_names (所属部门)
|
|
28
|
+
├── CourseData (课程数据)
|
|
29
|
+
│ ├── required_learning/finished (必修课程)
|
|
30
|
+
│ ├── optional_learning/finished (选修课程)
|
|
31
|
+
│ └── learn_time (学习时长)
|
|
32
|
+
├── ExamData (考试数据)
|
|
33
|
+
│ ├── not_attempt (未开始)
|
|
34
|
+
│ ├── passed (通过)
|
|
35
|
+
│ ├── notpassed (未通过)
|
|
36
|
+
│ └── reviewing (批阅中)
|
|
37
|
+
├── CertificateData (证书数据)
|
|
38
|
+
│ └── certificate_number (证书数量)
|
|
39
|
+
├── PointsAndCredits (积分学分)
|
|
40
|
+
│ ├── points (积分)
|
|
41
|
+
│ └── credits (学分)
|
|
42
|
+
└── TrainingData (培训数据)
|
|
43
|
+
├── training_finished (线下培训)
|
|
44
|
+
├── learning_map_finished (学习地图)
|
|
45
|
+
└── training_class_finished (培训班)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Shortcuts(推荐优先使用)
|
|
49
|
+
|
|
50
|
+
| Shortcut | 说明 |
|
|
51
|
+
|----------|------|
|
|
52
|
+
| [`+list`](#list) | 查询学员学习档案列表 |
|
|
53
|
+
|
|
54
|
+
## 辅助命令(contact 模块)
|
|
55
|
+
|
|
56
|
+
| Shortcut | 说明 |
|
|
57
|
+
|----------|------|
|
|
58
|
+
| `contact +search-user` | 根据姓名搜索学员 |
|
|
59
|
+
| `contact +search-dept` | 根据名称搜索部门 |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 命令详解
|
|
64
|
+
|
|
65
|
+
### +list
|
|
66
|
+
|
|
67
|
+
查询学员学习档案列表,支持按部门、学员ID筛选。
|
|
68
|
+
|
|
69
|
+
**命令格式**:
|
|
70
|
+
```bash
|
|
71
|
+
soke-cli learning-profile +list \
|
|
72
|
+
[--dept-user-ids <user_id1,user_id2,...>] \
|
|
73
|
+
[--dept-ids <dept_id1,dept_id2,...>] \
|
|
74
|
+
[--is-new <0|1>] \
|
|
75
|
+
[--offset <offset>] \
|
|
76
|
+
[--page-size <size>]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**参数说明**:
|
|
80
|
+
- `--dept-user-ids`: 学员ID列表,多个ID用逗号分隔(可选)
|
|
81
|
+
- `--dept-ids`: 部门ID列表,多个ID用逗号分隔(可选)
|
|
82
|
+
- `--is-new`: 是否新员工,0-否,1-是(可选)
|
|
83
|
+
- `--offset`: 偏移量,默认从0开始(可选)
|
|
84
|
+
- `--page-size`: 每页条数,最大100,默认10(可选)
|
|
85
|
+
|
|
86
|
+
**返回字段**(表格显示关键字段):
|
|
87
|
+
- `姓名`: 学员姓名
|
|
88
|
+
- `部门`: 所属部门
|
|
89
|
+
- `职位`: 职位
|
|
90
|
+
- `必修完成`: 必修课程完成情况(完成数/总数)
|
|
91
|
+
- `选修完成`: 选修课程完成情况(完成数/总数)
|
|
92
|
+
- `考试通过`: 考试通过数
|
|
93
|
+
- `学习时长`: 学习时长(格式化为"X小时Y分钟")
|
|
94
|
+
- `证书数`: 获得证书数量
|
|
95
|
+
- `学分`: 学分
|
|
96
|
+
- `积分`: 积分
|
|
97
|
+
|
|
98
|
+
**JSON 输出包含完整字段**(30+ 字段):
|
|
99
|
+
- 基础信息:`dept_user_id`, `dept_user_name`, `dept_names`, `position`, `job_number`, `avatar`, `is_leave`, `hired_date`
|
|
100
|
+
- 课程学习:`optional_learning`, `optional_finished`, `required_learning`, `required_finished`, `learn_time`
|
|
101
|
+
- 考试情况:`not_attempt`, `passed`, `notpassed`, `reviewing`
|
|
102
|
+
- 证书积分:`certificate_number`, `points`, `credits`
|
|
103
|
+
- 培训情况:`training_not_attempt`, `training_finished`, `class_length`
|
|
104
|
+
- 学习地图:`leaning_map_attempt`, `learning_map_finished`
|
|
105
|
+
- 培训班:`training_class_attempt`, `training_class_finished`
|
|
106
|
+
- 其他:`live_learn_time`, `external_training_time`, `knowledge_number`, `evaluation_score`
|
|
107
|
+
|
|
108
|
+
**示例**:
|
|
109
|
+
```bash
|
|
110
|
+
# 查询所有学员学习档案
|
|
111
|
+
soke-cli learning-profile +list --offset 0 --page-size 20
|
|
112
|
+
|
|
113
|
+
# 查询特定学员(单个)
|
|
114
|
+
soke-cli learning-profile +list --dept-user-ids user123
|
|
115
|
+
|
|
116
|
+
# 查询多个学员
|
|
117
|
+
soke-cli learning-profile +list --dept-user-ids user123,user456,user789
|
|
118
|
+
|
|
119
|
+
# 查询特定部门的学员
|
|
120
|
+
soke-cli learning-profile +list --dept-ids dept456
|
|
121
|
+
|
|
122
|
+
# 查询多个部门的学员
|
|
123
|
+
soke-cli learning-profile +list --dept-ids dept456,dept789
|
|
124
|
+
|
|
125
|
+
# 查询新员工的学习档案
|
|
126
|
+
soke-cli learning-profile +list --is-new 1 --page-size 50
|
|
127
|
+
|
|
128
|
+
# 分页查询(使用 offset)
|
|
129
|
+
soke-cli learning-profile +list --offset 0 --page-size 10 # 第1页
|
|
130
|
+
soke-cli learning-profile +list --offset 10 --page-size 10 # 第2页
|
|
131
|
+
soke-cli learning-profile +list --offset 20 --page-size 10 # 第3页
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**权限要求**: `learningProfile:readonly`
|
|
135
|
+
|
|
136
|
+
**使用场景**:
|
|
137
|
+
- 当用户询问"查询学员学习档案"时使用
|
|
138
|
+
- 当用户需要查看学员学习情况、统计学习数据时使用
|
|
139
|
+
- 当用户需要导出学员学习报表时使用
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 权限表
|
|
144
|
+
|
|
145
|
+
| 命令 | 所需权限 | 说明 |
|
|
146
|
+
|------|----------|------|
|
|
147
|
+
| `+list` | `learningProfile:readonly` | 查询学员学习档案 |
|
|
148
|
+
| `contact +search-user` | `contact:user:readonly` | 搜索学员 |
|
|
149
|
+
| `contact +search-dept` | `contact:department:readonly` | 搜索部门 |
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 常见工作流
|
|
154
|
+
|
|
155
|
+
### 工作流1: 根据姓名查询学员学习档案
|
|
156
|
+
|
|
157
|
+
当用户询问"查询张三的学习档案"时:
|
|
158
|
+
|
|
159
|
+
**步骤1**: 搜索学员获取 dept_user_id
|
|
160
|
+
```bash
|
|
161
|
+
soke-cli contact +search-user --dept-user-name "张三"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**步骤2**: 使用 dept_user_id 查询学习档案
|
|
165
|
+
```bash
|
|
166
|
+
soke-cli learning-profile +list --dept-user-ids <从步骤1获取的dept_user_id>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**注意**: 学习档案接口不支持按姓名直接查询,必须先通过 contact 模块获取 dept_user_id。
|
|
170
|
+
|
|
171
|
+
### 工作流2: 查询部门所有学员的学习档案
|
|
172
|
+
|
|
173
|
+
当用户询问"查询技术部所有学员的学习情况"时:
|
|
174
|
+
|
|
175
|
+
**步骤1**: 搜索部门获取 dept_id
|
|
176
|
+
```bash
|
|
177
|
+
soke-cli contact +search-dept --dept-name "技术部"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**步骤2**: 使用 dept_id 查询该部门学员学习档案
|
|
181
|
+
```bash
|
|
182
|
+
soke-cli learning-profile +list --dept-ids <从步骤1获取的dept_id> --page-size 100
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 工作流3: 批量导出学习档案
|
|
186
|
+
|
|
187
|
+
当用户需要导出学习档案数据时:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# 使用 JSON 格式输出并保存到文件
|
|
191
|
+
soke-cli learning-profile +list --page-size 100 --format json > learning_profiles.json
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 注意事项
|
|
197
|
+
|
|
198
|
+
1. **时间格式**: `learn_time`, `class_length` 等时长字段单位为秒,表格输出时会自动格式化为"X小时Y分钟"
|
|
199
|
+
2. **分页**: 使用 `offset` 和 `page_size` 进行分页,默认每页10条,最大100条
|
|
200
|
+
3. **数组参数**: `dept_user_ids` 和 `dept_ids` 是数组类型,多个ID用逗号分隔
|
|
201
|
+
4. **姓名查询**: 学习档案接口不支持按姓名查询,需要先通过 `contact +search-user` 获取 dept_user_id
|
|
202
|
+
5. **权限**: 需要 `learningProfile:readonly` 权限,如遇权限错误参考 soke-shared
|
|
203
|
+
6. **数据完整性**: 表格输出仅显示关键字段,完整数据请使用 `--format json`
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 错误处理
|
|
208
|
+
|
|
209
|
+
### 权限不足
|
|
210
|
+
如果遇到权限错误,参考 [`../soke-shared/SKILL.md`](../soke-shared/SKILL.md)
|
|
211
|
+
|
|
212
|
+
### 参数错误
|
|
213
|
+
使用 `--help` 查看命令参数说明:
|
|
214
|
+
```bash
|
|
215
|
+
soke-cli learning-profile +list --help
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 数据为空
|
|
219
|
+
如果查询结果为空,检查:
|
|
220
|
+
1. 筛选条件是否正确(dept_ids, dept_user_ids, is_new)
|
|
221
|
+
2. 学员是否有学习记录
|
|
222
|
+
3. 是否有权限查看该部门/学员的数据
|
|
223
|
+
4. 注意:学习档案接口不支持按姓名查询,需要先获取 dept_user_id
|