@xbongbong/xbbcli 2.4.1 → 2.4.2
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 +19 -4
- package/auth-login.js +1 -1
- package/auth-logout.js +4 -5
- package/auth-refresh-cache.js +117 -0
- package/package.json +1 -1
- package/xbb-token-store.js +84 -13
package/README.md
CHANGED
|
@@ -98,6 +98,20 @@ xbbcli auth-login --keepOpen # 登录成功后保留浏览器窗口(默
|
|
|
98
98
|
- `--debug` 输出请求体、返回体与浏览器信息(密钥只显示掩码),`--raw` 输出换取 API token 接口的原始响应
|
|
99
99
|
- 失败时返回合成错误行:`NO_BROWSER`、`BROWSER_CLOSED`、`LOGIN_TIMEOUT`、`API_TOKEN_FAILED`、`CORPID_MISMATCH`、`SAVE_FAILED` 等
|
|
100
100
|
|
|
101
|
+
### 刷新本地缓存(auth-refresh-cache)
|
|
102
|
+
|
|
103
|
+
`token-set` / `auth-login` 保存凭证时会顺带刷新三份本地缓存。插件升级(新增命令导致命令映射变化)、缓存过期或被删除后,可以单独重刷,不需要重新输入 token:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
xbbcli auth-refresh-cache -f json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- 刷新范围(仅当前启用公司):`~/.xbbcli/<corpid>.formlist.json`(表单清单)、`~/.xbbcli/<corpid>.command-map.md`(命令映射)、`~/.xbbcli/<corpid>.department-user.json`(部门/员工清单),并把 `corpName` / `userName` 回填进 `config.env`
|
|
110
|
+
- 环境变量模式(`XBB_*`)下同样可用:只刷新缓存文件,不回填 `config.env`
|
|
111
|
+
- 只支持当前启用公司:底层接口一律使用启用公司的凭证,切换公司请先用 `xbbcli token-use`
|
|
112
|
+
- `--userId` 覆盖用于匹配 `userName` 的员工 id(默认取配置里的 `userId`);`--debug` 在 stderr 输出配置来源、corpid 与三份缓存文件路径
|
|
113
|
+
- 失败时返回 `status=error`、`code=CACHE_REFRESH_FAILED`,`message` 以「步骤 formlist / command-map / department-user / profile」指出中断位置,已完成的部分照常在对应列输出
|
|
114
|
+
|
|
101
115
|
`token-set` 会按 `corpid` 新增或覆盖一家公司,并把该公司置为 `enable=true`(其余公司自动置为 `false`),同时写入公司名称 `corpName`(取部门 `id` 为 `1` 的部门名称)和操作人姓名 `userName`(从员工列表中按 `userId` 匹配)。除 `token-set`、`token-list`、`token-use`、`token-del`、`auth-status`、`auth-logout` 外,其余命令都使用 `enable` 为 `true` 的公司配置。
|
|
102
116
|
|
|
103
117
|
同时会自动拉取两份表单清单并合并缓存到:
|
|
@@ -145,7 +159,7 @@ xbbcli user-list --pageSize 200 -f json
|
|
|
145
159
|
xbbcli auth-status # 回显当前激活的配置(token 默认掩码)
|
|
146
160
|
xbbcli auth-status --showToken # 需要完整 token 时
|
|
147
161
|
xbbcli auth-logout # 登出:删除激活的那一家配置 + 清除 XBB_* 环境变量
|
|
148
|
-
xbbcli auth-logout --
|
|
162
|
+
xbbcli auth-logout --env 0 # 只删 config.env,保留环境变量
|
|
149
163
|
```
|
|
150
164
|
|
|
151
165
|
- `auth-status` 以 `key` / `value` 两列回显当前生效的配置值,固定 6 行:`corpid`、`corpName`、`userName`、`userId`、`baseurl`、`token`;不再输出 `status`、`source`、`message`、`enable`、`companyCount`、`envActive`、`configFile`、`code`、`msg` 这些元信息列。
|
|
@@ -166,7 +180,7 @@ note 以上取值来自环境变量 XBB_*(config.env 中没有启用公
|
|
|
166
180
|
- `auth-status` 默认把 token 掩码为「前 6 + `***` + 后 4」(长度不足 11 时只保留前 2 位),只有 `--showToken` 才输出明文。
|
|
167
181
|
- `auth-logout` 只删除 `enable=true` 的那一条,**不会**把其他公司自动提升为启用:登出后本地可能一个启用公司都没有,需要 `xbbcli token-use --corpid <CORPID>` 或重新 `auth-login` / `token-set`。想保留其他公司并可切换时,用 `xbbcli token-del --corpid <CORPID>`(它会保证剩余配置仍有且仅有一个启用)。
|
|
168
182
|
- 删除前 `config.env` 会整份备份到 `~/.xbbcli/config.env.bak`(每次登出覆盖),`backupFile` 列给出路径;误删把 `.bak` 复制回 `config.env` 即可恢复。
|
|
169
|
-
- 默认**同时**清除 `XBB_*` 环境变量:Windows 用 `reg delete HKCU\Environment` 删除用户级变量(已打开的终端要重开才生效,`envStored` 为 `user`,原本就不存在时为 `none`);macOS/Linux 清理 `~/.xbbcli/env.sh` 里的 `export XBB_*` 行(文件清空则删除,`envStored` 为 `cleared` / `removed` / `none
|
|
183
|
+
- 默认**同时**清除 `XBB_*` 环境变量:Windows 用 `reg delete HKCU\Environment` 删除用户级变量(已打开的终端要重开才生效,`envStored` 为 `user`,原本就不存在时为 `none`);macOS/Linux 清理 `~/.xbbcli/env.sh` 里的 `export XBB_*` 行(文件清空则删除,`envStored` 为 `cleared` / `removed` / `none`)。传 `--env 0` 时只删 `config.env`,此时若环境变量仍在,`message` 会提示「业务命令会回落到它,本次不算彻底登出」(`XBB_ENV_ONLY=1` 时提示为「已强制只用环境变量」)。
|
|
170
184
|
- `config.env` 没有启用公司时:只有在环境变量确实存在时才只清环境变量(`config.env` 保持不动);两者都不存在则返回 `NO_ACTIVE_CONFIG`,不写任何文件。
|
|
171
185
|
- 任何情况都不改动 `<corpid>.formlist.json` / `<corpid>.command-map.md` / `<corpid>.department-user.json` 三份缓存,重新启用该公司时无需再次拉取。
|
|
172
186
|
|
|
@@ -204,7 +218,8 @@ note 以上取值来自环境变量 XBB_*(config.env 中没有启用公
|
|
|
204
218
|
|
|
205
219
|
- `auth-login`:拉起本地浏览器完成交互式登录(账号密码 / 短信 / 扫码均可),自动读取 Web 会话、换取 API token 并复用 `token-set` 落盘;支持 `--browser`、`--timeout`、`--corpid`、`--keepOpen`、`--env`、`--debug`、`--raw`
|
|
206
220
|
- `auth-status`:以 `key` / `value` 两列回显当前激活配置的 `corpid`、`corpName`、`userName`、`userId`、`baseurl`、`token`(token 默认中间掩码,`--showToken` 出明文),来源与冲突提醒以 `note` 行追加,无生效配置时六个值留空并给出 `note`;`--debug` 在 stderr 输出配置文件路径、公司数量与生效的环境变量名
|
|
207
|
-
- `auth-logout`:删除 `config.env` 中 `enable=true` 的那一条配置,删除前整份备份为 `~/.xbbcli/config.env.bak`;不自动把其他公司提升为启用;默认同时清除 `XBB_*` 环境变量(`--
|
|
221
|
+
- `auth-logout`:删除 `config.env` 中 `enable=true` 的那一条配置,删除前整份备份为 `~/.xbbcli/config.env.bak`;不自动把其他公司提升为启用;默认同时清除 `XBB_*` 环境变量(`--env 0` 跳过,返回 `envStored` / `envFile`);既无启用公司又无环境变量时返回 `NO_ACTIVE_CONFIG` 且不改动文件
|
|
222
|
+
- `auth-refresh-cache`:对当前启用公司重新拉取表单缓存、命令映射与部门/员工缓存,并回填 `corpName` / `userName`;失败时返回 `code=CACHE_REFRESH_FAILED`,`message` 注明中断步骤(`formlist` / `command-map` / `department-user` / `profile`),已完成的部分照常输出;支持 `--userId`、`--debug`
|
|
208
223
|
- `token-set`:保存个人 token、`corpid`、`userId`、`baseurl`,并刷新本地表单缓存、命令映射文件与部门/员工缓存;传入的 token 不以 `user_` 开头时,会先为该 `userId` 刷新并保存个人 token;`--env` 控制存储方式:`0`(默认)仅写入本地文件,`1` 仅写入 `XBB_*` 环境变量(Windows 用 `setx`,其他平台写 `~/.xbbcli/env.sh`)且不写任何本地文件;返回 `envStored` / `envFile` 两列
|
|
209
224
|
- `token-list`:列出本地保存的所有公司配置和唯一启用的公司(含 `corpName` 公司名称与 `userName` 操作人姓名,`source` 列标记来源 `config`/`env`);`--showToken` 显示完整 token(默认脱敏);环境变量模式下单行显示
|
|
210
225
|
- `token-use`:切换当前启用的公司(`xbbcli token-use --corpid <CORPID>`),保证仅且只有一个公司被启用
|
|
@@ -452,7 +467,7 @@ note 以上取值来自环境变量 XBB_*(config.env 中没有启用公
|
|
|
452
467
|
## 通用行为
|
|
453
468
|
|
|
454
469
|
- 先执行一次 `token-set`(或 `auth-login`)保存有效的 `corpid`、`token`、`userId`
|
|
455
|
-
- 用 `xbbcli auth-status` 查看当前生效的配置来自 `config.env` 还是环境变量;`xbbcli auth-logout` 删除激活配置并默认清除 `XBB_*` 环境变量(`--
|
|
470
|
+
- 用 `xbbcli auth-status` 查看当前生效的配置来自 `config.env` 还是环境变量;`xbbcli auth-logout` 删除激活配置并默认清除 `XBB_*` 环境变量(`--env 0` 保留)
|
|
456
471
|
- 除 `token-set` 外,其余命令都会从 `~/.xbbcli/config.env` 读取 `corpid`
|
|
457
472
|
- 大部分命令会从 `~/.xbbcli/config.env` 读取 `token`
|
|
458
473
|
- 未配置 `config.env`(或其中没有启用公司)时,命令会回落到 `XBB_CORPID` / `XBB_TOKEN` / `XBB_BASEURL` / `XBB_USERID` / `XBB_CORPNAME` / `XBB_USERNAME` 环境变量;`XBB_ENV_ONLY=1` 可强制只用环境变量
|
package/auth-login.js
CHANGED
package/auth-logout.js
CHANGED
|
@@ -61,7 +61,7 @@ function previewCorpids(companies) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
async function authLogout(kwargs) {
|
|
64
|
-
const alsoEnv =
|
|
64
|
+
const alsoEnv = String(kwargs.env ?? '1').trim() !== '0';
|
|
65
65
|
const companies = readCompanies();
|
|
66
66
|
const index = companies.findIndex((item) => item && item.enable === true);
|
|
67
67
|
const envPresent = hasEnvConfig();
|
|
@@ -76,7 +76,7 @@ async function authLogout(kwargs) {
|
|
|
76
76
|
? `本地共 ${companies.length} 家公司(${previewCorpids(companies)})且均未启用;要登出某家请先用 xbbcli token-use --corpid <CORPID> 启用,或改用 xbbcli token-del --corpid <CORPID> 直接删除`
|
|
77
77
|
: '本地没有任何公司配置';
|
|
78
78
|
const envNote = envPresent
|
|
79
|
-
? '环境变量 XBB_*
|
|
79
|
+
? '环境变量 XBB_* 仍存在,本次未清除(用 --env 1 或不指定该参数即可一并清除)'
|
|
80
80
|
: '环境变量 XBB_* 也不存在,本次无可清除内容';
|
|
81
81
|
const hint = `${scope};${envNote}`;
|
|
82
82
|
return createRow({
|
|
@@ -139,7 +139,7 @@ async function authLogout(kwargs) {
|
|
|
139
139
|
}
|
|
140
140
|
} else if (envBefore) {
|
|
141
141
|
const forced = isEnvOnly() ? '且 XBB_ENV_ONLY=1 已强制只用环境变量' : '业务命令会回落到它';
|
|
142
|
-
parts.push(`注意:环境变量 XBB_*(corpid=${envBefore})仍然有效,${forced}
|
|
142
|
+
parts.push(`注意:环境变量 XBB_*(corpid=${envBefore})仍然有效,${forced},本次不算彻底登出;如需一并清除请改用 --env 1(或不指定该参数,auth-logout 默认会清除环境变量)`);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
const remainingCompanies = target ? remaining : readCompanies();
|
|
@@ -166,8 +166,7 @@ cli({
|
|
|
166
166
|
browser: false,
|
|
167
167
|
domain: 'proapi.xbongbong.com',
|
|
168
168
|
args: [
|
|
169
|
-
{ name: 'env', type: '
|
|
170
|
-
{ name: 'noEnv', type: 'bool', default: false, help: '不清除环境变量,仅删除 config.env 中的激活配置(等价于 --env=false)' },
|
|
169
|
+
{ name: 'env', type: 'str', default: '1', help: '是否同时清除 XBB_* 环境变量:1 清除(默认),0 仅删除 config.env 保留环境变量。Windows 删除用户级变量,其他平台清理 ~/.xbbcli/env.sh' },
|
|
171
170
|
{ name: 'debug', type: 'bool', default: false, help: '输出配置文件、备份路径与生效的环境变量名(不打印 token)' },
|
|
172
171
|
],
|
|
173
172
|
columns: ['status', 'message', 'configFile', 'backupFile', 'corpid', 'corpName', 'userId', 'companyCount', 'hasActive', 'envStored', 'envFile', 'code', 'msg'],
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { cli, Strategy } from './xbb-registry.js';
|
|
2
|
+
import { readActiveConfig, isEnvActive } from './xbb-config.js';
|
|
3
|
+
import {
|
|
4
|
+
refreshLocalCaches,
|
|
5
|
+
getFormlistFile,
|
|
6
|
+
getCommandMapFile,
|
|
7
|
+
getDepartmentUserFile,
|
|
8
|
+
} from './xbb-token-store.js';
|
|
9
|
+
|
|
10
|
+
function trim(value) {
|
|
11
|
+
return String(value ?? '').trim();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 统一输出:成功时给出三份缓存与回填结果,失败时回落到合成错误行(不抛异常)
|
|
15
|
+
function makeRow(fields) {
|
|
16
|
+
return [{
|
|
17
|
+
status: '',
|
|
18
|
+
message: '',
|
|
19
|
+
corpid: '',
|
|
20
|
+
userId: '',
|
|
21
|
+
corpName: '',
|
|
22
|
+
userName: '',
|
|
23
|
+
formlistFile: '',
|
|
24
|
+
formlistCount: '',
|
|
25
|
+
commandMapFile: '',
|
|
26
|
+
departmentUserFile: '',
|
|
27
|
+
departmentCount: '',
|
|
28
|
+
userCount: '',
|
|
29
|
+
profileUpdated: '',
|
|
30
|
+
code: '',
|
|
31
|
+
msg: '',
|
|
32
|
+
...fields,
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function makeErrorRow(code, msg, extra = {}) {
|
|
37
|
+
return makeRow({ status: 'error', code, msg, message: msg, ...extra });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function authRefreshCache(kwargs) {
|
|
41
|
+
const active = readActiveConfig();
|
|
42
|
+
const corpid = trim(active.corpid);
|
|
43
|
+
const userId = trim(kwargs.userId) || trim(active.userId);
|
|
44
|
+
|
|
45
|
+
if (kwargs.debug) {
|
|
46
|
+
const source = isEnvActive() ? 'env' : 'config';
|
|
47
|
+
process.stderr.write(`[debug] ConfigSource: ${source}\n[debug] Corpid: ${corpid || '(none)'}\n[debug] UserId: ${userId || '(none)'}\n[debug] FormlistFile: ${corpid ? getFormlistFile(corpid) : ''}\n[debug] CommandMapFile: ${corpid ? getCommandMapFile(corpid) : ''}\n[debug] DepartmentUserFile: ${corpid ? getDepartmentUserFile(corpid) : ''}\n`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!corpid) {
|
|
51
|
+
return makeErrorRow('NO_ACTIVE_CONFIG', '没有生效的配置:config.env 中不存在 enable=true 的公司,环境变量 XBB_* 也为空;请先执行 xbbcli auth-login 或 xbbcli token-set');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let cache;
|
|
55
|
+
try {
|
|
56
|
+
cache = await refreshLocalCaches(corpid, userId);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
const partial = error.cache || {};
|
|
59
|
+
const step = trim(error.step) || 'unknown';
|
|
60
|
+
const message = `刷新本地缓存失败(步骤 ${step}):${error.message || error}`;
|
|
61
|
+
return makeRow({
|
|
62
|
+
status: 'error',
|
|
63
|
+
code: 'CACHE_REFRESH_FAILED',
|
|
64
|
+
msg: message,
|
|
65
|
+
message,
|
|
66
|
+
corpid,
|
|
67
|
+
userId,
|
|
68
|
+
corpName: partial.corpName ?? '',
|
|
69
|
+
userName: partial.userName ?? '',
|
|
70
|
+
formlistFile: partial.formlistFile ?? '',
|
|
71
|
+
formlistCount: partial.formlistCount ?? '',
|
|
72
|
+
commandMapFile: partial.commandMapFile ?? '',
|
|
73
|
+
departmentUserFile: partial.departmentUserFile ?? '',
|
|
74
|
+
departmentCount: partial.departmentCount ?? '',
|
|
75
|
+
userCount: partial.userCount ?? '',
|
|
76
|
+
profileUpdated: partial.profileUpdated ?? '',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const message = cache.profileUpdated
|
|
81
|
+
? '已刷新表单清单缓存、命令映射与部门/员工缓存,并回填 corpName/userName 到 config.env'
|
|
82
|
+
: isEnvActive()
|
|
83
|
+
? '已刷新表单清单缓存、命令映射与部门/员工缓存;当前为环境变量模式,corpName/userName 未回填 config.env'
|
|
84
|
+
: '已刷新表单清单缓存、命令映射与部门/员工缓存;该公司不在 config.env 中,corpName/userName 未回填';
|
|
85
|
+
|
|
86
|
+
return makeRow({
|
|
87
|
+
status: 'ok',
|
|
88
|
+
message,
|
|
89
|
+
corpid,
|
|
90
|
+
userId,
|
|
91
|
+
corpName: cache.corpName,
|
|
92
|
+
userName: cache.userName,
|
|
93
|
+
formlistFile: cache.formlistFile,
|
|
94
|
+
formlistCount: cache.formlistCount,
|
|
95
|
+
commandMapFile: cache.commandMapFile,
|
|
96
|
+
departmentUserFile: cache.departmentUserFile,
|
|
97
|
+
departmentCount: cache.departmentCount,
|
|
98
|
+
userCount: cache.userCount,
|
|
99
|
+
profileUpdated: cache.profileUpdated,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
cli({
|
|
104
|
+
site: 'xbb',
|
|
105
|
+
name: 'auth-refresh-cache',
|
|
106
|
+
description: '刷新当前启用公司的本地缓存(表单清单、命令映射等)',
|
|
107
|
+
strategy: Strategy.PUBLIC,
|
|
108
|
+
access: 'write',
|
|
109
|
+
browser: false,
|
|
110
|
+
domain: 'proapi.xbongbong.com',
|
|
111
|
+
args: [
|
|
112
|
+
{ name: 'userId', type: 'str', default: '', help: '操作人 id,用于从员工清单匹配 userName;默认取当前启用配置的 userId' },
|
|
113
|
+
{ name: 'debug', type: 'bool', default: false, help: '在 stderr 输出配置来源、corpid 与三份缓存文件路径' },
|
|
114
|
+
],
|
|
115
|
+
columns: ['status', 'message', 'corpid', 'userId', 'corpName', 'userName', 'formlistFile', 'formlistCount', 'commandMapFile', 'departmentUserFile', 'departmentCount', 'userCount', 'profileUpdated', 'code', 'msg'],
|
|
116
|
+
func: authRefreshCache,
|
|
117
|
+
});
|
package/package.json
CHANGED
package/xbb-token-store.js
CHANGED
|
@@ -109,7 +109,7 @@ async function writeFormlistFile(corpid) {
|
|
|
109
109
|
const mergedRows = [...customForms, ...systemForms];
|
|
110
110
|
|
|
111
111
|
fs.writeFileSync(formlistFile, JSON.stringify(mergedRows, null, 2) + '\n', 'utf8');
|
|
112
|
-
return formlistFile;
|
|
112
|
+
return { file: formlistFile, count: mergedRows.length };
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
async function fetchAllRows(name, pageSize) {
|
|
@@ -178,7 +178,7 @@ async function writeDepartmentUserFile(corpid, userId) {
|
|
|
178
178
|
const file = getDepartmentUserFile(corpid);
|
|
179
179
|
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
180
180
|
fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n', 'utf8');
|
|
181
|
-
return { file, corpName: getCorpName(departmentRows), userName: getUserName(userRows, userId) };
|
|
181
|
+
return { file, corpName: getCorpName(departmentRows), userName: getUserName(userRows, userId), departmentCount: departmentRows.length, userCount: userRows.length };
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
function getCorpName(departmentRows) {
|
|
@@ -196,16 +196,89 @@ function getUserName(userRows, userId) {
|
|
|
196
196
|
return matched ? String(matched.name || '').trim() : '';
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
// 把 corpName / userName 合并进 config.env 对应公司,返回是否真的写过文件
|
|
200
|
+
// config.env 里没有这家公司的条目时(纯环境变量模式)直接跳过,避免凭空生成一份只有 corpName 的 config.env
|
|
199
201
|
export function writeCompanyProfile(corpid, profile) {
|
|
202
|
+
const target = String(corpid || '').trim();
|
|
200
203
|
const fields = Object.entries(profile).filter(([, value]) => String(value || '').trim() !== '');
|
|
201
|
-
if (!fields.length) {
|
|
202
|
-
return;
|
|
204
|
+
if (!target || !fields.length) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const companies = readCompanies();
|
|
208
|
+
const index = companies.findIndex((item) => String(item.corpid || '').trim() === target);
|
|
209
|
+
if (index === -1) {
|
|
210
|
+
return false;
|
|
203
211
|
}
|
|
204
212
|
const patch = Object.fromEntries(fields);
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
213
|
+
const next = companies.map((item, itemIndex) => (itemIndex === index ? { ...item, ...patch } : item));
|
|
214
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(next, null, 2) + '\n', 'utf8');
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// token-set / auth-login / auth-refresh-cache 共用:刷新三份本地缓存并回填 corpName、userName
|
|
219
|
+
// 失败时抛出的 error 上带 step(formlist/command-map/department-user/profile)与已完成部分的 cache,便于命令回显进度
|
|
220
|
+
export async function refreshLocalCaches(corpid, userId) {
|
|
221
|
+
const target = String(corpid || '').trim();
|
|
222
|
+
if (!target) {
|
|
223
|
+
const error = new Error('缺少 corpid,无法确定要刷新哪家公司的缓存');
|
|
224
|
+
error.step = 'formlist';
|
|
225
|
+
error.cache = { formlistFile: '', commandMapFile: '', departmentUserFile: '', formlistCount: '', departmentCount: '', userCount: '', corpName: '', userName: '', profileUpdated: false };
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
const cache = {
|
|
229
|
+
formlistFile: getFormlistFile(target),
|
|
230
|
+
commandMapFile: '',
|
|
231
|
+
departmentUserFile: '',
|
|
232
|
+
formlistCount: '',
|
|
233
|
+
departmentCount: '',
|
|
234
|
+
userCount: '',
|
|
235
|
+
corpName: '',
|
|
236
|
+
userName: '',
|
|
237
|
+
profileUpdated: false,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
const formlist = await writeFormlistFile(target);
|
|
244
|
+
cache.formlistFile = formlist.file;
|
|
245
|
+
cache.formlistCount = formlist.count;
|
|
246
|
+
} catch (error) {
|
|
247
|
+
error.step = 'formlist';
|
|
248
|
+
error.cache = cache;
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
cache.commandMapFile = writeCommandMap(target);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
error.step = 'command-map';
|
|
256
|
+
error.cache = cache;
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
const departmentUser = await writeDepartmentUserFile(target, userId);
|
|
262
|
+
cache.departmentUserFile = departmentUser.file;
|
|
263
|
+
cache.corpName = departmentUser.corpName;
|
|
264
|
+
cache.userName = departmentUser.userName;
|
|
265
|
+
cache.departmentCount = departmentUser.departmentCount;
|
|
266
|
+
cache.userCount = departmentUser.userCount;
|
|
267
|
+
} catch (error) {
|
|
268
|
+
error.step = 'department-user';
|
|
269
|
+
error.cache = cache;
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
cache.profileUpdated = writeCompanyProfile(target, { corpName: cache.corpName, userName: cache.userName });
|
|
275
|
+
} catch (error) {
|
|
276
|
+
error.step = 'profile';
|
|
277
|
+
error.cache = cache;
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return cache;
|
|
209
282
|
}
|
|
210
283
|
|
|
211
284
|
function normalizeBusinessType(value) {
|
|
@@ -373,15 +446,13 @@ export async function saveCompanyCredentials(kwargs) {
|
|
|
373
446
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(companies, null, 2) + '\n', 'utf8');
|
|
374
447
|
|
|
375
448
|
try {
|
|
376
|
-
const
|
|
377
|
-
const commandMapFile =
|
|
378
|
-
const { file: departmentUserFile, corpName, userName } = await writeDepartmentUserFile(corpid, userId);
|
|
379
|
-
writeCompanyProfile(corpid, { corpName, userName });
|
|
449
|
+
const cache = await refreshLocalCaches(corpid, userId);
|
|
450
|
+
const { formlistFile, commandMapFile, departmentUserFile, corpName, userName } = cache;
|
|
380
451
|
return createResult('ok', '已保存 corpid、token、baseurl、userId,并同步表单模板缓存、命令映射文件与部门/员工缓存', corpid, baseurl, userId, formlistFile, commandMapFile, true, companies.length, departmentUserFile, corpName, userName, 'skipped', '');
|
|
381
452
|
} catch (error) {
|
|
382
453
|
return createResult(
|
|
383
454
|
'partial',
|
|
384
|
-
`已保存 corpid、token、baseurl、userId
|
|
455
|
+
`已保存 corpid、token、baseurl、userId,但同步缓存失败${error.step ? `(步骤 ${error.step})` : ''}:${error.message}`,
|
|
385
456
|
corpid,
|
|
386
457
|
baseurl,
|
|
387
458
|
userId,
|