11-jimengManager.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * 云函数:jimengManager
  3. * 代理即梦图片、视频、数字人、动作迁移等任务接口,避免前端暴露上游地址和 token。
  4. *
  5. * 部署后把函数 objectId 填入 src/app/services/cloud-functions.ts 的 jimeng。
  6. */
  7. const JIMENG_TOKEN = 'Bearer r:f0333969e312a40e4703e8fe4ed1c600';
  8. const JIMENG_BASE_URL = 'https://server.fmode.cn/api/volcengine/jimeng';
  9. const PARSE_BASE_URL = 'https://server.fmode.cn/parse';
  10. const PARSE_APP_ID = 'ncloudmaster';
  11. const ALLOWED_ENDPOINTS = new Set([
  12. 'getVideoV3_720p',
  13. 'getVideoV3_1080p',
  14. 'getVideoV3_Pro',
  15. 'getText2ImgV31',
  16. 'getImgV4',
  17. 'getDataByTask02',
  18. 'getOhIdentifyMain',
  19. 'getOhDateByTask',
  20. 'getOmniHuman',
  21. 'getActorV2',
  22. ]);
  23. async function handler(request, response) {
  24. try {
  25. const action = pickParam(request, 'action') || 'call';
  26. if (action === 'call') {
  27. const endpoint = String(pickParam(request, 'endpoint') || '').trim();
  28. const payload = pickParam(request, 'payload', 'data') || {};
  29. if (!ALLOWED_ENDPOINTS.has(endpoint)) {
  30. return response.json({ code: 400, success: false, error: '不支持的生成接口' });
  31. }
  32. const upstreamPayload = stripEmpty({ ...payload, token: JIMENG_TOKEN });
  33. const data = await postJson(`${JIMENG_BASE_URL}/${endpoint}`, upstreamPayload);
  34. response.json(data);
  35. return;
  36. }
  37. if (action === 'getWorkResult') {
  38. const workId = String(pickParam(request, 'workId', 'objectId') || '').trim();
  39. if (!workId) {
  40. return response.json({ code: 400, success: false, error: '缺少作品 ID' });
  41. }
  42. const data = await getJson(`${PARSE_BASE_URL}/classes/ImagineWork/${encodeURIComponent(workId)}`, {
  43. 'X-Parse-Application-Id': PARSE_APP_ID,
  44. });
  45. response.json({ code: 200, success: true, data });
  46. return;
  47. }
  48. response.json({ code: 400, success: false, error: `未知 action: ${action}` });
  49. } catch (error) {
  50. console.error('jimengManager failed:', error && error.message ? error.message : error);
  51. response.json({ code: 500, success: false, error: error && error.message ? error.message : '生成服务调用失败' });
  52. }
  53. }
  54. function pickParam(request, ...names) {
  55. const sources = [request.params, request.body, request];
  56. for (const src of sources) {
  57. if (!src || typeof src !== 'object') continue;
  58. for (const n of names) {
  59. const v = src[n];
  60. if (v !== undefined && v !== null && v !== '') return v;
  61. }
  62. }
  63. return null;
  64. }
  65. function stripEmpty(value) {
  66. if (!value || typeof value !== 'object') return value;
  67. const out = Array.isArray(value) ? [] : {};
  68. for (const [key, val] of Object.entries(value)) {
  69. if (val === undefined || val === null || val === '') continue;
  70. if (val && typeof val === 'object' && !Array.isArray(val)) {
  71. const nested = stripEmpty(val);
  72. if (Object.keys(nested).length) out[key] = nested;
  73. } else {
  74. out[key] = val;
  75. }
  76. }
  77. return out;
  78. }
  79. async function postJson(url, body) {
  80. const r = await fetch(url, {
  81. method: 'POST',
  82. headers: { 'Content-Type': 'application/json' },
  83. body: JSON.stringify(body),
  84. });
  85. return readResponse(r);
  86. }
  87. async function getJson(url, headers) {
  88. const r = await fetch(url, { method: 'GET', headers });
  89. const data = await readResponse(r);
  90. if (data && data.success === false) throw new Error(data.error || '查询结果失败');
  91. return data;
  92. }
  93. async function readResponse(r) {
  94. const text = await r.text();
  95. let data = null;
  96. try { data = text ? JSON.parse(text) : null; } catch {}
  97. if (!r.ok) {
  98. return { code: r.status, success: false, error: readError(data, text) || `HTTP ${r.status}` };
  99. }
  100. return data || { code: 500, success: false, error: '服务返回异常' };
  101. }
  102. function readError(data, fallback) {
  103. return data?.error?.message || data?.error || data?.message || data?.msg || fallback || '';
  104. }