diff --git a/account-service/README.md b/account-service/README.md
index fb5c90f..e07e18f 100644
--- a/account-service/README.md
+++ b/account-service/README.md
@@ -39,6 +39,7 @@ POST /api/login
| POST | `/api/admin/disable` | 停用 `{staffNo}`,立即无法登录并被踢下线 |
| POST | `/api/admin/enable` | 启用 `{staffNo}` |
| POST | `/api/admin/reset_password` | 重置密码 `{staffNo, password}` |
+| POST | `/api/admin/delete` | 删除 `{staffNo}`,立即无法登录并被踢下线(OpenIM 侧同名用户保留但本服务不再为其签发令牌,等于不可用) |
管理页:浏览器打开 `http://<服务器IP>:10010/`,输入管理口令即可操作,无需写接口。
diff --git a/account-service/admin.html b/account-service/admin.html
index f564735..dda615c 100644
--- a/account-service/admin.html
+++ b/account-service/admin.html
@@ -54,7 +54,9 @@
支持逗号或 Tab 分隔(Excel 复制出来直接粘贴即可);重复工号会覆盖原账号(姓名与密码重置、状态恢复为启用)。
+
+
@@ -110,6 +112,7 @@ async function loadList() {
? ``
: ``}
+
`).join('') || '| 暂无员工,请先导入 |
';
} catch (e) { show(e.message, false); }
@@ -151,6 +154,30 @@ async function doImport() {
} catch (e) { show(e.message, false); }
}
+// 直接选择模板 CSV 文件导入,不用复制粘贴
+async function importFile(input) {
+ const file = input.files[0];
+ input.value = '';
+ if (!file) return;
+ try {
+ let text = await file.text();
+ if (text.charCodeAt(0) === 0xFEFF) text = text.slice(1); // 去 BOM
+ const d = await api('/api/admin/import', { csv: text });
+ const bad = d.results.filter(r => !r.ok);
+ show('文件「' + file.name + '」导入完成:成功 ' + d.imported + ' / ' + d.total + (bad.length ? '\n失败明细:\n' + bad.map(b => b.line + ' → ' + b.msg).join('\n') : ''), bad.length === 0);
+ loadList();
+ } catch (e) { show(e.message, false); }
+}
+
+async function deleteEmp(staffNo) {
+ if (!confirm('确定删除 ' + staffNo + ' 吗?删除后该员工立即无法登录,需要重新添加才能恢复。')) return;
+ try {
+ await api('/api/admin/delete', { staffNo });
+ show('已删除 ' + staffNo, true);
+ loadList();
+ } catch (e) { show(e.message, false); }
+}
+
// 下载 CSV 导入模板(加 BOM 让 Excel 正确识别中文)
function downloadTemplate() {
const csv = '\uFEFF工号,姓名,初始密码\n10001,张三,abc123456\n10002,李四,abc123456\n';
diff --git a/account-service/server.js b/account-service/server.js
index 7435fa6..6cb61e9 100644
--- a/account-service/server.js
+++ b/account-service/server.js
@@ -260,6 +260,17 @@ const routes = {
ok(res, publicView(emp, body.staffNo));
},
+ // 删除员工:本地账号直接移除(立即无法再登录并被踢下线)。
+ // 注意:OpenIM 侧的同名用户不删(其公开 API 不提供删除),但删除后本服务不再为其签发令牌,等于不可用。
+ 'POST /api/admin/delete': async (req, res, body) => {
+ const emp = employees[body.staffNo];
+ if (!emp) return fail(res, '员工不存在');
+ delete employees[body.staffNo];
+ saveStore();
+ forceLogoutAll(body.staffNo); // 异步踢下线,不等结果
+ ok(res, { staffNo: body.staffNo, deleted: true });
+ },
+
'POST /api/admin/reset_password': async (req, res, body) => {
const emp = employees[body.staffNo];
if (!emp) return fail(res, '员工不存在');
diff --git a/account-service/t-data/e.json b/account-service/t-data/e.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/account-service/t-data/e.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/account-service/t-srv.log b/account-service/t-srv.log
new file mode 100644
index 0000000..e69de29