mirror of
https://github.com/schroinerxy/cloud-mail.git
synced 2026-06-22 03:45:52 +08:00
167 lines
4.5 KiB
JavaScript
167 lines
4.5 KiB
JavaScript
import orm from '../entity/orm';
|
|
import { att } from '../entity/att';
|
|
import { and, eq, isNull, inArray, notInArray } from 'drizzle-orm';
|
|
import r2Service from './r2-service';
|
|
import constant from '../const/constant';
|
|
import fileUtils from '../utils/file-utils';
|
|
import { attConst } from '../const/entity-const';
|
|
import { parseHTML } from 'linkedom';
|
|
|
|
const attService = {
|
|
|
|
async addAtt(c, attachments) {
|
|
|
|
for (let attachment of attachments) {
|
|
await r2Service.putObj(c, attachment.key, attachment.content, {
|
|
contentType: attachment.mimeType,
|
|
contentDisposition: `attachment; filename="${attachment.filename}"`
|
|
});
|
|
}
|
|
|
|
await orm(c).insert(att).values(attachments).run();
|
|
},
|
|
|
|
list(c, params, userId) {
|
|
const { emailId } = params;
|
|
|
|
return orm(c).select().from(att).where(
|
|
and(
|
|
eq(att.emailId, emailId),
|
|
eq(att.userId, userId),
|
|
eq(att.type, attConst.type.ATT),
|
|
isNull(att.contentId)
|
|
)
|
|
).all();
|
|
},
|
|
|
|
async toImageUrlHtml(c, content, r2Domain) {
|
|
|
|
const { document } = parseHTML(content);
|
|
|
|
const images = Array.from(document.querySelectorAll('img'));
|
|
|
|
const attDataList = [];
|
|
|
|
for (const img of images) {
|
|
|
|
const src = img.getAttribute('src');
|
|
if (src && src.startsWith('data:image')) {
|
|
const file = fileUtils.base64ToFile(src);
|
|
const buff = await file.arrayBuffer();
|
|
const key = constant.ATTACHMENT_PREFIX + await fileUtils.getBuffHash(buff) + fileUtils.getExtFileName(file.name);
|
|
img.setAttribute('src', r2Domain + '/' + key);
|
|
|
|
const attData = {};
|
|
attData.key = key;
|
|
attData.filename = file.name;
|
|
attData.mimeType = file.type;
|
|
attData.size = file.size;
|
|
attData.buff = buff;
|
|
|
|
attDataList.push(attData);
|
|
}
|
|
|
|
const hasInlineWidth = img.hasAttribute('width');
|
|
const style = img.getAttribute('style') || '';
|
|
const hasStyleWidth = /(^|\s)width\s*:\s*[^;]+/.test(style);
|
|
|
|
if (!hasInlineWidth && !hasStyleWidth) {
|
|
const newStyle = (style ? style.trim().replace(/;$/, '') + '; ' : '') + 'max-width: 100%;';
|
|
img.setAttribute('style', newStyle);
|
|
}
|
|
}
|
|
return { attDataList, html: document.toString() };
|
|
},
|
|
|
|
async saveSendAtt(c, attList, userId, accountId, emailId) {
|
|
|
|
const attDataList = [];
|
|
|
|
for (let att of attList) {
|
|
att.buff = fileUtils.base64ToUint8Array(att.content);
|
|
att.key = constant.ATTACHMENT_PREFIX + await fileUtils.getBuffHash(att.buff) + fileUtils.getExtFileName(att.filename);
|
|
const attData = { userId, accountId, emailId };
|
|
attData.key = att.key;
|
|
attData.size = att.buff.length;
|
|
attData.filename = att.filename;
|
|
attData.mimeType = att.type;
|
|
attData.type = attConst.type.ATT;
|
|
attDataList.push(attData);
|
|
}
|
|
|
|
await orm(c).insert(att).values(attDataList).run();
|
|
|
|
for (let att of attList) {
|
|
await r2Service.putObj(c, att.key, att.buff, {
|
|
contentType: att.type,
|
|
contentDisposition: `attachment; filename="${att.filename}"`
|
|
});
|
|
}
|
|
|
|
},
|
|
|
|
async saveArticleAtt(c, attDataList, userId, accountId, emailId) {
|
|
|
|
for (let attData of attDataList) {
|
|
attData.userId = userId;
|
|
attData.emailId = emailId;
|
|
attData.accountId = accountId;
|
|
attData.type = attConst.type.EMBED;
|
|
await r2Service.putObj(c, attData.key, attData.buff, {
|
|
contentType: attData.mimeType
|
|
});
|
|
}
|
|
|
|
await orm(c).insert(att).values(attDataList).run();
|
|
|
|
},
|
|
|
|
async removeByUserIds(c, userIds) {
|
|
await this.removeAttByField(c, att.userId, userIds);
|
|
},
|
|
|
|
async removeByEmailIds(c, emailIds) {
|
|
await this.removeAttByField(c, att.emailId, emailIds);
|
|
},
|
|
|
|
async removeByAccountIds(c, accountIds) {
|
|
await this.removeAttByField(c, att.accountId, accountIds);
|
|
},
|
|
|
|
async removeAttByField(c, fieldName, fieldValues) {
|
|
|
|
const condition = inArray(fieldName, fieldValues);
|
|
const attList = await orm(c).select().from(att).where(condition).limit(99);
|
|
|
|
if (attList.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const attIds = attList.map(attRow => attRow.attId);
|
|
const keys = attList.map(attRow => attRow.key);
|
|
await orm(c).delete(att).where(inArray(att.attId, attIds)).run();
|
|
|
|
const existAttRows = await orm(c).select().from(att).where(inArray(att.key, keys)).all();
|
|
const existKeys = existAttRows.map(attRow => attRow.key);
|
|
const delKeyList = keys.filter(key => !existKeys.includes(key));
|
|
if (delKeyList.length > 0) {
|
|
await c.env.r2.delete(delKeyList);
|
|
}
|
|
|
|
if (attList.length >= 99) {
|
|
await this.removeAttByField(c, fieldName, fieldValues);
|
|
}
|
|
},
|
|
|
|
selectByEmailIds(c, emailIds) {
|
|
return orm(c).select().from(att).where(
|
|
and(
|
|
inArray(att.emailId,emailIds),
|
|
eq(att.type, attConst.type.ATT)
|
|
))
|
|
.all();
|
|
}
|
|
};
|
|
|
|
export default attService;
|