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
|
@@ -1,565 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cr } from 'node:module';
|
|
2
|
-
import { fileURLToPath as __f2p } from 'node:url';
|
|
3
|
-
import { dirname as __dirnameFn } from 'node:path';
|
|
4
|
-
const require = __cr(import.meta.url);
|
|
5
|
-
const __filename = __f2p(import.meta.url);
|
|
6
|
-
const __dirname = __dirnameFn(__filename);
|
|
7
|
-
import {
|
|
8
|
-
load
|
|
9
|
-
} from "./chunk-SAJB6JRK.mjs";
|
|
10
|
-
|
|
11
|
-
// dist/.server-tsc/extraction/linkedin-extractor.js
|
|
12
|
-
var SECTION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
13
|
-
"About",
|
|
14
|
-
"Experience",
|
|
15
|
-
"Education",
|
|
16
|
-
"Skills",
|
|
17
|
-
"Projects",
|
|
18
|
-
"Featured",
|
|
19
|
-
"Activity",
|
|
20
|
-
"People you may know",
|
|
21
|
-
"You might like",
|
|
22
|
-
"Ad Options",
|
|
23
|
-
"Don\u2019t want to see this",
|
|
24
|
-
"Explore Premium profiles",
|
|
25
|
-
"People who follow"
|
|
26
|
-
]);
|
|
27
|
-
function isSectionLike(text) {
|
|
28
|
-
const t = text.trim();
|
|
29
|
-
if (!t)
|
|
30
|
-
return true;
|
|
31
|
-
for (const kw of SECTION_KEYWORDS) {
|
|
32
|
-
if (t.includes(kw))
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
var NON_NAME_KEYWORDS = /notifications|messages|jobs|network|home|search/i;
|
|
38
|
-
function looksLikeName(text) {
|
|
39
|
-
const t = text.trim();
|
|
40
|
-
return t.length > 0 && t.length <= 80 && !isSectionLike(t) && !NON_NAME_KEYWORDS.test(t);
|
|
41
|
-
}
|
|
42
|
-
function isPunctuationOnly(text) {
|
|
43
|
-
return /^[^\p{L}\p{N}]*$/u.test(text.trim());
|
|
44
|
-
}
|
|
45
|
-
function looksLikeLocation(text) {
|
|
46
|
-
const t = text.trim();
|
|
47
|
-
const parts = t.split(",").map((s) => s.trim()).filter(Boolean);
|
|
48
|
-
if (parts.length === 0 || parts.length > 3)
|
|
49
|
-
return false;
|
|
50
|
-
return parts.every((p) => /^[A-Za-zÀ-ſ\s'-]{2,40}$/.test(p) && !/\d/.test(p));
|
|
51
|
-
}
|
|
52
|
-
function looksLikeUrl(text) {
|
|
53
|
-
return /^https?:\/\//.test(text.trim());
|
|
54
|
-
}
|
|
55
|
-
function looksLikeFollowers(text) {
|
|
56
|
-
const t = text.trim();
|
|
57
|
-
return /followers|connections/i.test(t) || /^[\d,]+\+?\s*$/.test(t);
|
|
58
|
-
}
|
|
59
|
-
function looksLikeExperienceLocation(text) {
|
|
60
|
-
const t = text.trim();
|
|
61
|
-
if (t.length > 60)
|
|
62
|
-
return false;
|
|
63
|
-
if (/\b(Area|Region|City|Metropolitan)\b/i.test(t))
|
|
64
|
-
return true;
|
|
65
|
-
if (/^[A-Z][a-z]+(?:\s+[A-Z][a-z]+){0,5}(?:\s+(Area|Region|City|Metropolitan))?$/i.test(t))
|
|
66
|
-
return true;
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
function looksLikeDateRange(text) {
|
|
70
|
-
const t = text.trim();
|
|
71
|
-
const hasYear = /\b(19|20)\d{2}\b/.test(t);
|
|
72
|
-
const hasMonthOrPresent = /\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Present|present|至今)\b/.test(t);
|
|
73
|
-
const yearRange = /\b(19|20)\d{2}\b\s*[-–—]\s*\b(19|20)\d{2}\b/.test(t);
|
|
74
|
-
return hasYear && (hasMonthOrPresent || yearRange);
|
|
75
|
-
}
|
|
76
|
-
function firstText($, container) {
|
|
77
|
-
return $(container).text().replace(/\s+/g, " ").trim();
|
|
78
|
-
}
|
|
79
|
-
function extractLinkedInProfile(html) {
|
|
80
|
-
const $ = load(html);
|
|
81
|
-
const out = {};
|
|
82
|
-
const h2s = $("h2");
|
|
83
|
-
let name = null;
|
|
84
|
-
let nameEl = null;
|
|
85
|
-
h2s.each((_i, el) => {
|
|
86
|
-
if (name)
|
|
87
|
-
return;
|
|
88
|
-
const $el = $(el);
|
|
89
|
-
const cls = $el.attr("class") || "";
|
|
90
|
-
const parentCls = $el.parent().attr("class") || "";
|
|
91
|
-
const t = $el.text().replace(/\s+/g, " ").trim().replace(/\s*\|\s*$/, "");
|
|
92
|
-
if (looksLikeName(t) && (cls.includes("_1f667e81") || parentCls.includes("a8841267"))) {
|
|
93
|
-
name = t;
|
|
94
|
-
nameEl = $el;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
if (!name) {
|
|
98
|
-
h2s.each((_i, el) => {
|
|
99
|
-
if (name)
|
|
100
|
-
return;
|
|
101
|
-
const t = $(el).text().replace(/\s+/g, " ").trim().replace(/\s*\|\s*$/, "");
|
|
102
|
-
if (looksLikeName(t)) {
|
|
103
|
-
name = t;
|
|
104
|
-
nameEl = $(el);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
if (name)
|
|
109
|
-
out.name = name;
|
|
110
|
-
const topCard = nameEl ? nameEl.closest("section").first() : h2s.first().closest("section").first();
|
|
111
|
-
const topTexts = [];
|
|
112
|
-
topCard.find("p").each((_i, el) => {
|
|
113
|
-
const t = $(el).text().replace(/\s+/g, " ").trim();
|
|
114
|
-
if (t && !topTexts.includes(t))
|
|
115
|
-
topTexts.push(t);
|
|
116
|
-
});
|
|
117
|
-
const meaningfulTop = topTexts.filter((t) => !/^·\s*\d+(?:rd|th|nd|st)?$/.test(t));
|
|
118
|
-
if (meaningfulTop[0] && !isSectionLike(meaningfulTop[0])) {
|
|
119
|
-
out.headline = meaningfulTop[0];
|
|
120
|
-
}
|
|
121
|
-
if (meaningfulTop[1] && !isSectionLike(meaningfulTop[1]) && !isPunctuationOnly(meaningfulTop[1])) {
|
|
122
|
-
out.currentCompany = meaningfulTop[1];
|
|
123
|
-
}
|
|
124
|
-
for (let i = 0; i < meaningfulTop.length; i++) {
|
|
125
|
-
const t = meaningfulTop[i];
|
|
126
|
-
if (t === out.headline || t === out.currentCompany)
|
|
127
|
-
continue;
|
|
128
|
-
if (!out.location && looksLikeLocation(t))
|
|
129
|
-
out.location = t;
|
|
130
|
-
if (looksLikeUrl(t))
|
|
131
|
-
out.website = t;
|
|
132
|
-
if (looksLikeFollowers(t)) {
|
|
133
|
-
const next = meaningfulTop[i + 1];
|
|
134
|
-
out.followers = next && /connections|followers/i.test(next) ? `${t} ${next}` : t;
|
|
135
|
-
if (next && /connections|followers/i.test(next))
|
|
136
|
-
i++;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
const aboutH2 = h2s.filter((_i, el) => $(el).text().includes("About")).first();
|
|
140
|
-
if (aboutH2.length) {
|
|
141
|
-
let cursor = aboutH2.parent().next();
|
|
142
|
-
const summaryParts = [];
|
|
143
|
-
for (let i = 0; i < 6 && cursor.length; i++) {
|
|
144
|
-
const tag = cursor.prop("tagName")?.toLowerCase();
|
|
145
|
-
if (tag === "h2")
|
|
146
|
-
break;
|
|
147
|
-
const t = firstText($, cursor);
|
|
148
|
-
if (t.length > 20 && !isSectionLike(t))
|
|
149
|
-
summaryParts.push(t);
|
|
150
|
-
cursor = cursor.next();
|
|
151
|
-
}
|
|
152
|
-
if (summaryParts.length)
|
|
153
|
-
out.summary = summaryParts.join(" ");
|
|
154
|
-
}
|
|
155
|
-
const expH2 = h2s.filter((_i, el) => $(el).text().includes("Experience")).first();
|
|
156
|
-
if (expH2.length) {
|
|
157
|
-
const section = expH2.closest("section").first();
|
|
158
|
-
const pTexts = [];
|
|
159
|
-
section.find("p").each((_i, el) => {
|
|
160
|
-
const t = firstText($, el);
|
|
161
|
-
if (t && !isSectionLike(t))
|
|
162
|
-
pTexts.push(t);
|
|
163
|
-
});
|
|
164
|
-
const experiences = [];
|
|
165
|
-
let lastDateIdx = -1;
|
|
166
|
-
for (let i = 0; i < pTexts.length; i++) {
|
|
167
|
-
if (looksLikeDateRange(pTexts[i])) {
|
|
168
|
-
const item = { duration: pTexts[i] };
|
|
169
|
-
if (pTexts[i - 1])
|
|
170
|
-
item.company = pTexts[i - 1];
|
|
171
|
-
if (pTexts[i - 2])
|
|
172
|
-
item.title = pTexts[i - 2];
|
|
173
|
-
if (experiences.length > 0 && lastDateIdx >= 0) {
|
|
174
|
-
const desc = pTexts.slice(lastDateIdx + 1, i - 2);
|
|
175
|
-
if (desc.length) {
|
|
176
|
-
const first = desc[0];
|
|
177
|
-
if (looksLikeExperienceLocation(first)) {
|
|
178
|
-
experiences[experiences.length - 1].location = first;
|
|
179
|
-
if (desc.length > 1) {
|
|
180
|
-
experiences[experiences.length - 1].description = desc.slice(1).join(" ");
|
|
181
|
-
}
|
|
182
|
-
} else {
|
|
183
|
-
experiences[experiences.length - 1].description = desc.join(" ");
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
if (Object.keys(item).length > 1)
|
|
188
|
-
experiences.push(item);
|
|
189
|
-
lastDateIdx = i;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (experiences.length)
|
|
193
|
-
out.experiences = experiences;
|
|
194
|
-
}
|
|
195
|
-
const eduH2 = h2s.filter((_i, el) => $(el).text().includes("Education")).first();
|
|
196
|
-
if (eduH2.length) {
|
|
197
|
-
const section = eduH2.closest("section").first();
|
|
198
|
-
const pTexts = [];
|
|
199
|
-
section.find("p").each((_i, el) => {
|
|
200
|
-
const t = firstText($, el);
|
|
201
|
-
if (t && !isSectionLike(t))
|
|
202
|
-
pTexts.push(t);
|
|
203
|
-
});
|
|
204
|
-
const education = [];
|
|
205
|
-
let lastDateIdx = -1;
|
|
206
|
-
for (let i = 0; i < pTexts.length; i++) {
|
|
207
|
-
if (looksLikeDateRange(pTexts[i])) {
|
|
208
|
-
const item = { years: pTexts[i] };
|
|
209
|
-
if (pTexts[i - 2]) {
|
|
210
|
-
item.school = pTexts[i - 2];
|
|
211
|
-
item.degree = pTexts[i - 1];
|
|
212
|
-
} else if (pTexts[i - 1]) {
|
|
213
|
-
item.school = pTexts[i - 1];
|
|
214
|
-
}
|
|
215
|
-
if (Object.keys(item).length > 1)
|
|
216
|
-
education.push(item);
|
|
217
|
-
lastDateIdx = i;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (lastDateIdx >= 0 && lastDateIdx < pTexts.length - 1) {
|
|
221
|
-
const tail = pTexts.slice(lastDateIdx + 1);
|
|
222
|
-
if (tail.length >= 2) {
|
|
223
|
-
education.push({ school: tail[0], degree: tail[1] });
|
|
224
|
-
} else if (tail.length === 1) {
|
|
225
|
-
education.push({ school: tail[0] });
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (education.length)
|
|
229
|
-
out.education = education;
|
|
230
|
-
}
|
|
231
|
-
const skillH2 = h2s.filter((_i, el) => $(el).text().includes("Skills")).first();
|
|
232
|
-
if (skillH2.length) {
|
|
233
|
-
const section = skillH2.closest("section, div").first();
|
|
234
|
-
const skills = /* @__PURE__ */ new Set();
|
|
235
|
-
section.find('span, button, a, li, div[role="listitem"]').each((_i, el) => {
|
|
236
|
-
const t = firstText($, el);
|
|
237
|
-
if (t && t.length <= 50 && t.length >= 2 && !isSectionLike(t) && !looksLikeDateRange(t) && !looksLikeFollowers(t) && !looksLikeUrl(t)) {
|
|
238
|
-
skills.add(t);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
if (skills.size)
|
|
242
|
-
out.skills = Array.from(skills).slice(0, 50);
|
|
243
|
-
}
|
|
244
|
-
return out;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// dist/.server-tsc/extraction/talent-entity.js
|
|
248
|
-
var LIEPIN_CONSUMED_SECTION_KEYS = /* @__PURE__ */ new Set([
|
|
249
|
-
"single",
|
|
250
|
-
"basic-info",
|
|
251
|
-
"job-exp-info",
|
|
252
|
-
"job-expectancy-info-wrap",
|
|
253
|
-
"work-info",
|
|
254
|
-
"project-info",
|
|
255
|
-
"edu-info",
|
|
256
|
-
"lang-info",
|
|
257
|
-
"skill-info",
|
|
258
|
-
"self-eva-info",
|
|
259
|
-
"self-evaluation-info",
|
|
260
|
-
"operation-wrap"
|
|
261
|
-
]);
|
|
262
|
-
var LIEPIN_WORK_KNOWN_COLS = /* @__PURE__ */ new Set([
|
|
263
|
-
"\u6240\u5728\u90E8\u95E8",
|
|
264
|
-
"\u5DE5\u4F5C\u5730\u70B9",
|
|
265
|
-
"\u4E0B\u5C5E\u4EBA\u6570",
|
|
266
|
-
"\u6C47\u62A5\u5BF9\u8C61",
|
|
267
|
-
"\u804C\u8D23\u4E1A\u7EE9"
|
|
268
|
-
]);
|
|
269
|
-
var LIEPIN_PROJECT_KNOWN_COLS = /* @__PURE__ */ new Set(["\u9879\u76EE\u804C\u52A1", "\u6240\u5728\u516C\u53F8", "\u9879\u76EE\u63CF\u8FF0", "\u9879\u76EE\u804C\u8D23"]);
|
|
270
|
-
function pickUnmappedCols(cols, known) {
|
|
271
|
-
const out = {};
|
|
272
|
-
for (const [k, v] of Object.entries(cols)) {
|
|
273
|
-
if (!known.has(k))
|
|
274
|
-
out[k] = v;
|
|
275
|
-
}
|
|
276
|
-
return Object.keys(out).length ? out : void 0;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// dist/.server-tsc/extraction/liepin-extractor.js
|
|
280
|
-
var clean = (s) => {
|
|
281
|
-
if (s == null)
|
|
282
|
-
return null;
|
|
283
|
-
const t = s.replace(/\s+/g, " ").trim();
|
|
284
|
-
return t || null;
|
|
285
|
-
};
|
|
286
|
-
function splitByI($, el) {
|
|
287
|
-
const html = $(el).html() || "";
|
|
288
|
-
return html.replace(/<i[^>]*>\s*<\/i>/g, "|").split("|").map((s) => clean($(s).text?.() ?? s) ?? clean(s.replace(/<[^>]+>/g, ""))).map((s) => s || "").filter(Boolean);
|
|
289
|
-
}
|
|
290
|
-
function parsePeriod(text) {
|
|
291
|
-
const m = text.match(/[((]\s*([^))]*?)\s*[))]/);
|
|
292
|
-
if (!m)
|
|
293
|
-
return { start: null, end: null, duration: null };
|
|
294
|
-
const parts = m[1].split(",").map((s) => clean(s)).filter(Boolean);
|
|
295
|
-
const range = (parts[0] || "").split("-").map((s) => clean(s));
|
|
296
|
-
return {
|
|
297
|
-
start: range[0] || null,
|
|
298
|
-
end: range[1] || null,
|
|
299
|
-
duration: parts[1] || null
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
function readInfoCols($, root) {
|
|
303
|
-
const out = {};
|
|
304
|
-
root.find(".rd-info-col").each((_i, col) => {
|
|
305
|
-
const title = clean($(col).find(".rd-info-col-title").first().text());
|
|
306
|
-
const cont = clean($(col).find(".rd-info-col-cont").first().text());
|
|
307
|
-
if (title && cont)
|
|
308
|
-
out[title.replace(/[::]\s*$/, "")] = cont;
|
|
309
|
-
});
|
|
310
|
-
return out;
|
|
311
|
-
}
|
|
312
|
-
function extractBasic($) {
|
|
313
|
-
const root = $("#resume-detail-basic-info, .resume-detail-basic-info").first();
|
|
314
|
-
if (!root.length)
|
|
315
|
-
return {};
|
|
316
|
-
const name = clean(root.find(".name-box .name").first().text());
|
|
317
|
-
const sepInfos = root.find(".basic-cont .sep-info, .sep-info").toArray();
|
|
318
|
-
const sepParts = sepInfos.map((el) => splitByI($, el));
|
|
319
|
-
const contactIdx = sepParts.findIndex((p) => /方便联系时间/.test(p.join(" ")));
|
|
320
|
-
const personalIdx = sepParts.findIndex((p) => /岁|工作\s*\d+\s*年/.test(p.join(" ")));
|
|
321
|
-
const partsP = personalIdx >= 0 ? sepParts[personalIdx] : sepParts[0] ?? [];
|
|
322
|
-
const companyIdx = sepParts.findIndex((p, i) => i !== personalIdx && i !== contactIdx && p.join(" ").trim().length > 0);
|
|
323
|
-
const partsC = companyIdx >= 0 ? sepParts[companyIdx] : [];
|
|
324
|
-
const joined0 = partsP.join(" ");
|
|
325
|
-
const age = joined0.match(/(\d+)\s*岁/)?.[1] ?? null;
|
|
326
|
-
const workYears = joined0.match(/工作\s*(\d+)\s*年/)?.[1] ?? null;
|
|
327
|
-
const gender = partsP.find((p) => /^(男|女)$/.test(p)) ?? null;
|
|
328
|
-
const currentPosition = partsC.length ? partsC[0] : null;
|
|
329
|
-
const personalLast = partsP.length ? partsP[partsP.length - 1] ?? null : null;
|
|
330
|
-
const companyFromLine = partsC.length > 1 ? partsC.slice(1).join(" ") : null;
|
|
331
|
-
const currentCompany = personalLast === "\u4FDD\u5BC6" ? "\u4FDD\u5BC6" : companyFromLine ?? personalLast;
|
|
332
|
-
const companyMasked = currentCompany === "\u4FDD\u5BC6" ? true : partsP.includes("\u4FDD\u5BC6") || (currentCompany ? /保密/.test(currentCompany) : false) ? true : void 0;
|
|
333
|
-
const contactTimeRaw = clean(root.find(".res-status-box").first().text());
|
|
334
|
-
return {
|
|
335
|
-
name,
|
|
336
|
-
nameMasked: name ? /\*/.test(name) : void 0,
|
|
337
|
-
statusTag: clean(root.find(".user-status-tag").first().text()),
|
|
338
|
-
gender,
|
|
339
|
-
age: age ? Number(age) : null,
|
|
340
|
-
city: partsP.find((p) => /^(北京|上海|广州|深圳|天津|重庆|杭州|南京|苏州|成都|武汉|西安)$/.test(p)) ?? partsP.find((p) => /^[一-鿿]{2,6}$/.test(p) && !/^(男|女|保密)$/.test(p) && !/岁|年/.test(p) && !/(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(p)) ?? null,
|
|
341
|
-
degree: partsP.find((p) => /(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(p)) ?? null,
|
|
342
|
-
workYears: workYears ? Number(workYears) : null,
|
|
343
|
-
workYearsText: joined0.match(/工作[^|]*/) ? joined0.match(/工作\s*\d+\s*年/)?.[0] ?? null : null,
|
|
344
|
-
currentCompany: currentCompany ?? null,
|
|
345
|
-
currentCompanyMasked: companyMasked,
|
|
346
|
-
currentPosition,
|
|
347
|
-
contactTime: contactTimeRaw ? contactTimeRaw.replace(/^方便联系时间[::]\s*/, "") : null,
|
|
348
|
-
photoUrl: root.find(".logo-box img").first().attr("src") ?? null
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
function extractIntent($) {
|
|
352
|
-
const root = $("#resume-detail-job-exp-info, .resume-detail-job-expectancy-info-wrap").first();
|
|
353
|
-
if (!root.length)
|
|
354
|
-
return {};
|
|
355
|
-
const labels = root.find(".lebels-wrap span").toArray().map((el) => clean($(el).text())).filter(Boolean);
|
|
356
|
-
return {
|
|
357
|
-
position: clean(root.find(".tabs .title").first().attr("title")) ?? clean(root.find(".tabs .title").first().text()),
|
|
358
|
-
salary: clean(root.find(".tabs .salary").first().text()),
|
|
359
|
-
city: clean(root.find(".dqname-wrap").first().text()),
|
|
360
|
-
industries: labels
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
function extractWorkExperiences($) {
|
|
364
|
-
const out = [];
|
|
365
|
-
$("#resume-detail-work-info .rd-work-item-cont, .resume-detail-work-info .rd-info-tpl-item").each((_i, el) => {
|
|
366
|
-
const item = $(el);
|
|
367
|
-
const periodText = clean(item.find(".rd-work-time").first().text()) ?? "";
|
|
368
|
-
const cols = readInfoCols($, item);
|
|
369
|
-
const extra = pickUnmappedCols(cols, LIEPIN_WORK_KNOWN_COLS);
|
|
370
|
-
out.push({
|
|
371
|
-
company: clean(item.find(".rd-work-comp h5").first().attr("title")) ?? clean(item.find(".rd-work-comp h5").first().text()),
|
|
372
|
-
...parsePeriod(periodText),
|
|
373
|
-
position: clean(item.find(".job-name").first().text()),
|
|
374
|
-
department: cols["\u6240\u5728\u90E8\u95E8"] ?? null,
|
|
375
|
-
location: cols["\u5DE5\u4F5C\u5730\u70B9"] ?? null,
|
|
376
|
-
subordinates: cols["\u4E0B\u5C5E\u4EBA\u6570"] != null ? Number(cols["\u4E0B\u5C5E\u4EBA\u6570"]) : null,
|
|
377
|
-
reportsTo: cols["\u6C47\u62A5\u5BF9\u8C61"] ?? null,
|
|
378
|
-
responsibilities: cols["\u804C\u8D23\u4E1A\u7EE9"] ?? null,
|
|
379
|
-
...extra ? { extra } : {}
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
return out;
|
|
383
|
-
}
|
|
384
|
-
function extractProjects($) {
|
|
385
|
-
const out = [];
|
|
386
|
-
$("#resume-detail-project-info .rd-project-item-cont, .resume-detail-project-info .rd-project-item-cont, .resume-detail-project-info .rd-info-tpl-item").each((_i, el) => {
|
|
387
|
-
const item = $(el);
|
|
388
|
-
const periodText = clean(item.find(".rd-project-time").first().text()) ?? "";
|
|
389
|
-
const cols = readInfoCols($, item);
|
|
390
|
-
const extra = pickUnmappedCols(cols, LIEPIN_PROJECT_KNOWN_COLS);
|
|
391
|
-
out.push({
|
|
392
|
-
name: clean(item.find(".rd-project-name h5").first().attr("title")) ?? clean(item.find(".rd-project-name h5").first().text()),
|
|
393
|
-
...parsePeriod(periodText),
|
|
394
|
-
role: cols["\u9879\u76EE\u804C\u52A1"] ?? null,
|
|
395
|
-
company: cols["\u6240\u5728\u516C\u53F8"] ?? null,
|
|
396
|
-
description: cols["\u9879\u76EE\u63CF\u8FF0"] ?? null,
|
|
397
|
-
duties: cols["\u9879\u76EE\u804C\u8D23"] ?? null,
|
|
398
|
-
...extra ? { extra } : {}
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
return out;
|
|
402
|
-
}
|
|
403
|
-
function extractEducation($) {
|
|
404
|
-
const out = [];
|
|
405
|
-
$("#resume-detail-edu-info .rd-edu-info-item, .resume-detail-edu-info .rd-edu-info-item").each((_i, el) => {
|
|
406
|
-
const item = $(el);
|
|
407
|
-
const raw = clean(item.text()) ?? "";
|
|
408
|
-
const segs = raw.split("\xB7").map((s) => clean(s)).filter(Boolean);
|
|
409
|
-
const periodM = raw.match(/\d{4}\.\d{2}\s*-\s*(?:\d{4}\.\d{2}|至今)/);
|
|
410
|
-
const segEdu = (segs.length > 2 ? segs[2] : segs.length > 1 ? segs[1] : "").match(/(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/);
|
|
411
|
-
out.push({
|
|
412
|
-
school: clean(item.find(".school-name").first().attr("title")) ?? clean(item.find(".school-name").first().text()),
|
|
413
|
-
major: clean(item.find(".school-special").first().attr("title")) ?? clean(item.find(".school-special").first().text()) ?? (segs.length > 1 ? /^(博士|硕士|MBA|本科|大专|专科|高中|中专|初中)/.test(segs[1]) ? null : segs[1] : null),
|
|
414
|
-
degree: clean(item.find(".school-degree").first().attr("title")) ?? clean(item.find(".school-degree").first().text()) ?? (segEdu ? segEdu[0] : null),
|
|
415
|
-
period: clean(item.find(".school-time").first().text()) ?? (periodM ? periodM[0] : null),
|
|
416
|
-
tags: item.find(".edu-school-tags .tag-item, .tag-item").toArray().map((t) => clean($(t).text())).filter(Boolean)
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
return out;
|
|
420
|
-
}
|
|
421
|
-
function extractResId($) {
|
|
422
|
-
const scm = $("[data-tlg-scm]").first().attr("data-tlg-scm") || "";
|
|
423
|
-
const m = scm.match(/cid=([^&]+)/);
|
|
424
|
-
return m?.[1] ?? null;
|
|
425
|
-
}
|
|
426
|
-
function sweepExtraSections($) {
|
|
427
|
-
const sections = [];
|
|
428
|
-
const seen = /* @__PURE__ */ new Set();
|
|
429
|
-
$('[id^="resume-detail-"], [class*="resume-detail-"]').each((_i, el) => {
|
|
430
|
-
const $el = $(el);
|
|
431
|
-
const id = $el.attr("id") || "";
|
|
432
|
-
const cls = ($el.attr("class") || "").split(/\s+/).find((c) => c.startsWith("resume-detail-") && c !== "resume-detail-template" && c !== "resume-detail-template-cont") || "";
|
|
433
|
-
const key = (id || cls).replace(/^resume-detail-/, "");
|
|
434
|
-
if (!key || seen.has(key))
|
|
435
|
-
return;
|
|
436
|
-
const isSection = $el.find(".resume-detail-template-cont").length > 0 || $el.parents('[id^="resume-detail-"], [class*="resume-detail-"]').length === 0;
|
|
437
|
-
if (!isSection)
|
|
438
|
-
return;
|
|
439
|
-
seen.add(key);
|
|
440
|
-
if (LIEPIN_CONSUMED_SECTION_KEYS.has(key))
|
|
441
|
-
return;
|
|
442
|
-
const text = clean($el.text());
|
|
443
|
-
if (!text)
|
|
444
|
-
return;
|
|
445
|
-
const title = clean($el.find(".resume-detail-template-title, .template-title").first().text()) ?? clean($el.find("h3, h4").first().text());
|
|
446
|
-
sections.push({ key, title, text: text.length > 2e3 ? `${text.slice(0, 2e3)}\u2026` : text });
|
|
447
|
-
});
|
|
448
|
-
return sections;
|
|
449
|
-
}
|
|
450
|
-
function extractLiepinTalent(html) {
|
|
451
|
-
const $ = load(html);
|
|
452
|
-
const isTalentPage = $("#resume-detail-basic-info, .resume-detail-basic-info").length > 0;
|
|
453
|
-
if (!isTalentPage)
|
|
454
|
-
return { platform: "liepin", pageType: "unknown" };
|
|
455
|
-
const languages = $("#resume-detail-lang-info .rd-lang-item .lang-name, .resume-detail-lang-info .rd-lang-item .lang-name").toArray().map((el) => clean($(el).text())).filter(Boolean);
|
|
456
|
-
const skills = $("#resume-detail-skill-info .skill-tag, .resume-detail-skill-info .skill-tag").toArray().map((el) => clean($(el).text())).filter(Boolean);
|
|
457
|
-
const basic = extractBasic($);
|
|
458
|
-
const workExperiences = extractWorkExperiences($);
|
|
459
|
-
const projects = extractProjects($);
|
|
460
|
-
const education = extractEducation($);
|
|
461
|
-
const extraSections = sweepExtraSections($);
|
|
462
|
-
return {
|
|
463
|
-
platform: "liepin",
|
|
464
|
-
pageType: "talent",
|
|
465
|
-
resId: extractResId($),
|
|
466
|
-
...basic,
|
|
467
|
-
intent: extractIntent($),
|
|
468
|
-
workExperiences,
|
|
469
|
-
projects,
|
|
470
|
-
education,
|
|
471
|
-
languages,
|
|
472
|
-
skills,
|
|
473
|
-
selfEvaluation: clean($("#resume-detail-self-eva-info .resume-detail-template-cont").first().text()) ?? clean($(".resume-detail-self-evaluation-info").first().text()),
|
|
474
|
-
statement: clean($(".c-detail-statement").first().text()),
|
|
475
|
-
hasAntiScrapeWatermark: $(".cozue").length > 0,
|
|
476
|
-
...extraSections.length ? { extra: { sections: extraSections } } : {},
|
|
477
|
-
_counts: {
|
|
478
|
-
workExperiences: workExperiences.length,
|
|
479
|
-
projects: projects.length,
|
|
480
|
-
education: education.length,
|
|
481
|
-
languages: languages.length,
|
|
482
|
-
skills: skills.length,
|
|
483
|
-
extraSections: extraSections.length
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
// dist/.server-tsc/extraction/script-rule.js
|
|
489
|
-
function readField($, root, rule) {
|
|
490
|
-
const el = rule.self ? root.first() : root.find(rule.selector).first();
|
|
491
|
-
if (!el.length)
|
|
492
|
-
return null;
|
|
493
|
-
let value;
|
|
494
|
-
if (!rule.attr || rule.attr === "text")
|
|
495
|
-
value = el.text().trim();
|
|
496
|
-
else if (rule.attr === "html")
|
|
497
|
-
value = el.html();
|
|
498
|
-
else
|
|
499
|
-
value = el.attr(rule.attr) ?? null;
|
|
500
|
-
if (value == null)
|
|
501
|
-
return null;
|
|
502
|
-
if (rule.regex) {
|
|
503
|
-
const m = value.match(new RegExp(rule.regex, "s"));
|
|
504
|
-
value = m?.[1]?.trim() ?? null;
|
|
505
|
-
}
|
|
506
|
-
return value || null;
|
|
507
|
-
}
|
|
508
|
-
function applyScriptRule(html, payload) {
|
|
509
|
-
if (payload.engine === "linkedin-profile") {
|
|
510
|
-
return extractLinkedInProfile(html);
|
|
511
|
-
}
|
|
512
|
-
if (payload.engine === "liepin-talent") {
|
|
513
|
-
return extractLiepinTalent(html);
|
|
514
|
-
}
|
|
515
|
-
const $ = load(html);
|
|
516
|
-
const out = {};
|
|
517
|
-
for (const [field, rule] of Object.entries(payload.fields || {})) {
|
|
518
|
-
out[field] = readField($, $("body").length ? $("body") : $.root(), rule);
|
|
519
|
-
}
|
|
520
|
-
for (const [listName, listRule] of Object.entries(payload.lists || {})) {
|
|
521
|
-
const items = [];
|
|
522
|
-
$(listRule.selector).each((_i, el) => {
|
|
523
|
-
const item = {};
|
|
524
|
-
for (const [field, rule] of Object.entries(listRule.fields)) {
|
|
525
|
-
item[field] = readField($, $(el), rule);
|
|
526
|
-
}
|
|
527
|
-
if (Object.values(item).some((v) => v != null))
|
|
528
|
-
items.push(item);
|
|
529
|
-
});
|
|
530
|
-
if (items.length) {
|
|
531
|
-
const seen = /* @__PURE__ */ new Set();
|
|
532
|
-
out[listName] = items.filter((item) => {
|
|
533
|
-
const key = JSON.stringify(item, Object.keys(item).sort());
|
|
534
|
-
if (seen.has(key))
|
|
535
|
-
return false;
|
|
536
|
-
seen.add(key);
|
|
537
|
-
return true;
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
if (payload.entityList) {
|
|
542
|
-
const items = [];
|
|
543
|
-
$(payload.entityList.selector).each((_i, el) => {
|
|
544
|
-
const item = {};
|
|
545
|
-
for (const [field, rule] of Object.entries(payload.entityList.fields)) {
|
|
546
|
-
item[field] = readField($, $(el), rule);
|
|
547
|
-
}
|
|
548
|
-
if (Object.values(item).some((v) => v != null))
|
|
549
|
-
items.push(item);
|
|
550
|
-
});
|
|
551
|
-
const seen = /* @__PURE__ */ new Set();
|
|
552
|
-
out.__entityList = items.filter((item) => {
|
|
553
|
-
const key = JSON.stringify(item, Object.keys(item).sort());
|
|
554
|
-
if (seen.has(key))
|
|
555
|
-
return false;
|
|
556
|
-
seen.add(key);
|
|
557
|
-
return true;
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
return out;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
export {
|
|
564
|
-
applyScriptRule
|
|
565
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cr } from 'node:module';
|
|
2
|
-
import { fileURLToPath as __f2p } from 'node:url';
|
|
3
|
-
import { dirname as __dirnameFn } from 'node:path';
|
|
4
|
-
const require = __cr(import.meta.url);
|
|
5
|
-
const __filename = __f2p(import.meta.url);
|
|
6
|
-
const __dirname = __dirnameFn(__filename);
|
|
7
|
-
import {
|
|
8
|
-
contains,
|
|
9
|
-
esm_default,
|
|
10
|
-
html,
|
|
11
|
-
load,
|
|
12
|
-
merge,
|
|
13
|
-
parseHTML,
|
|
14
|
-
root,
|
|
15
|
-
text,
|
|
16
|
-
xml
|
|
17
|
-
} from "./chunk-SAJB6JRK.mjs";
|
|
18
|
-
import "./chunk-GNM26E3H.mjs";
|
|
19
|
-
export {
|
|
20
|
-
contains,
|
|
21
|
-
esm_default as default,
|
|
22
|
-
html,
|
|
23
|
-
load,
|
|
24
|
-
merge,
|
|
25
|
-
parseHTML,
|
|
26
|
-
root,
|
|
27
|
-
text,
|
|
28
|
-
xml
|
|
29
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
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]="52f3f658-a1d6-4559-836f-ba5a541ddddd",e._sentryDebugIdIdentifier="sentry-dbid-52f3f658-a1d6-4559-836f-ba5a541ddddd")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[954],{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?"没有更多了":""})]})}},65912:function(e,t,n){n.d(t,{dy:function(){return d},h5:function(){return f},oj:function(){return s},rY:function(){return x}});var l=n(72835),r=n(8448),a=n(84704);function s(e){let{name:t,headline:n,source:a,updatedAt:s}=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:[a?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("span",{children:a}),(0,l.jsx)("span",{children:"\xb7"})]}):null,(0,l.jsx)("span",{children:(0,r.d3)(s)})]})]})}let i={active:"启动中",closed:"结束"},c={recommended:"推",pending_invite:"邀",invited:"发",replied:"复",to_client:"客",interview_pending:"面",interview_scheduled:"试",offer_pending:"o",onboarding:"到",rejected:"否"};function u(e){let{stages:t}=e,n=Object.keys(t);if(!n.length)return null;let r=0,a=0;for(let e of n)r+=t[e].week,a+=t[e].total;return(0,l.jsxs)("div",{className:"mt-1",children:[(0,l.jsx)("div",{className:"flex gap-px overflow-hidden rounded",children:n.map(e=>{var n;let r=t[e],a=r.total>0;return(0,l.jsxs)("span",{title:"".concat(e,": 本周 ").concat(r.week," / 总 ").concat(r.total),className:"flex-1 py-0.5 text-center text-[9px] leading-none ".concat(a?"text-white":"bg-gray-100 text-gray-300"),style:a?{background:"var(--brand)"}:void 0,children:[null!==(n=c[e])&&void 0!==n?n:e.slice(0,1),r.total>0?r.total:""]},e)})}),(0,l.jsxs)("div",{className:"mt-0.5 text-[10px] text-gray-400",children:["本周 +",r," \xb7 共 ",a]})]})}function o(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,a.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 d(e){var t;let{title:n,status:a,hmhLocal:s,subtitle:c,customerName:d,time:f,stages:x,platforms:h,apps:m,myRole:g}=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}),(0,l.jsx)("span",{className:"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!==(t=i[a])&&void 0!==t?t:a}),s?(0,l.jsx)("span",{className:"rounded bg-purple-100 px-1.5 py-0.5 text-xs text-purple-700",children:"本地"}):null,"op"===g?(0,l.jsx)("span",{className:"rounded bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700",children:"op"}):null,"rs"===g?(0,l.jsx)("span",{className:"rounded bg-cyan-100 px-1.5 py-0.5 text-xs text-cyan-700",children:"rs"}):null,h?(0,l.jsx)(o,{platforms:h}):null]}),c?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:c}):null,void 0!==d?(0,l.jsx)("div",{className:"text-xs text-gray-500",children:d}):null,x?(0,l.jsx)(u,{stages:x}):null,m?(0,l.jsxs)("div",{className:"mt-0.5 text-[10px] text-gray-400",children:["简历:本周 ",m.week," / 共 ",m.total]}):null,(0,l.jsx)("div",{className:"mt-0.5 text-xs text-gray-400",children:(0,r.d3)(f)})]})}function f(e){var t;let{name:n,headline:a,overall:s,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!=s?(0,l.jsxs)("span",{className:"rounded bg-emerald-100 px-1.5 py-0.5 text-xs text-emerald-700",children:[s,"分"]}):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]}),a?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:a}):null,(0,l.jsx)("div",{className:"mt-0.5 text-xs text-gray-400",children:(0,r.d3)(c)})]})}function x(e){let{title:t,source:n,company:a,sourceUrl:s,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})]}),a?(0,l.jsx)("div",{className:"truncate text-xs text-gray-500",children:a}):null,(0,l.jsxs)("div",{className:"mt-0.5 flex items-center gap-2 text-xs text-gray-400",children:[(0,l.jsx)("span",{children:(0,r.d3)(i)}),s?(0,l.jsx)("a",{href:s,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})},[]),h=(0,r.useCallback)(()=>n(new Set),[]),m=(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]),g=(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:m,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 g(),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,g,e.label]),clear:h}}},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),[h,m]=(0,l.useState)(null),g=(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=++g.current;0===t?d(!0):x(!0),m(null);try{var r;let s=await e.fetchPage(t,a);if(l!==g.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!==g.current)return;m(e instanceof Error?e.message:"加载失败")}finally{l===g.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 w=(0,l.useCallback)(()=>{!p.current&&(v.current.length>=c||(p.current=!0,j(b.current,!0)))},[j,c]),N=(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:h,loadMore:w,refresh:N}}},65777:function(e,t,n){let l;n.d(t,{Cd:function(){return S},Xc:function(){return C},aG:function(){return N},cp:function(){return k},nu:function(){return w},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 h(){try{return await (0,a.aA)("/auth/session")}catch(e){return null}}async function m(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 g(){x(!0);try{var e;let[t,n]=await Promise.all([h(),m("/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 m("/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=g().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 w(){return(0,r.useSyncExternalStore)(v,b,j)}function N(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)}}}}]);
|