feat: convert attachment path to ArrayBuffer

This commit is contained in:
eoao
2026-05-10 18:33:54 +08:00
parent f6eaf6d0fd
commit fdf4259701
5 changed files with 64 additions and 27 deletions

View File

@@ -91,13 +91,10 @@ const attService = {
if (src.startsWith(domainUtils.toOssDomain(r2Domain))) {
attData.key = src.replace(domainUtils.toOssDomain(r2Domain) + '/','');
attData.path = src;
}
if (src.startsWith('attachments/')) {
const origin = new URL(c.req.url).origin;
attData.key = src;
attData.path = origin + '/' + src;
}
attData.contentId = cid;
@@ -117,22 +114,34 @@ const attService = {
}
//查询已有内嵌url图片信息
const keys = [...new Set(imageDataList.filter(item => item.path).map(item => item.key))];
const keys = [...new Set(imageDataList.filter(item => !item.content).map(item => item.key))];
const dbImageList = await this.selectOneByKeys(c, keys);
//设置给当前附件
imageDataList.forEach(image => {
dbImageList.forEach(dbImage => {
if (image.path && (image.key === dbImage.key)) {
image.size = dbImage.size;
image.filename = dbImage.filename;
image.mimeType = dbImage.mimeType;
image.contentType = dbImage.mimeType;
}
})
})
await Promise.all(imageDataList.map(async image => {
if (image.content) {
return;
}
imageDataList = imageDataList.filter(image => !image.path || image.size);
const dbImage = dbImageList.find(dbImage => image.key === dbImage.key);
if (!dbImage) {
return;
}
image.size = dbImage.size;
image.filename = dbImage.filename;
image.mimeType = dbImage.mimeType;
image.contentType = dbImage.mimeType;
const obj = await r2Service.getObj(c, image.key);
if (!obj) {
return;
}
image.content = obj instanceof ArrayBuffer ? obj : await obj.arrayBuffer();
}))
imageDataList = imageDataList.filter(image => image.content);
return { imageDataList, html: document.toString() };
},

View File

@@ -472,14 +472,6 @@ const emailService = {
async toAttachmentArrayBuffer(attachment) {
let content = attachment.content;
if (!content && attachment.path) {
const response = await fetch(attachment.path);
if (!response.ok) {
throw new BizError(`Attachment fetch failed: ${attachment.filename}`);
}
return await response.arrayBuffer();
}
if (!content) {
return null;
}

View File

@@ -17,9 +17,11 @@ const kvObjService = {
await Promise.all(keys.map( key => c.env.kv.delete(key)));
},
async toObjResp(c, key) {
async getObj(c, key) {
const obj = await c.env.kv.getWithMetadata(key, { type: "arrayBuffer"});
if (!obj.value) {
return null;
}
return new Response(obj.value, {
headers: {
@@ -28,6 +30,11 @@ const kvObjService = {
'Cache-Control': obj.metadata?.cacheControl || null
}
});
},
async toObjResp(c, key) {
return await this.getObj(c, key);
}

View File

@@ -41,7 +41,19 @@ const r2Service = {
},
async getObj(c, key) {
return await c.env.r2.get(key);
const storageType = await this.storageType(c);
if (storageType === 'KV') {
return await kvObjService.getObj(c, key);
}
if (storageType === 'R2') {
return await c.env.r2.get(key);
}
if (storageType === 'S3') {
return await s3Service.getObj(c, key);
}
},
async delete(c, key) {

View File

@@ -1,4 +1,4 @@
import { S3Client, PutObjectCommand, DeleteObjectsCommand } from "@aws-sdk/client-s3";
import { S3Client, PutObjectCommand, DeleteObjectsCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import settingService from './setting-service';
import domainUtils from '../utils/domain-uitls';
import { settingConst } from '../const/entity-const';
@@ -75,6 +75,23 @@ const s3Service = {
);
},
async getObj(c, key) {
const client = await this.client(c);
const { bucket } = await settingService.query(c);
const result = await client.send(new GetObjectCommand({
Bucket: bucket,
Key: key
}));
return new Response(result.Body, {
headers: {
'Content-Type': result.ContentType || 'application/octet-stream',
'Content-Disposition': result.ContentDisposition || null,
'Cache-Control': result.CacheControl || null
}
});
},
async client(c) {
const { region, endpoint, s3AccessKey, s3SecretKey, forcePathStyle } = await settingService.query(c);