Extract memind_adm admin server, add local dev tooling, and remove image-generation.
Split platform admin and ops APIs into standalone admin-server.mjs with network guards; simplify billing to RMB token pricing, refactor user auth, and add rsync deploy plus local-test scripts and docs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,96 +23,11 @@ function loadEnvFile(filePath) {
|
||||
loadEnvFile(path.join(root, '../../.env.local'));
|
||||
loadEnvFile(path.join(root, '.env'));
|
||||
|
||||
const COVER_QUALITY = 'auto=format&fit=crop&w=1920&h=1200&q=90';
|
||||
|
||||
const CATEGORY_IMAGE_POOLS = {
|
||||
'work-report': [
|
||||
`https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1460925895917-afdab827c52f?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1551288049-bebda4e38f71?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1522071820081-009f0129c71c?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1504384308090-c894fdcc538d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1542744173-8e7e53415bb0?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1600880292203-757bb62b4baf?${COVER_QUALITY}`,
|
||||
],
|
||||
'study-notes': [
|
||||
`https://images.unsplash.com/photo-1456513080510-7bf3a84b82f8?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1516116216624-53e697fedbea?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1515879214367-846362d3526?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1676299085922-0a9a504459f8?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1516321318423-f06f85e504b3?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1434030216411-0b793f4b4173?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1503676260728-1c00da094a0b?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1524995998267-8169c4e50d05?${COVER_QUALITY}`,
|
||||
],
|
||||
creative: [
|
||||
`https://images.unsplash.com/photo-1513364776144-60967b0f800f?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1514565131-fce0801e5785?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1511379938544-be09687a4d4b?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1541961017774-22349e4a1262?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1558591710-4b4a1ae0f04d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1561998338-13ad7886534d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?${COVER_QUALITY}`,
|
||||
],
|
||||
business: [
|
||||
`https://images.unsplash.com/photo-1441986300917-64674bd600d8?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1518611012118-696072aa579a?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1554118811-1e0d58224f24?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1447933601403-0c6688de566e?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1560472354-b33ff0c44a43?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1414235077428-338989a2e8c0?${COVER_QUALITY}`,
|
||||
],
|
||||
travel: [
|
||||
`https://images.unsplash.com/photo-1506905925346-21bda4d32df4?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1596422846544-75c675fcd5d0?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1493976040374-85c8e577f47e?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1488646953014-85cb44e25828?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1476514525535-07fb3b4fcc5f?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1501785888041-af3ef285b470?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1528127269322-539801943592?${COVER_QUALITY}`,
|
||||
],
|
||||
'data-analysis': [
|
||||
`https://images.unsplash.com/photo-1551288049-bebda4e38f71?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1543286386-713bdd548da4?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1504868584819-f8e8b4b6d7e3?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1555949963-aa79dcee981c?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1518186285589-2f7649de83e0?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1573164713714-d95e436ab8d6?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1639322537504-6427a16b0a28?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1591696205602-2f950c417cb9?${COVER_QUALITY}`,
|
||||
],
|
||||
lifestyle: [
|
||||
`https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1497215842964-222b430dc094?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1455390582260-0446deae2f3f?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1416879595882-3373a0480b5b?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1498805903192-2f734adc632a?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1517487881594-2787fef5ebf7?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1556911220-e15b29be8c8f?${COVER_QUALITY}`,
|
||||
],
|
||||
other: [
|
||||
`https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1484480974693-6ca0a7823cce?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1516321318423-f06f85e504b3?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1529156069898-49953e39b3ac?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1522202176988-66273c2fd55f?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1515378792601-1a587fd37b2d?${COVER_QUALITY}`,
|
||||
`https://images.unsplash.com/photo-1523240795612-9a054b0db644?${COVER_QUALITY}`,
|
||||
],
|
||||
};
|
||||
|
||||
const COVER_SPECS = [
|
||||
{
|
||||
match: 'Q2 产品增长复盘',
|
||||
file: 'work-report-growth.jpg',
|
||||
url: `https://images.unsplash.com/photo-1551288049-bebda4e38f71?${COVER_QUALITY}`,
|
||||
url: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=1280&h=800&q=85',
|
||||
},
|
||||
{
|
||||
match: 'AI 客服落地',
|
||||
@@ -222,36 +137,21 @@ const CATEGORY_FALLBACKS = {
|
||||
other: 'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=1280&h=800&q=85',
|
||||
};
|
||||
|
||||
function hashTitle(title) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < title.length; i += 1) {
|
||||
hash = (hash * 31 + title.charCodeAt(i)) >>> 0;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
function coverFileName(categorySlug, title) {
|
||||
const hash = hashTitle(title).toString(36);
|
||||
const asciiSlug = String(title)
|
||||
.normalize('NFKD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
function slugify(value) {
|
||||
return String(value)
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/[^\p{L}\p{N}]+/gu, '-')
|
||||
.replace(/^-+|-+$/g, '')
|
||||
.slice(0, 32);
|
||||
const suffix = asciiSlug ? `${asciiSlug}-${hash}` : hash;
|
||||
return `${categorySlug}-${suffix}.jpg`;
|
||||
.slice(0, 48);
|
||||
}
|
||||
|
||||
function resolveSpec(title, categorySlug) {
|
||||
const spec = COVER_SPECS.find((item) => title.includes(item.match));
|
||||
if (spec) return spec;
|
||||
const pool = CATEGORY_IMAGE_POOLS[categorySlug] ?? CATEGORY_IMAGE_POOLS.other;
|
||||
const url = pool[hashTitle(title) % pool.length];
|
||||
return {
|
||||
match: title,
|
||||
file: coverFileName(categorySlug, title),
|
||||
url,
|
||||
file: `${categorySlug}-${slugify(title)}.jpg`,
|
||||
url: CATEGORY_FALLBACKS[categorySlug] ?? CATEGORY_FALLBACKS.other,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -308,7 +208,7 @@ const [posts] = await pool.query(
|
||||
let updated = 0;
|
||||
for (const post of posts) {
|
||||
const spec = resolveSpec(post.title, post.category_slug);
|
||||
await downloadCover(spec, (CATEGORY_IMAGE_POOLS[post.category_slug] ?? CATEGORY_IMAGE_POOLS.other)[0]);
|
||||
await downloadCover(spec, CATEGORY_FALLBACKS[post.category_slug]);
|
||||
const coverUrl = `${coverBase}/${spec.file}`;
|
||||
if (post.cover_url === coverUrl) continue;
|
||||
await pool.query(`UPDATE plaza_posts SET cover_url = ?, updated_at = ? WHERE id = ?`, [
|
||||
|
||||
Reference in New Issue
Block a user