hunter-mate 0.1.23 → 0.1.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/dist/assets/extension/build-info.json +1 -1
- package/dist/assets/extension/manifest.json +3 -3
- package/dist/assets/server/chunks/{chunk-SAJB6JRK.mjs → chunk-VL7WHUEV.mjs} +556 -8
- package/dist/assets/server/chunks/{script-rule-ZJN6CEYX.mjs → script-rule-4RZQ2PQE.mjs} +1 -2
- package/dist/assets/server/main.mjs +220 -105
- package/dist/index.js +221 -38
- package/dist/web/dist/404.html +1 -1
- package/dist/web/dist/_next/static/chunks/253-a05d05b94bfbd7a4.js +1 -0
- package/dist/web/dist/_next/static/chunks/{852-248884963a986600.js → 852-ad19b97821a4cf9e.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/companies/{page-ec27ce9ab3610221.js → page-e8d02fe997579315.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-4827a9ef286b6483.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/talents/{page-c0a0c250eb5f5459.js → page-0edef6d07b3cf69d.js} +1 -1
- package/dist/web/dist/_next/static/css/10ba1fa1d6ce23a7.css +3 -0
- package/dist/web/dist/admin/data.html +1 -1
- package/dist/web/dist/admin/data.txt +1 -1
- package/dist/web/dist/auth/verify.html +1 -1
- package/dist/web/dist/auth/verify.txt +1 -1
- package/dist/web/dist/companies.html +1 -1
- package/dist/web/dist/companies.txt +2 -2
- package/dist/web/dist/company/admin.html +1 -1
- package/dist/web/dist/company/admin.txt +1 -1
- package/dist/web/dist/entity.html +1 -1
- package/dist/web/dist/entity.txt +1 -1
- package/dist/web/dist/index.html +1 -1
- package/dist/web/dist/index.txt +1 -1
- package/dist/web/dist/jobs.html +1 -1
- package/dist/web/dist/jobs.txt +2 -2
- package/dist/web/dist/logs.html +1 -1
- package/dist/web/dist/logs.txt +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +1 -1
- package/dist/web/dist/parselog.html +1 -1
- package/dist/web/dist/parselog.txt +1 -1
- package/dist/web/dist/recordings.html +1 -1
- package/dist/web/dist/recordings.txt +1 -1
- package/dist/web/dist/resource-usage.html +1 -1
- package/dist/web/dist/resource-usage.txt +1 -1
- package/dist/web/dist/shared/placeholder.html +1 -1
- package/dist/web/dist/shared/placeholder.txt +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +1 -1
- package/dist/web/dist/talents.html +1 -1
- package/dist/web/dist/talents.txt +2 -2
- package/dist/web/dist/team/insights.html +1 -1
- package/dist/web/dist/team/insights.txt +1 -1
- package/package.json +1 -1
- package/dist/assets/server/chunks/chunk-BLXHCSZD.mjs +0 -565
- package/dist/assets/server/chunks/esm-4U746B76.mjs +0 -29
- package/dist/web/dist/_next/static/chunks/954-fb0212fe71f60a52.js +0 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-4175a90f1b42f87d.js +0 -1
- package/dist/web/dist/_next/static/css/bd072fee69ae8474.css +0 -3
- /package/dist/assets/extension/background/{service-worker.20261016165050.js → service-worker.20261017183328.js} +0 -0
- /package/dist/web/dist/_next/static/{a_JzW5lROd6a66UMqSE9Z → 5MA8faUttk6FzlxGWnOlM}/_buildManifest.js +0 -0
- /package/dist/web/dist/_next/static/{a_JzW5lROd6a66UMqSE9Z → 5MA8faUttk6FzlxGWnOlM}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -63698,6 +63698,26 @@ function processCmdline(pid) {
|
|
|
63698
63698
|
return "";
|
|
63699
63699
|
}
|
|
63700
63700
|
}
|
|
63701
|
+
function parentPid(pid) {
|
|
63702
|
+
try {
|
|
63703
|
+
if (process.platform === "win32") {
|
|
63704
|
+
const r2 = spawnSync2(
|
|
63705
|
+
"wmic",
|
|
63706
|
+
["process", "where", `processId=${pid}`, "get", "ParentProcessId"],
|
|
63707
|
+
{ encoding: "utf-8" }
|
|
63708
|
+
);
|
|
63709
|
+
if (r2.status !== 0) return null;
|
|
63710
|
+
const ppid2 = Number((r2.stdout ?? "").trim().split(/\s+/).pop());
|
|
63711
|
+
return Number.isInteger(ppid2) && ppid2 > 0 ? ppid2 : null;
|
|
63712
|
+
}
|
|
63713
|
+
const r = spawnSync2("ps", ["-p", String(pid), "-o", "ppid="], { encoding: "utf-8" });
|
|
63714
|
+
if (r.status !== 0) return null;
|
|
63715
|
+
const ppid = Number((r.stdout ?? "").trim());
|
|
63716
|
+
return Number.isInteger(ppid) && ppid > 0 ? ppid : null;
|
|
63717
|
+
} catch {
|
|
63718
|
+
return null;
|
|
63719
|
+
}
|
|
63720
|
+
}
|
|
63701
63721
|
async function waitPortFree(port, timeoutMs) {
|
|
63702
63722
|
const deadline = Date.now() + timeoutMs;
|
|
63703
63723
|
while (Date.now() < deadline) {
|
|
@@ -63769,12 +63789,17 @@ __export(server_exports, {
|
|
|
63769
63789
|
acquireStartLock: () => acquireStartLock,
|
|
63770
63790
|
defaultPortFromConfig: () => defaultPortFromConfig,
|
|
63771
63791
|
findServerRoot: () => findServerRoot,
|
|
63792
|
+
isHmServerCmd: () => isHmServerCmd,
|
|
63793
|
+
isHmWatchdogCmd: () => isHmWatchdogCmd,
|
|
63794
|
+
probeHealthPid: () => probeHealthPid,
|
|
63772
63795
|
probeServerHealth: () => probeServerHealth,
|
|
63773
63796
|
reclaimPortIfOurs: () => reclaimPortIfOurs,
|
|
63797
|
+
restartCommand: () => restartCommand,
|
|
63774
63798
|
rotateLogIfNeeded: () => rotateLogIfNeeded,
|
|
63775
63799
|
runStart: () => runStart,
|
|
63776
63800
|
runStop: () => runStop,
|
|
63777
63801
|
startCommand: () => startCommand,
|
|
63802
|
+
stopByPortDiscovery: () => stopByPortDiscovery,
|
|
63778
63803
|
stopCommand: () => stopCommand,
|
|
63779
63804
|
tryReadPid: () => tryReadPid
|
|
63780
63805
|
});
|
|
@@ -63936,8 +63961,6 @@ async function runStart(opts) {
|
|
|
63936
63961
|
}
|
|
63937
63962
|
}
|
|
63938
63963
|
async function reclaimPortIfOurs(port, notes) {
|
|
63939
|
-
const isHmServerCmd = (cmd) => /packages[/\\]server[/\\]dist[/\\]main|assets[/\\]server[/\\]main/.test(cmd);
|
|
63940
|
-
const isHmWatchdogCmd = (cmd) => /watchdog\.js/.test(cmd) && /hunter-mate|packages[/\\]cli|cli[/\\]dist/.test(cmd);
|
|
63941
63964
|
for (let round = 1; round <= 3; round++) {
|
|
63942
63965
|
const occupant = findListeningPid(port);
|
|
63943
63966
|
if (!occupant) return { ok: true, pid: null, msg: "" };
|
|
@@ -63968,6 +63991,103 @@ async function reclaimPortIfOurs(port, notes) {
|
|
|
63968
63991
|
msg: `\u2717 \u7AEF\u53E3 ${port} \u88AB\u8FDB\u7A0B(pid=${still ?? "\u672A\u77E5"})\u53CD\u590D\u5360\u7528,\u5DF2\u91CD\u8BD5 3 \u8F6E\u4ECD\u65E0\u6CD5\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5`
|
|
63969
63992
|
};
|
|
63970
63993
|
}
|
|
63994
|
+
async function probeHealthPid(url2, timeoutMs = 1500) {
|
|
63995
|
+
try {
|
|
63996
|
+
const res = await fetch(`${url2}/health`, { signal: AbortSignal.timeout(timeoutMs) });
|
|
63997
|
+
if (!res.ok) return null;
|
|
63998
|
+
const body = await res.json();
|
|
63999
|
+
const pid = Number(body?.pid);
|
|
64000
|
+
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
64001
|
+
} catch {
|
|
64002
|
+
return null;
|
|
64003
|
+
}
|
|
64004
|
+
}
|
|
64005
|
+
async function stopByPortDiscovery(port, opts, io = {}) {
|
|
64006
|
+
const findPid = io.findListeningPidFn ?? findListeningPid;
|
|
64007
|
+
const cmdline = io.processCmdlineFn ?? processCmdline;
|
|
64008
|
+
const getPpid = io.parentPidFn ?? parentPid;
|
|
64009
|
+
const probePid = io.probeHealthPidFn ?? probeHealthPid;
|
|
64010
|
+
const kill = io.killGracefullyFn ?? killGracefully;
|
|
64011
|
+
const waitFree = io.waitPortFreeFn ?? waitPortFree;
|
|
64012
|
+
const occupant = findPid(port);
|
|
64013
|
+
if (!occupant) {
|
|
64014
|
+
return { stopped: false, pid: null, via: null, msg: "(server \u672A\u8FD0\u884C,\u65E0\u9700\u505C\u6B62)" };
|
|
64015
|
+
}
|
|
64016
|
+
const cmd = cmdline(occupant);
|
|
64017
|
+
if (!isHmServerCmd(cmd)) {
|
|
64018
|
+
return {
|
|
64019
|
+
stopped: false,
|
|
64020
|
+
pid: occupant,
|
|
64021
|
+
via: null,
|
|
64022
|
+
msg: `\u2717 \u7AEF\u53E3 ${port} \u88AB\u5176\u4ED6\u7A0B\u5E8F\u5360\u7528(pid=${occupant}: ${cmd.slice(0, 80) || "\u547D\u4EE4\u884C\u4E0D\u53EF\u8BFB"}),\u672A\u6267\u884C\u505C\u6B62;\u8BF7\u5148\u91CA\u653E\u8BE5\u7AEF\u53E3`
|
|
64023
|
+
};
|
|
64024
|
+
}
|
|
64025
|
+
const healthPid = await probePid(opts.url);
|
|
64026
|
+
if (healthPid === null) {
|
|
64027
|
+
return {
|
|
64028
|
+
stopped: false,
|
|
64029
|
+
pid: occupant,
|
|
64030
|
+
via: null,
|
|
64031
|
+
msg: `\u2717 \u7AEF\u53E3 ${port} \u4E0A\u7684 server(pid=${occupant})\u65E0 /health \u54CD\u5E94,\u672A\u6267\u884C\u505C\u6B62;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B\u8FDB\u7A0B\u8BF7\u624B\u5DE5 kill pid=${occupant}`
|
|
64032
|
+
};
|
|
64033
|
+
}
|
|
64034
|
+
if (healthPid !== occupant) {
|
|
64035
|
+
return {
|
|
64036
|
+
stopped: false,
|
|
64037
|
+
pid: occupant,
|
|
64038
|
+
via: null,
|
|
64039
|
+
msg: `\u2717 \u7AEF\u53E3 ${port} \u4E0A\u7684 server \u8EAB\u4EFD\u65E0\u6CD5\u786E\u8BA4(/health \u81EA\u62A5 pid=${healthPid} \u4E0E\u76D1\u542C\u8FDB\u7A0B pid=${occupant} \u4E0D\u4E00\u81F4),\u672A\u6267\u884C\u505C\u6B62;\u8BF7\u5148\u91CA\u653E\u8BE5\u7AEF\u53E3`
|
|
64040
|
+
};
|
|
64041
|
+
}
|
|
64042
|
+
const found = (() => {
|
|
64043
|
+
const fromFile = tryReadPidFile(WATCHDOG_PID_FILE());
|
|
64044
|
+
if (fromFile && fromFile !== occupant && fromFile !== 1 && isHmWatchdogCmd(cmdline(fromFile))) {
|
|
64045
|
+
return { wdPid: fromFile };
|
|
64046
|
+
}
|
|
64047
|
+
const ppid = getPpid(occupant);
|
|
64048
|
+
if (ppid && ppid !== 1 && ppid !== process.pid && isHmWatchdogCmd(cmdline(ppid))) {
|
|
64049
|
+
return { wdPid: ppid };
|
|
64050
|
+
}
|
|
64051
|
+
return null;
|
|
64052
|
+
})();
|
|
64053
|
+
const intro = `\u26A0 \u672A\u627E\u5230 pid \u6587\u4EF6,\u5DF2\u4ECE\u7AEF\u53E3 ${port} \u53D1\u73B0\u8FD0\u884C\u4E2D\u7684 server (pid=${occupant})`;
|
|
64054
|
+
if (found) {
|
|
64055
|
+
await kill(found.wdPid, 5e3);
|
|
64056
|
+
if (await waitFree(port, 8e3)) {
|
|
64057
|
+
cleanPidFile(WATCHDOG_PID_FILE());
|
|
64058
|
+
cleanPidFile(PID_FILE());
|
|
64059
|
+
return {
|
|
64060
|
+
stopped: true,
|
|
64061
|
+
pid: occupant,
|
|
64062
|
+
via: "watchdog",
|
|
64063
|
+
msg: `${intro}
|
|
64064
|
+
\u26A0 \u68C0\u6D4B\u5230\u5176 watchdog (pid=${found.wdPid}),\u5DF2\u4E00\u5E76\u505C\u6B62
|
|
64065
|
+
\u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})`
|
|
64066
|
+
};
|
|
64067
|
+
}
|
|
64068
|
+
await kill(occupant, 5e3);
|
|
64069
|
+
if (await waitFree(port, 4e3)) {
|
|
64070
|
+
cleanPidFile(WATCHDOG_PID_FILE());
|
|
64071
|
+
cleanPidFile(PID_FILE());
|
|
64072
|
+
return {
|
|
64073
|
+
stopped: true,
|
|
64074
|
+
pid: occupant,
|
|
64075
|
+
via: "server",
|
|
64076
|
+
msg: `${intro}
|
|
64077
|
+
\u26A0 watchdog (pid=${found.wdPid}) \u5DF2\u505C\u6B62,\u4F46\u5176\u6258\u7BA1\u7684 server \u672A\u8FDE\u5E26\u9000\u51FA,\u5DF2\u8865\u6740
|
|
64078
|
+
\u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})`
|
|
64079
|
+
};
|
|
64080
|
+
}
|
|
64081
|
+
return { stopped: false, pid: occupant, via: null, msg: `\u2717 \u7AEF\u53E3 ${port} \u957F\u65F6\u95F4\u672A\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5(pid=${occupant})` };
|
|
64082
|
+
}
|
|
64083
|
+
await kill(occupant, 5e3);
|
|
64084
|
+
if (await waitFree(port, 8e3)) {
|
|
64085
|
+
cleanPidFile(PID_FILE());
|
|
64086
|
+
return { stopped: true, pid: occupant, via: "server", msg: `${intro}
|
|
64087
|
+
\u2713 server \u5DF2\u505C\u6B62 (pid=${occupant})` };
|
|
64088
|
+
}
|
|
64089
|
+
return { stopped: false, pid: occupant, via: null, msg: `\u2717 \u7AEF\u53E3 ${port} \u957F\u65F6\u95F4\u672A\u91CA\u653E,\u8BF7\u624B\u5DE5\u6392\u67E5(pid=${occupant})` };
|
|
64090
|
+
}
|
|
63971
64091
|
async function runStartLocked(opts, ctx) {
|
|
63972
64092
|
const { url: url2, port, host, notes } = ctx;
|
|
63973
64093
|
const config = loadConfig();
|
|
@@ -64152,9 +64272,9 @@ async function runStop() {
|
|
|
64152
64272
|
msg: `\u2717 server \u65E0\u54CD\u5E94(${url2}/health \u4E0D\u53EF\u8FBE),watchdog pid=${wdPid} \u672A\u6740(\u7591\u4F3C stale pid,\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u8FDB\u7A0B\u590D\u7528)\u3002pid \u6587\u4EF6\u4FDD\u7559\u4EE5\u4FBF\u590D\u63A2;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B\u8FDB\u7A0B\u8BF7\u624B\u5DE5 kill`
|
|
64153
64273
|
};
|
|
64154
64274
|
}
|
|
64155
|
-
const
|
|
64275
|
+
const ok = killGracefullySync(wdPid);
|
|
64156
64276
|
cleanPidFile(WATCHDOG_PID_FILE());
|
|
64157
|
-
if (
|
|
64277
|
+
if (ok) {
|
|
64158
64278
|
try {
|
|
64159
64279
|
const pid2 = tryReadPid();
|
|
64160
64280
|
if (pid2) {
|
|
@@ -64167,22 +64287,25 @@ async function runStop() {
|
|
|
64167
64287
|
}
|
|
64168
64288
|
}
|
|
64169
64289
|
const pid = tryReadPid();
|
|
64170
|
-
if (
|
|
64171
|
-
|
|
64172
|
-
|
|
64173
|
-
|
|
64174
|
-
|
|
64175
|
-
|
|
64176
|
-
|
|
64177
|
-
|
|
64178
|
-
|
|
64179
|
-
|
|
64180
|
-
|
|
64290
|
+
if (pid) {
|
|
64291
|
+
if (!healthy) {
|
|
64292
|
+
return {
|
|
64293
|
+
stopped: false,
|
|
64294
|
+
pid,
|
|
64295
|
+
msg: `\u2717 pid=${pid} \u5B58\u6D3B\u4F46 server \u65E0\u54CD\u5E94,\u672A\u53D1\u9001 kill \u4FE1\u53F7(\u7591\u4F3C stale pid,\u53EF\u80FD\u5C5E\u4E8E\u5176\u4ED6\u8FDB\u7A0B)\u3002pid \u6587\u4EF6\u4FDD\u7559\u4EE5\u4FBF\u590D\u63A2;\u5982\u786E\u8BA4\u662F\u50F5\u6B7B server \u8BF7\u624B\u5DE5 kill`
|
|
64296
|
+
};
|
|
64297
|
+
}
|
|
64298
|
+
const ok = killGracefullySync(pid);
|
|
64299
|
+
if (!ok) {
|
|
64300
|
+
return { stopped: false, pid, msg: `failed to signal ${pid}` };
|
|
64301
|
+
}
|
|
64302
|
+
cleanPidFile(PID_FILE());
|
|
64303
|
+
return { stopped: true, pid, msg: `server stopped (pid=${pid})` };
|
|
64181
64304
|
}
|
|
64182
|
-
|
|
64183
|
-
return
|
|
64305
|
+
const port = defaultPortFromConfig(config.serverUrl);
|
|
64306
|
+
return await stopByPortDiscovery(port, { url: url2 });
|
|
64184
64307
|
}
|
|
64185
|
-
var __dirname3, PID_FILE, LOG_FILE, WATCHDOG_PID_FILE, START_LOCK_FILE, START_LOCK_STALE_MS, LOG_MAX_BYTES, LOG_KEEP_FILES, startCommand, stopCommand;
|
|
64308
|
+
var __dirname3, PID_FILE, LOG_FILE, WATCHDOG_PID_FILE, START_LOCK_FILE, START_LOCK_STALE_MS, LOG_MAX_BYTES, LOG_KEEP_FILES, isHmServerCmd, isHmWatchdogCmd, startCommand, stopCommand, restartCommand;
|
|
64186
64309
|
var init_server = __esm({
|
|
64187
64310
|
"src/commands/server.ts"() {
|
|
64188
64311
|
"use strict";
|
|
@@ -64198,16 +64321,31 @@ var init_server = __esm({
|
|
|
64198
64321
|
START_LOCK_STALE_MS = 9e4;
|
|
64199
64322
|
LOG_MAX_BYTES = () => Number(process.env.HM_LOG_MAX_BYTES || 50 * 1024 * 1024);
|
|
64200
64323
|
LOG_KEEP_FILES = 3;
|
|
64324
|
+
isHmServerCmd = (cmd) => /packages[/\\]server[/\\]dist[/\\]main|assets[/\\]server[/\\]main/.test(cmd);
|
|
64325
|
+
isHmWatchdogCmd = (cmd) => /watchdog\.js/.test(cmd) && /hunter-mate|packages[/\\]cli|cli[/\\]dist/.test(cmd);
|
|
64201
64326
|
startCommand = new Command("start").description("\u542F\u52A8\u672C\u5730 NestJS server\uFF08REST + WebSocket + SPA\uFF09\uFF0C\u5BF9\u5E94 chromepilot start").option("-p, --port <port>", `server \u7AEF\u53E3\uFF0C\u4F18\u5148\u7EA7: -p > \u73AF\u5883\u53D8\u91CF PORT > config.serverUrl(\u65E7\u9ED8\u8BA4 34570 \u5DF2\u7EDF\u4E00\u8FC1\u79FB\u5230 ${DEFAULT_SERVER_PORT})`).option("-h, --host <host>", "\u7ED1\u5B9A host\uFF0C\u9ED8\u8BA4 127.0.0.1", "127.0.0.1").option("-f, --foreground", "\u524D\u53F0\u8FD0\u884C\uFF08\u9ED8\u8BA4\u540E\u53F0 daemon\uFF0C\u5199 server.pid + server.log\uFF09").action(async (opts) => {
|
|
64202
64327
|
const r = await runStart({ port: opts.port ? Number(opts.port) : void 0, host: opts.host, foreground: opts.foreground });
|
|
64203
64328
|
console.log(r.msg);
|
|
64204
64329
|
if (!r.started && !r.pid) process.exit(1);
|
|
64205
64330
|
});
|
|
64206
|
-
stopCommand = new Command("stop").description("\u505C\u6B62\u672C\u5730 server\uFF08\u8BFB ~/.hunter-mate/server.pid \u5E76 SIGTERM\uFF09").action(async () => {
|
|
64331
|
+
stopCommand = new Command("stop").description("\u505C\u6B62\u672C\u5730 server\uFF08\u8BFB ~/.hunter-mate/server.pid \u5E76 SIGTERM;pid \u6587\u4EF6\u7F3A\u5931\u65F6\u6309\u7AEF\u53E3\u56DE\u9000\u53D1\u73B0,\u9A8C\u660E\u8EAB\u4EFD\u540E\u7ECF watchdog \u4E00\u5E76\u505C\u6B62\uFF09").action(async () => {
|
|
64207
64332
|
const r = await runStop();
|
|
64208
64333
|
console.log(r.msg);
|
|
64209
64334
|
if (!r.stopped && r.pid) process.exit(1);
|
|
64210
64335
|
});
|
|
64336
|
+
restartCommand = new Command("restart").description("\u91CD\u542F\u672C\u5730 server(\u5148\u505C\u6B62\u73B0\u6709\u5B9E\u4F8B\u2014\u2014\u542B\u65E0 pid \u6587\u4EF6\u65F6\u7684\u7AEF\u53E3\u56DE\u9000\u53D1\u73B0,\u518D\u91CD\u65B0\u542F\u52A8;\u505C\u6B62\u88AB\u62D2\u65F6\u4E0D\u542F\u52A8)").option("-p, --port <port>", `server \u7AEF\u53E3\uFF0C\u4F18\u5148\u7EA7: -p > \u73AF\u5883\u53D8\u91CF PORT > config.serverUrl(\u65E7\u9ED8\u8BA4 34570 \u5DF2\u7EDF\u4E00\u8FC1\u79FB\u5230 ${DEFAULT_SERVER_PORT})`).option("-h, --host <host>", "\u7ED1\u5B9A host\uFF0C\u9ED8\u8BA4 127.0.0.1", "127.0.0.1").action(async (opts) => {
|
|
64337
|
+
console.log("-- \u505C\u6B62\u73B0\u6709 server --");
|
|
64338
|
+
const stopR = await runStop();
|
|
64339
|
+
console.log(stopR.msg);
|
|
64340
|
+
if (!stopR.stopped && stopR.pid) {
|
|
64341
|
+
console.log("\u2717 \u91CD\u542F\u5DF2\u4E2D\u6B62:\u73B0\u6709 server \u672A\u80FD\u505C\u6B62,\u672A\u6267\u884C\u542F\u52A8");
|
|
64342
|
+
process.exit(1);
|
|
64343
|
+
}
|
|
64344
|
+
console.log("-- \u542F\u52A8\u65B0 server --");
|
|
64345
|
+
const startR = await runStart({ port: opts.port ? Number(opts.port) : void 0, host: opts.host });
|
|
64346
|
+
console.log(startR.msg);
|
|
64347
|
+
if (!startR.started && !startR.pid) process.exit(1);
|
|
64348
|
+
});
|
|
64211
64349
|
}
|
|
64212
64350
|
});
|
|
64213
64351
|
|
|
@@ -70211,7 +70349,7 @@ var init_auto_doctor = __esm({
|
|
|
70211
70349
|
var hmh_sync_exports = {};
|
|
70212
70350
|
__export(hmh_sync_exports, {
|
|
70213
70351
|
maybeSyncHmhLocal: () => maybeSyncHmhLocal,
|
|
70214
|
-
parseFrontmatter: () =>
|
|
70352
|
+
parseFrontmatter: () => parseFrontmatter2,
|
|
70215
70353
|
resolveHmhLocalDir: () => resolveHmhLocalDir
|
|
70216
70354
|
});
|
|
70217
70355
|
import * as fs28 from "fs";
|
|
@@ -70254,7 +70392,7 @@ function resolveHmhLocalDir() {
|
|
|
70254
70392
|
}
|
|
70255
70393
|
return null;
|
|
70256
70394
|
}
|
|
70257
|
-
function
|
|
70395
|
+
function parseFrontmatter2(text) {
|
|
70258
70396
|
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
70259
70397
|
if (!m) return {};
|
|
70260
70398
|
const meta = {};
|
|
@@ -70360,7 +70498,7 @@ async function maybeSyncHmhLocal() {
|
|
|
70360
70498
|
const clientsDir = path30.join(localDir, "clients");
|
|
70361
70499
|
for (const clientDir of listIndexDirs(clientsDir)) {
|
|
70362
70500
|
const indexFile = path30.join(clientDir, "INDEX.md");
|
|
70363
|
-
const meta =
|
|
70501
|
+
const meta = parseFrontmatter2(fs28.readFileSync(indexFile, "utf8"));
|
|
70364
70502
|
const clientName = cleanValue(meta.client) || path30.basename(clientDir);
|
|
70365
70503
|
report.checkedClients = (report.checkedClients ?? 0) + 1;
|
|
70366
70504
|
const wantName = looseName(clientName);
|
|
@@ -70410,7 +70548,7 @@ async function maybeSyncHmhLocal() {
|
|
|
70410
70548
|
const positionsDir = path30.join(clientDir, "positions");
|
|
70411
70549
|
for (const posDir of listIndexDirs(positionsDir)) {
|
|
70412
70550
|
const posIndexFile = path30.join(posDir, "INDEX.md");
|
|
70413
|
-
const posMeta =
|
|
70551
|
+
const posMeta = parseFrontmatter2(fs28.readFileSync(posIndexFile, "utf8"));
|
|
70414
70552
|
const posName = cleanValue(posMeta.position) || path30.basename(posDir);
|
|
70415
70553
|
report.checkedPositions = (report.checkedPositions ?? 0) + 1;
|
|
70416
70554
|
const posCustomerStamped = Number(posMeta.customer_id);
|
|
@@ -71114,24 +71252,47 @@ function collectJobFiles(dir, relPrefix = "", out = {}) {
|
|
|
71114
71252
|
}
|
|
71115
71253
|
return out;
|
|
71116
71254
|
}
|
|
71255
|
+
function parseFrontmatter(text) {
|
|
71256
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
71257
|
+
if (!m) return {};
|
|
71258
|
+
const out = {};
|
|
71259
|
+
for (const line of m[1].split(/\r?\n/)) {
|
|
71260
|
+
const idx = line.indexOf(":");
|
|
71261
|
+
if (idx <= 0) continue;
|
|
71262
|
+
const key = line.slice(0, idx).trim();
|
|
71263
|
+
let value = line.slice(idx + 1).trim();
|
|
71264
|
+
if (value.startsWith('"') && value.endsWith('"')) value = value.slice(1, -1);
|
|
71265
|
+
if (value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
71266
|
+
if (key && value) out[key] = value;
|
|
71267
|
+
}
|
|
71268
|
+
return out;
|
|
71269
|
+
}
|
|
71270
|
+
var FM_REQUIREMENT_KEYS = ["company", "location", "salary", "employment", "department"];
|
|
71271
|
+
function orderedFileKeys(rawFiles) {
|
|
71272
|
+
const keys = Object.keys(rawFiles);
|
|
71273
|
+
const md = keys.filter((k2) => k2.endsWith(".md"));
|
|
71274
|
+
const rootMd = md.filter((k2) => !k2.includes("/"));
|
|
71275
|
+
const preferred = rootMd.filter((k2) => /^(job|jd|index)\.md$/i.test(k2));
|
|
71276
|
+
return [...preferred, ...rootMd.filter((k2) => !preferred.includes(k2)), ...md.filter((k2) => !rootMd.includes(k2))];
|
|
71277
|
+
}
|
|
71278
|
+
async function resolveCustomerId(customerRef) {
|
|
71279
|
+
if (/^\d+$/.test(customerRef.trim())) return parseInt(customerRef.trim(), 10);
|
|
71280
|
+
const hits = await runCustomerList(customerRef.trim());
|
|
71281
|
+
if (!hits.length) {
|
|
71282
|
+
throw new Error(`\u5BA2\u6237 "${customerRef}" \u672A\u5165\u5E93,\u8BF7\u5148: hunter-mate customer upsert --name "${customerRef}"`);
|
|
71283
|
+
}
|
|
71284
|
+
if (hits.length > 1) {
|
|
71285
|
+
console.error(`\u2139 \u5BA2\u6237 "${customerRef}" \u547D\u4E2D ${hits.length} \u6761,\u4F7F\u7528\u7B2C\u4E00\u4E2A: [${hits[0].id}] ${hits[0].canonicalName}`);
|
|
71286
|
+
}
|
|
71287
|
+
return hits[0].id;
|
|
71288
|
+
}
|
|
71117
71289
|
async function runJobCreate(folderPath, customerRef) {
|
|
71118
71290
|
const config = loadConfig();
|
|
71119
71291
|
const token = await getToken();
|
|
71120
71292
|
const headers = token ? { Authorization: `UTOKEN ${token}` } : {};
|
|
71121
71293
|
let customerId;
|
|
71122
71294
|
if (customerRef) {
|
|
71123
|
-
|
|
71124
|
-
customerId = parseInt(customerRef.trim(), 10);
|
|
71125
|
-
} else {
|
|
71126
|
-
const hits = await runCustomerList(customerRef.trim());
|
|
71127
|
-
if (!hits.length) {
|
|
71128
|
-
throw new Error(`\u5BA2\u6237 "${customerRef}" \u672A\u5165\u5E93,\u8BF7\u5148: hunter-mate customer upsert --name "${customerRef}"`);
|
|
71129
|
-
}
|
|
71130
|
-
customerId = hits[0].id;
|
|
71131
|
-
if (hits.length > 1) {
|
|
71132
|
-
console.error(`\u2139 \u5BA2\u6237 "${customerRef}" \u547D\u4E2D ${hits.length} \u6761,\u4F7F\u7528\u7B2C\u4E00\u4E2A: [${hits[0].id}] ${hits[0].canonicalName}`);
|
|
71133
|
-
}
|
|
71134
|
-
}
|
|
71295
|
+
customerId = await resolveCustomerId(customerRef);
|
|
71135
71296
|
}
|
|
71136
71297
|
const resolved = path17.resolve(folderPath);
|
|
71137
71298
|
if (!fs15.existsSync(resolved)) {
|
|
@@ -71142,9 +71303,29 @@ async function runJobCreate(folderPath, customerRef) {
|
|
|
71142
71303
|
throw new Error(`Folder \u5185\u672A\u627E\u5230 .md/.txt/.pdf \u6587\u4EF6: ${resolved}`);
|
|
71143
71304
|
}
|
|
71144
71305
|
const rawText = Object.values(rawFiles).join("\n---\n");
|
|
71306
|
+
const fm = {};
|
|
71307
|
+
for (const key of orderedFileKeys(rawFiles)) {
|
|
71308
|
+
const parsed = parseFrontmatter(rawFiles[key]);
|
|
71309
|
+
if (Object.keys(parsed).length) {
|
|
71310
|
+
Object.assign(fm, parsed);
|
|
71311
|
+
break;
|
|
71312
|
+
}
|
|
71313
|
+
}
|
|
71314
|
+
if (customerId === void 0 && fm.customer) {
|
|
71315
|
+
customerId = await resolveCustomerId(fm.customer);
|
|
71316
|
+
console.error(`\u2139 \u5BA2\u6237\u53D6\u81EA JD frontmatter: ${fm.customer} \u2192 id=${customerId}`);
|
|
71317
|
+
}
|
|
71318
|
+
const requirements = {};
|
|
71319
|
+
for (const k2 of FM_REQUIREMENT_KEYS) {
|
|
71320
|
+
if (fm[k2]) requirements[k2] = fm[k2];
|
|
71321
|
+
}
|
|
71145
71322
|
const firstKey = Object.keys(rawFiles)[0];
|
|
71146
71323
|
const titleBase = firstKey.includes("/") ? firstKey.split("/").pop() : firstKey;
|
|
71147
|
-
const
|
|
71324
|
+
const fallbackTitle = titleBase.replace(/\.[^.]+$/, "") || "Untitled JobCase";
|
|
71325
|
+
const title = (fm.title ?? "").trim() || fallbackTitle;
|
|
71326
|
+
if (fm.title) {
|
|
71327
|
+
console.error(`\u2139 \u804C\u4F4D\u540D\u53D6\u81EA JD frontmatter: "${title}"`);
|
|
71328
|
+
}
|
|
71148
71329
|
const res = await axios_default.post(
|
|
71149
71330
|
`${config.serverUrl}/job-cases`,
|
|
71150
71331
|
{
|
|
@@ -71152,7 +71333,8 @@ async function runJobCreate(folderPath, customerRef) {
|
|
|
71152
71333
|
title,
|
|
71153
71334
|
folderPath: resolved,
|
|
71154
71335
|
rawFiles,
|
|
71155
|
-
customerId
|
|
71336
|
+
customerId,
|
|
71337
|
+
requirements: Object.keys(requirements).length ? requirements : void 0
|
|
71156
71338
|
},
|
|
71157
71339
|
{ headers, proxy: false }
|
|
71158
71340
|
);
|
|
@@ -73579,7 +73761,7 @@ function installLocalProxyBypass() {
|
|
|
73579
73761
|
// package.json
|
|
73580
73762
|
var package_default = {
|
|
73581
73763
|
name: "hunter-mate",
|
|
73582
|
-
version: "0.1.
|
|
73764
|
+
version: "0.1.25",
|
|
73583
73765
|
type: "module",
|
|
73584
73766
|
description: "HiredChina \u730E\u5934 Agent \u6570\u636E\u52A9\u624B CLI:\u4EBA\u624D\u5E93/\u5BA2\u6237/\u804C\u4F4D\u6570\u636E\u8BBF\u95EE,\u6D4F\u89C8\u5668\u5F55\u5236\u89E3\u6790\u7B80\u5386,server/\u6269\u5C55\u4E00\u81F4\u6027\u81EA\u6108",
|
|
73585
73767
|
license: "MIT",
|
|
@@ -73739,6 +73921,7 @@ program2.addCommand(initCommand);
|
|
|
73739
73921
|
program2.addCommand(installCommand);
|
|
73740
73922
|
program2.addCommand(startCommand);
|
|
73741
73923
|
program2.addCommand(stopCommand);
|
|
73924
|
+
program2.addCommand(restartCommand);
|
|
73742
73925
|
program2.addCommand(loginCommand);
|
|
73743
73926
|
program2.addCommand(logoutCommand);
|
|
73744
73927
|
program2.addCommand(tokenCommand);
|
package/dist/web/dist/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="zh-CN"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/10ba1fa1d6ce23a7.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-54e74ccc9e9451ee.js"/><script src="/_next/static/chunks/a7067448-e416655baf443992.js" async=""></script><script src="/_next/static/chunks/935-7be3e60dd8bc29d2.js" async=""></script><script src="/_next/static/chunks/main-app-f496bd51a73ef9f3.js" async=""></script><script src="/_next/static/chunks/589-f984bff035a1cb85.js" async=""></script><script src="/_next/static/chunks/105-dcd8f6d5867c8995.js" async=""></script><script src="/_next/static/chunks/app/layout-af39afc7866e74db.js" async=""></script><meta name="robots" content="noindex"/><title>HunterMate 采集仪表盘</title><meta name="description" content="HunterMate 采集/解析/入库仪表盘"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="flex h-screen overflow-hidden bg-gray-50 text-gray-900"><div class="flex h-screen w-screen flex-col items-center justify-center bg-gray-50"><span class="hm-spinner" aria-label="加载中"></span><div class="mt-4 text-sm text-gray-400">正在加载,请稍候…</div></div><script src="/_next/static/chunks/webpack-54e74ccc9e9451ee.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/10ba1fa1d6ce23a7.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[76939,[],\"\"]\n4:I[74268,[],\"\"]\n5:I[81050,[],\"\"]\n6:I[15214,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"AuthGate\"]\n7:I[67188,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"AntdProvider\"]\n8:I[9424,[\"589\",\"static/chunks/589-f984bff035a1cb85.js\",\"105\",\"static/chunks/105-dcd8f6d5867c8995.js\",\"185\",\"static/chunks/app/layout-af39afc7866e74db.js\"],\"SystemSidebar\"]\ne:I[62319,[],\"\"]\n9:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\na:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\nb:{\"display\":\"inline-block\"}\nc:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nf:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"5MA8faUttk6FzlxGWnOlM\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/10ba1fa1d6ce23a7.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"zh-CN\",\"children\":[\"$\",\"body\",null,{\"className\":\"flex h-screen overflow-hidden bg-gray-50 text-gray-900\",\"children\":[\"$\",\"$L6\",null,{\"children\":[\"$\",\"$L7\",null,{\"children\":[[\"$\",\"$L8\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1 overflow-hidden\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$9\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$a\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$b\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$c\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Ld\"],\"globalErrorComponent\":\"$e\",\"missingSlots\":\"$Wf\"}]\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"HunterMate 采集仪表盘\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"HunterMate 采集/解析/入库仪表盘\"}]]\n3:null\n"])</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="d94bef85-19b8-4754-8ff1-524e1467ad51",e._sentryDebugIdIdentifier="sentry-dbid-d94bef85-19b8-4754-8ff1-524e1467ad51")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[253],{94518:function(e,t,n){n.d(t,{m:function(){return r}});var l=n(72835);function r(e){let{filterBar:t,listPanel:n,detailPanel:r}=e;return(0,l.jsxs)("div",{className:"flex h-full",children:[(0,l.jsxs)("div",{className:"flex w-80 flex-col border-r border-gray-200 bg-white",children:[t,n]}),(0,l.jsx)("div",{className:"flex-1 overflow-auto bg-gray-50 p-6",children:r})]})}},63718:function(e,t,n){n.d(t,{L:function(){return a}});var l=n(72835),r=n(60635);function a(e){let{items:t,selectedId:n,onSelect:a,loading:s,emptyText:i="暂无数据",onLoadMore:c,loadingMore:u,exhausted:o}=e,d=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!c)return;let e=d.current;if(!e)return;let t=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&c()},{root:e.closest(".overflow-auto"),rootMargin:"200px"});return t.observe(e),()=>t.disconnect()},[c]),(0,l.jsxs)("div",{className:"flex-1 overflow-auto",children:[s?(0,l.jsx)("div",{className:"p-4 text-center text-sm text-gray-400",children:"加载中…"}):0===t.length?(0,l.jsx)("div",{className:"p-4 text-center text-sm text-gray-400",children:i}):(0,l.jsx)("ul",{className:"divide-y divide-gray-100",children:t.map(e=>(0,l.jsx)("li",{role:"button",tabIndex:0,onClick:()=>a(e.id),onKeyDown:t=>{("Enter"===t.key||" "===t.key)&&a(e.id)},className:"cursor-pointer px-3 py-2 text-sm transition-colors ".concat(n===e.id?"bg-blue-50":"hover:bg-gray-50"),children:e.content},e.id))}),c&&!s&&t.length>0&&(0,l.jsx)("div",{ref:d,className:"p-3 text-center text-xs text-gray-400",children:u?"加载更多…":o?"没有更多了":""})]})}},27828:function(e,t,n){n.d(t,{dy:function(){return f},rY:function(){return g},h5:function(){return x},oj:function(){return i}});var l=n(72835),r=n(84704);function a(e){return String(e).padStart(2,"0")}function s(e){let{value:t}=e;if(!t)return null;let n=new Date(t);return Number.isNaN(n.getTime())?null:(0,l.jsx)("span",{title:function(e){let t="string"==typeof e?new Date(e):e;return Number.isNaN(t.getTime())?"":"".concat(t.getFullYear(),"/").concat(a(t.getMonth()+1),"/").concat(a(t.getDate())," ")+"".concat(a(t.getHours()),":").concat(a(t.getMinutes()),":").concat(a(t.getSeconds()))}(n),className:"cursor-default",children:function(e,t){let n="string"==typeof e?new Date(e):e,l=n.getTime();if(Number.isNaN(l))return"";let r=Math.floor(Math.max(0,t.getTime()-l)/6e4);if(r<1)return"刚刚";if(r<60)return"".concat(r," 分钟前");let s=Math.floor(r/60);if(s<24)return"".concat(s," 小时前");let i=Math.floor((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime())/864e5);return i<=1?"昨天":i<30?"".concat(i," 天前"):"".concat(n.getFullYear(),"/").concat(a(n.getMonth()+1),"/").concat(a(n.getDate()))}(n,new Date)})}function i(e){let{name:t,headline:n,source:r,updatedAt:a}=e;return(0,l.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,l.jsx)("div",{className:"font-medium text-gray-900",children:t}),n?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:n}):null,(0,l.jsxs)("div",{className:"mt-0.5 flex items-center gap-2 text-xs text-gray-400",children:[r?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("span",{children:r}),(0,l.jsx)("span",{children:"\xb7"})]}):null,(0,l.jsx)(s,{value:a})]})]})}let c={active:"启动中",closed:"结束"},u={recommended:"推荐人才",pending_invite:"待邀请",invited:"已邀请待回复",replied:"已回复待筛选",to_client:"待推荐给客户",interview_pending:"已推荐待安排面试",interview_scheduled:"已安排面试",offer_pending:"待offer",onboarding:"待上班",rejected:"不合适"};function o(e){let{stages:t}=e,n=Object.keys(t).filter(e=>{var n,l;return(null!==(l=null===(n=t[e])||void 0===n?void 0:n.total)&&void 0!==l?l:0)>0});return n.length?(0,l.jsx)("div",{className:"mt-1 flex flex-wrap items-center gap-1",children:n.map(e=>{var n;let r=t[e],a=null!==(n=u[e])&&void 0!==n?n:e;return(0,l.jsxs)("span",{title:"".concat(a," 今天").concat(r.today,"/本周").concat(r.week,"/全部").concat(r.total),className:"rounded bg-[color:var(--brand-soft)] px-1.5 py-0.5 text-[10px] font-medium",style:{color:"var(--brand)"},children:[a," ",r.today,"/",r.week,"/",r.total]},e)})}):null}function d(e){let{platforms:t}=e;return t.length?(0,l.jsx)("span",{className:"flex items-center gap-0.5",title:t.join("、"),children:t.map(e=>{let t=(0,r.mS)(e);return(0,l.jsx)("span",{title:e,className:"flex h-4 w-4 items-center justify-center rounded bg-[color:var(--brand-soft)] text-[9px] font-semibold",style:{color:t.fg},children:t.label},e)})}):null}function f(e){var t,n;let{title:r,status:a,hmhLocal:i,subtitle:u,customerName:f,opName:x,rsNames:g,time:h,updatedAt:m,createdAt:p,stages:v,platforms:y,myRole:b}=e,j=null!==(t=null!=m?m:h)&&void 0!==t?t:"",N=null!=p?p:"",w=!!j&&!!N&&1e3>Math.abs(new Date(j).getTime()-new Date(N).getTime());return(0,l.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"truncate font-medium text-gray-900",children:r}),(0,l.jsx)("span",{className:"shrink-0 rounded px-1.5 py-0.5 text-xs ".concat("active"===a?"bg-emerald-100 text-emerald-700":"bg-gray-100 text-gray-500"),children:null!==(n=c[a])&&void 0!==n?n:a}),i?(0,l.jsx)("span",{className:"shrink-0 rounded bg-purple-100 px-1.5 py-0.5 text-xs text-purple-700",children:"本地"}):null,"op"===b?(0,l.jsx)("span",{className:"shrink-0 rounded bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700",children:"op"}):null,"rs"===b?(0,l.jsx)("span",{className:"shrink-0 rounded bg-cyan-100 px-1.5 py-0.5 text-xs text-cyan-700",children:"rs"}):null,y?(0,l.jsx)(d,{platforms:y}):null]}),u?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:u}):null,void 0!==f?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:f}):null,x||g&&g.length?(0,l.jsxs)("div",{className:"mt-0.5 flex flex-wrap items-center gap-x-2 text-xs text-gray-500",children:[x?(0,l.jsxs)("span",{children:["op:",(0,l.jsx)("span",{className:"text-gray-700",children:x})]}):null,g&&g.length?(0,l.jsxs)("span",{children:["rs:",(0,l.jsx)("span",{className:"text-gray-700",children:g.join("、")})]}):null]}):null,v?(0,l.jsx)(o,{stages:v}):null,j?(0,l.jsxs)("div",{className:"mt-0.5 flex items-center justify-between gap-2 text-xs text-gray-400",children:[(0,l.jsx)(s,{value:j}),N&&!w?(0,l.jsx)(s,{value:N}):null]}):null]})}function x(e){var t;let{name:n,headline:r,overall:a,invitationChannel:i,updatedAt:c}=e;return(0,l.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"font-medium text-gray-900",children:n}),null!=a?(0,l.jsxs)("span",{className:"rounded bg-emerald-100 px-1.5 py-0.5 text-xs text-emerald-700",children:[a,"分"]}):null,i?(0,l.jsx)("span",{className:"rounded bg-sky-100 px-1.5 py-0.5 text-xs text-sky-700",children:null!==(t=({email:"邮件",linkedin:"LinkedIn",wechat:"微信"})[i])&&void 0!==t?t:i}):null]}),r?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:r}):null,(0,l.jsx)("div",{className:"mt-0.5 text-xs text-gray-400",children:(0,l.jsx)(s,{value:c})})]})}function g(e){let{title:t,source:n,company:r,sourceUrl:a,updatedAt:i}=e;return(0,l.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsx)("span",{className:"font-medium text-gray-900",children:t}),(0,l.jsx)("span",{className:"rounded bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700",children:n})]}),r?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:r}):null,(0,l.jsxs)("div",{className:"mt-0.5 flex items-center gap-2 text-xs text-gray-400",children:[(0,l.jsx)(s,{value:i}),a?(0,l.jsx)("a",{href:a,target:"_blank",rel:"noreferrer",className:"text-blue-500 hover:underline",onClick:e=>e.stopPropagation(),children:"来源"}):null]})]})}},26119:function(e,t,n){n.d(t,{B:function(){return s}});var l=n(72835),r=n(60635),a=n(82182);function s(e){let[t,n]=(0,r.useState)(new Set),[s,i]=(0,r.useState)(null),[c,u]=(0,r.useState)(!1),[o,d]=(0,r.useState)(null),f=(0,r.useCallback)(e=>{n(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),x=(0,r.useCallback)(e=>{let t=new Set(e);n(e=>{let n=new Set(Array.from(e).filter(e=>t.has(e)));return n.size===e.size?e:n})},[]),g=(0,r.useCallback)(()=>n(new Set),[]),h=(0,r.useCallback)(e=>(0,l.jsx)("input",{type:"checkbox",className:"mt-1 accent-blue-600",checked:t.has(e),onChange:()=>f(e),onClick:e=>e.stopPropagation()}),[t,f]),m=(0,r.useCallback)(async()=>{if(!s)return;u(!0),d(null);let t=s.ids;try{var l,r;let s=await fetch(e.deleteUrl,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:t})});if(!s.ok){let l=await s.json().catch(()=>null),i=null==l?void 0:l.message;if(401===s.status){d("登录已过期,请在弹窗中重新登录;登录后自动继续删除"),(0,a.jr)({message:"string"==typeof i?i:"登录已过期,请重新登录",oldUserId:null!==(r=e.currentUserId)&&void 0!==r?r:null,retry:async()=>{var l;let r=await fetch(e.deleteUrl,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:t})});if(!r.ok){let e=await r.json().catch(()=>null),t=null==e?void 0:e.message;return d("string"==typeof t?t:"续跑删除仍失败,请稍后重试"),!1}return n(new Set),d("已删除 ".concat(t.length," 条")),null===(l=e.onDeleted)||void 0===l||l.call(e),!0}});return}d("string"==typeof i?i:"操作失败,请稍后重试");return}n(new Set),d("已删除 ".concat(t.length," 条")),null===(l=e.onDeleted)||void 0===l||l.call(e)}finally{u(!1),i(null)}},[s,e.deleteUrl,e.onDeleted,e.currentUserId]),p=(0,r.useCallback)(e=>(0,l.jsxs)("div",{className:"flex items-center gap-3 border-t border-gray-100 px-3 py-2",children:[(0,l.jsxs)("label",{className:"flex items-center gap-1.5 text-sm text-gray-600",children:[(0,l.jsx)("input",{type:"checkbox",className:"accent-blue-600",checked:e.length>0&&t.size===e.length,onChange:()=>n(t=>t.size===e.length&&e.length>0?new Set:new Set(e.map(e=>String(e.id))))}),"全选"]}),t.size>0&&(0,l.jsxs)("span",{className:"flex items-center gap-2 text-sm",children:[(0,l.jsxs)("span",{className:"text-gray-500",children:["已选 ",t.size," 条"]}),(0,l.jsx)("button",{type:"button",onClick:()=>i({ids:Array.from(t).map(Number)}),className:"rounded-lg bg-red-600 px-3 py-1 text-white hover:bg-red-700",children:"删除"})]}),o&&(0,l.jsx)("span",{className:"text-xs text-green-600",children:o})]}),[t,o]);return{selectedIds:t,checkbox:h,prune:x,bar:p,modal:(0,r.useCallback)(()=>s?(0,l.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40",children:(0,l.jsxs)("div",{className:"w-96 rounded-xl bg-white p-6 shadow-xl",children:[(0,l.jsx)("h3",{className:"text-base font-semibold text-gray-900",children:"删除确认"}),(0,l.jsxs)("p",{className:"mt-3 text-sm text-gray-600",children:["确定删除选中的 ",s.ids.length," 条",e.label,"吗?删除后不能自行恢复;如误删,请联系管理员找回。"]}),(0,l.jsxs)("div",{className:"mt-6 flex justify-end gap-2",children:[(0,l.jsx)("button",{type:"button",disabled:c,onClick:()=>i(null),className:"rounded-lg px-4 py-1.5 text-sm text-gray-600 hover:bg-gray-100",children:"取消"}),(0,l.jsx)("button",{type:"button",disabled:c,onClick:()=>void m(),className:"rounded-lg bg-red-600 px-4 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-50",children:c?"处理中…":"确定"})]})]})}):null,[s,c,m,e.label]),clear:g}}},93464:function(e,t,n){n.d(t,{k:function(){return r}});var l=n(60635);function r(e){var t,n,r;let a=null!==(t=e.pageSize)&&void 0!==t?t:50,[s,i]=(0,l.useState)([]),[c,u]=(0,l.useState)(0),[o,d]=(0,l.useState)(!0),[f,x]=(0,l.useState)(!1),[g,h]=(0,l.useState)(null),m=(0,l.useRef)(0),p=(0,l.useRef)(!1),v=(0,l.useRef)([]),y=null!==(n=e.byKey)&&void 0!==n?n:e=>String(e.id),b=(0,l.useRef)(0),j=(0,l.useCallback)(async(t,n)=>{let l=++m.current;0===t?d(!0):x(!0),h(null);try{var r;let s=await e.fetchPage(t,a);if(l!==m.current)return;b.current=null!==(r=s.nextOffset)&&void 0!==r?r:t+s.items.length,n&&0===s.items.length?u(e=>Math.min(e,v.current.length)):u(s.total),i(e=>{if(!n)return s.items;let t=new Set(e.map(y));return[...e,...s.items.filter(e=>!t.has(y(e)))]})}catch(e){if(l!==m.current)return;h(e instanceof Error?e.message:"加载失败")}finally{l===m.current&&(d(!1),x(!1),p.current=!1)}},[e.fetchPage,a]);(0,l.useEffect)(()=>{p.current=!0,j(0,!1)},[j,...null!==(r=e.deps)&&void 0!==r?r:[]]),(0,l.useEffect)(()=>{v.current=s},[s]);let N=(0,l.useCallback)(()=>{!p.current&&(v.current.length>=c||(p.current=!0,j(b.current,!0)))},[j,c]),w=(0,l.useCallback)(()=>{p.current=!0,b.current=0,j(0,!1)},[j]);return{items:s,total:c,loading:o,loadingMore:f,exhausted:!o&&s.length>=c,error:g,loadMore:N,refresh:w}}},65777:function(e,t,n){let l;n.d(t,{Cd:function(){return S},Xc:function(){return C},aG:function(){return w},cp:function(){return k},nu:function(){return N},tQ:function(){return E}});var r=n(60635),a=n(74431),s=n(67002),i=n(60529);let c=null,u=null,o=null,d=new Set;function f(){d.forEach(e=>e())}function x(e){c=c?{...c,refreshing:e}:{...y,refreshing:e},f()}async function g(){try{return await (0,a.aA)("/auth/session")}catch(e){return null}}async function h(e){let t=new Headers,n=(0,s.Xc)();n&&t.set("Authorization","UTOKEN ".concat(n));try{return await (0,a.aA)(e,{headers:t})}catch(e){return null}}async function m(){x(!0);try{var e;let[t,n]=await Promise.all([g(),h("/datasync/state")]),r=(null==t?void 0:t.loggedIn)&&t.token?t.token:null,a=null!=n?n:null;!a&&t&&r&&r!==(0,s.Xc)()?((0,s.GK)(r),a=await h("/datasync/state")):(0,s.GK)(r),function(e){if(void 0===l){l=e;return}if(e!==l){l=e;try{window.localStorage.removeItem("hm-view-mode")}catch(e){}}}((null==t?void 0:t.loggedIn)&&null!==(e=t.hmUserId)&&void 0!==e?e:null);let i=!!((null==t?void 0:t.loggedIn)||(null==a?void 0:a.loggedIn));if(!t&&!a){c=c?{...c,loadError:"本地服务无响应"}:{...y,loadError:"本地服务无响应"},f();return}c={session:null!=t?t:{loggedIn:!1},sync:a,utoken:(0,s.Xc)(),loadError:null,refreshing:!1,authStatus:i?"in":"out",refresh:p},f()}finally{(null==c?void 0:c.refreshing)&&x(!1)}}function p(){return u||(u=m().finally(()=>{u=null}))}function v(e){return d.add(e),1===d.size&&(p(),o=setInterval(()=>void p(),6e4)),()=>{d.delete(e),0===d.size&&o&&(clearInterval(o),o=null)}}let y={session:null,sync:null,utoken:null,loadError:null,refreshing:!1,authStatus:"loading",refresh:p};function b(){return null!=c?c:y}function j(){return b()}function N(){return(0,r.useSyncExternalStore)(v,b,j)}function w(e){var t;return(null!==(t=null==e?void 0:e.memberships)&&void 0!==t?t:[]).filter(e=>!e.isPersonal&&!e.leftAt)}function k(e){var t,n;let l=null!==(t=null==e?void 0:e.activeTenantId)&&void 0!==t?t:null;if(null==l)return null;let r=(null!==(n=null==e?void 0:e.memberships)&&void 0!==n?n:[]).find(e=>e.tenantId===l&&!e.leftAt);return!r||r.isPersonal?null:l}function S(e,t){var n,l;if(!t)return null;let r=(null!==(n=null==e?void 0:e.memberships)&&void 0!==n?n:[]).find(e=>e.tenantId===t&&!e.leftAt&&!e.isPersonal);return null!==(l=null==r?void 0:r.role)&&void 0!==l?l:null}function E(){return i.env.NEXT_PUBLIC_HUNTER_MATE_SERVER_URL||""}function C(){return(0,s.Xc)()}},82182:function(e,t,n){n.d(t,{H7:function(){return o},jr:function(){return s},mn:function(){return u},nk:function(){return c},qd:function(){return i}});let l=null,r=new Set;function a(){r.forEach(e=>e())}function s(e){l=e,a()}function i(){l&&(l=null,a())}function c(){return l}function u(e){return r.add(e),()=>r.delete(e)}function o(e){if(!e)return null;try{var t,n,l,r,a;let s=e.split(".")[1],i=JSON.parse(decodeURIComponent(escape(atob(s.replace(/-/g,"+").replace(/_/g,"/"))))),c=null!==(a=null!==(r=null!==(l=null==i?void 0:null===(t=i.data)||void 0===t?void 0:t._id)&&void 0!==l?l:null==i?void 0:null===(n=i.data)||void 0===n?void 0:n.id)&&void 0!==r?r:null==i?void 0:i.sub)&&void 0!==a?a:null;return"number"==typeof c?c:null}catch(e){return null}}},8448:function(e,t,n){n.d(t,{d3:function(){return l}});function l(e){return e?("string"==typeof e?new Date(e):e).toLocaleString("zh-CN",{hour12:!1}):""}},74431:function(e,t,n){n.d(t,{Ox:function(){return a},aA:function(){return c}});var l=n(67002),r=n(60529);function a(){return r.env.HUNTER_MATE_SERVER_URL||""}let s=a();class i extends Error{constructor(e,t,n){super(null!=n?n:"请求失败(".concat(e,")").concat(t?": ".concat(t):"")),this.status=e,this.path=t,this.name="HttpError"}}async function c(e,t){let n;try{n=await fetch("".concat(s).concat(e),{cache:"no-store",...function(e){let t=(0,l.Xc)();if(!t)return e;let n=new Headers(null==e?void 0:e.headers);return n.has("Authorization")||n.set("Authorization","UTOKEN ".concat(t)),{...e,headers:n}}(t)})}catch(t){throw new i(0,e,t instanceof Error?t.message:"网络错误")}if(!n.ok)throw new i(n.status,e,"HTTP ".concat(n.status));try{return await n.json()}catch(t){throw new i(n.status,e,t instanceof Error?"响应解析失败: ".concat(t.message):"响应解析失败")}}},84704:function(e,t,n){n.d(t,{mS:function(){return r}});let l={linkedin:{label:"in",fg:"#0a66c2"},builtin:{label:"bi",fg:"#5c2d91"},lagou:{label:"拉",fg:"#00b38a"},zhaopin:{label:"智",fg:"#ff7f00"},"51job":{label:"前",fg:"#ff6000"},liepin:{label:"猎",fg:"#008ccb"},boss:{label:"B",fg:"#00bebd"}};function r(e){var t;return null!==(t=l[e.replace(/^www\./,"").split(".")[0].toLowerCase()])&&void 0!==t?t:{label:e.slice(0,1).toUpperCase(),fg:"var(--brand)"}}},67002:function(e,t,n){n.d(t,{GK:function(){return s},Lc:function(){return i},Xc:function(){return a}});let l=null,r=new Set;function a(){return l}function s(e){e!==l&&(l=e,r.forEach(e=>e()))}function i(e){return r.add(e),()=>{r.delete(e)}}}}]);
|