Files
dukang/scripts/upload-mini-user-static.mjs
T
2026-08-30 15:07:58 +08:00

123 lines
3.8 KiB
JavaScript

/**
* 把本地文件上传到 OSS `static/mini-user/`(不进小程序主包)。
* 凭证优先读 system_config,其次 server/dukang-api/.env。
*
* 用法:node scripts/upload-mini-user-static.mjs <localFile> [objectName]
*/
import { readFileSync, existsSync } from 'node:fs';
import { basename, resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createRequire } from 'node:module';
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, '..');
const apiRoot = resolve(root, 'server/dukang-api');
const require = createRequire(resolve(apiRoot, 'package.json'));
const OSS = require('ali-oss');
const { PrismaClient } = require('@prisma/client');
function loadEnvFile(path) {
if (!existsSync(path)) return;
for (const line of readFileSync(path, 'utf8').split(/\r?\n/)) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
const eq = trimmed.indexOf('=');
if (eq <= 0) continue;
const key = trimmed.slice(0, eq).trim();
let value = trimmed.slice(eq + 1).trim();
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
if (process.env[key] === undefined) process.env[key] = value;
}
}
loadEnvFile(resolve(apiRoot, '.env'));
loadEnvFile(resolve(apiRoot, '.env.local'));
const localFile = process.argv[2];
if (!localFile) {
console.error('用法:node scripts/upload-mini-user-static.mjs <localFile> [objectName]');
process.exit(1);
}
const absFile = resolve(process.cwd(), localFile);
if (!existsSync(absFile)) {
console.error(`文件不存在:${absFile}`);
process.exit(1);
}
const objectName = process.argv[3] || basename(absFile);
const ossKey = `static/mini-user/${objectName.replace(/^\/+/, '')}`;
const prisma = new PrismaClient();
const rows = await prisma.systemConfig.findMany({
where: {
configKey: {
in: [
'OSS_ACCESS_KEY_ID',
'OSS_ACCESS_KEY_SECRET',
'OSS_BUCKET',
'OSS_REGION',
'OSS_ENDPOINT',
'OSS_CDN_BASE',
'OSS_AUTHORIZATION_V4',
'MINI_USER_STATIC_OSS_BASE',
],
},
},
});
await prisma.$disconnect();
for (const row of rows) {
if (row.value?.trim()) process.env[row.configKey] = row.value.trim();
}
const accessKeyId = process.env.OSS_ACCESS_KEY_ID ?? '';
const accessKeySecret = process.env.OSS_ACCESS_KEY_SECRET ?? '';
const bucket = process.env.OSS_BUCKET ?? '';
const region = process.env.OSS_REGION ?? 'oss-cn-hangzhou';
const endpoint = process.env.OSS_ENDPOINT ?? '';
const cdnBase = (process.env.OSS_CDN_BASE ?? '').replace(/\/$/, '');
const staticBase = (process.env.MINI_USER_STATIC_OSS_BASE ?? '').replace(/\/$/, '/');
if (!accessKeyId || !accessKeySecret || !bucket) {
console.error('OSS 未配置:请在 HQ 系统设置或 .env 填写 OSS_ACCESS_KEY_ID / SECRET / BUCKET');
process.exit(1);
}
const client = new OSS({
region,
accessKeyId,
accessKeySecret,
bucket,
...(endpoint ? { endpoint } : {}),
...(process.env.OSS_AUTHORIZATION_V4 === 'true' ? { authorizationV4: true } : {}),
});
const mime =
absFile.endsWith('.png')
? 'image/png'
: absFile.endsWith('.gif')
? 'image/gif'
: absFile.endsWith('.jpg') || absFile.endsWith('.jpeg')
? 'image/jpeg'
: 'application/octet-stream';
const result = await client.put(ossKey, absFile, {
mime,
headers: {
'Content-Disposition': 'inline',
'Cache-Control': 'public, max-age=31536000',
},
});
const publicUrl =
(staticBase ? `${staticBase}${objectName}` : '') ||
(cdnBase ? `${cdnBase}/${ossKey}` : result.url);
console.log(`uploaded bucket=${bucket} region=${region}`);
console.log(`key=${ossKey}`);
console.log(`url=${publicUrl}`);