新增邮件发送和管理员功能
This commit is contained in:
@@ -1,21 +1,160 @@
|
||||
import orm from '../entity/orm';
|
||||
import { att } from '../entity/att';
|
||||
import { and, eq } from 'drizzle-orm';
|
||||
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, params) {
|
||||
await orm(c).insert(att).values(params).run();
|
||||
|
||||
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();
|
||||
},
|
||||
async list(c, params, userId) {
|
||||
|
||||
list(c, params, userId) {
|
||||
const { emailId } = params;
|
||||
|
||||
const list = await orm(c).select().from(att).where(
|
||||
return orm(c).select().from(att).where(
|
||||
and(
|
||||
eq(att.emailId, emailId),
|
||||
eq(att.userId, userId)))
|
||||
.all();
|
||||
eq(att.userId, userId),
|
||||
eq(att.type, attConst.type.ATT),
|
||||
isNull(att.contentId)
|
||||
)
|
||||
).all();
|
||||
},
|
||||
|
||||
return list;
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user