修复自动刷新问题

This commit is contained in:
eoao
2025-06-03 13:29:52 +08:00
parent 9b8598da57
commit 3190b47bb9
11 changed files with 45 additions and 38 deletions

View File

@@ -47,14 +47,9 @@
<div class="att-icon" @click="showImage(att.key)"> <div class="att-icon" @click="showImage(att.key)">
<Icon :icon="getIconByName(att.filename)" width="20" height="20"/> <Icon :icon="getIconByName(att.filename)" width="20" height="20"/>
</div> </div>
<el-tooltip <div class="att-name" @click="showImage(att.key)">
effect="dark" {{ att.filename }}
:content="att.filename" </div>
>
<div class="att-name" @click="showImage(att.key)">
{{ att.filename }}
</div>
</el-tooltip>
<div style="color: rgba(24, 36, 48, 0.6);">{{ formatBytes(att.size) }}</div> <div style="color: rgba(24, 36, 48, 0.6);">{{ formatBytes(att.size) }}</div>
<div class="opt-icon att-icon"> <div class="opt-icon att-icon">
<Icon v-if="isImage(att.filename)" icon="hugeicons:view" width="22" height="22" @click="showImage(att.key)"/> <Icon v-if="isImage(att.filename)" icon="hugeicons:view" width="22" height="22" @click="showImage(att.key)"/>

View File

@@ -827,7 +827,7 @@ function adjustWidth() {
padding: 20px; padding: 20px;
display: grid; display: grid;
gap: 10px; gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
.details-item-title { .details-item-title {
white-space: pre; white-space: pre;
@@ -894,7 +894,7 @@ function adjustWidth() {
justify-content: center; justify-content: center;
background-color: rgba(255, 255, 255, 0.8); background-color: rgba(255, 255, 255, 0.8);
left: 0; left: 0;
z-index: 1000; z-index: 2;
top: 0; top: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,8 +6,8 @@
<title></title> <title></title>
<link rel="icon" href="/assets/favicon-C5dAZutX.svg" type="image/svg+xml"> <link rel="icon" href="/assets/favicon-C5dAZutX.svg" type="image/svg+xml">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script type="module" crossorigin src="/assets/index-Cy4AcSPU.js"></script> <script type="module" crossorigin src="/assets/index-BMdBWW7j.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-B2XKi21Y.css"> <link rel="stylesheet" crossorigin href="/assets/index-Blmh8UBo.css">
</head> </head>
<body> <body>
<div id="loading-first"> <div id="loading-first">

View File

@@ -33,7 +33,8 @@ export const emailConst = {
DELIVERED: 2, DELIVERED: 2,
BOUNCED: 3, BOUNCED: 3,
COMPLAINED: 4, COMPLAINED: 4,
DELAYED: 5 DELAYED: 5,
SAVING: 6
} }
} }

View File

@@ -5,6 +5,7 @@ import settingService from '../service/setting-service';
import attService from '../service/att-service'; import attService from '../service/att-service';
import constant from '../const/constant'; import constant from '../const/constant';
import fileUtils from '../utils/file-utils'; import fileUtils from '../utils/file-utils';
import { emailConst, isDel } from '../const/entity-const';
export async function email(message, env, ctx) { export async function email(message, env, ctx) {
@@ -35,7 +36,9 @@ export async function email(message, env, ctx) {
content: email.html, content: email.html,
text: email.text, text: email.text,
userId: account.userId, userId: account.userId,
accountId: account.accountId accountId: account.accountId,
isDel: isDel.DELETE,
status: emailConst.status.SAVING
}; };
const attachments = []; const attachments = [];
@@ -60,6 +63,7 @@ export async function email(message, env, ctx) {
}) })
await attService.addAtt({ env }, attachments); await attService.addAtt({ env }, attachments);
await emailService.completeReceive({ env }, emailRow.emailId);
} catch (e) { } catch (e) {
console.error('邮件接收异常: ', e); console.error('邮件接收异常: ', e);

View File

@@ -1,7 +1,7 @@
import orm from '../entity/orm'; import orm from '../entity/orm';
import email from '../entity/email'; import email from '../entity/email';
import { emailConst, isDel, settingConst } from '../const/entity-const'; import { emailConst, isDel, settingConst } from '../const/entity-const';
import { and, desc, eq, gt, inArray, lt, count, asc, like } from 'drizzle-orm'; import { and, desc, eq, gt, inArray, lt, count, asc, like, ne } from 'drizzle-orm';
import { star } from '../entity/star'; import { star } from '../entity/star';
import settingService from './setting-service'; import settingService from './setting-service';
import accountService from './account-service'; import accountService from './account-service';
@@ -248,7 +248,7 @@ const emailService = {
const attsList = await attService.selectByEmailIds(c, [emailRow.emailId]); const attsList = await attService.selectByEmailIds(c, [emailRow.emailId]);
emailRow.attList = attsList; emailRow.attList = attsList;
return emailRow; return emailRow;
}, },
@@ -261,7 +261,7 @@ const emailService = {
async latest(c, params, userId) { async latest(c, params, userId) {
let { emailId, accountId } = params; let { emailId, accountId } = params;
const list = orm(c).select().from(email).where( const list = await orm(c).select().from(email).where(
and( and(
eq(email.userId, userId), eq(email.userId, userId),
eq(email.isDel, isDel.NORMAL), eq(email.isDel, isDel.NORMAL),
@@ -273,12 +273,16 @@ const emailService = {
.limit(20); .limit(20);
const emailIds = list.map(item => item.emailId); const emailIds = list.map(item => item.emailId);
const attsList = await attService.selectByEmailIds(c, emailIds);
list.forEach(emailRow => { if (emailIds.length > 0) {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts; const attsList = await attService.selectByEmailIds(c, emailIds);
});
list.forEach(emailRow => {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts;
});
}
return list; return list;
}, },
@@ -394,6 +398,8 @@ const emailService = {
conditions.push(like(email.subject, `${subject}%`)); conditions.push(like(email.subject, `${subject}%`));
} }
conditions.push(ne(email.status, emailConst.status.SAVING))
const countConditions = [...conditions]; const countConditions = [...conditions];
if (timeSort) { if (timeSort) {
@@ -438,6 +444,10 @@ const emailService = {
async restoreByUserId(c, userId) { async restoreByUserId(c, userId) {
await orm(c).update(email).set({ isDel: isDel.NORMAL }).where(eq(email.userId, userId)).run(); await orm(c).update(email).set({ isDel: isDel.NORMAL }).where(eq(email.userId, userId)).run();
},
async completeReceive(c, emailId) {
await orm(c).update(email).set({ isDel: isDel.NORMAL, status: emailConst.status.RECEIVE }).where(eq(email.emailId, emailId)).run();
} }
}; };

View File

@@ -45,7 +45,7 @@ const loginService = {
} }
if (accountRow) { if (accountRow) {
throw new BizError('该邮箱已被注册'); throw new BizError('该邮箱已被其他用户绑定');
} }
if (await settingService.isRegisterVerify(c)) { if (await settingService.isRegisterVerify(c)) {
@@ -74,15 +74,15 @@ const loginService = {
const userRow = await userService.selectByEmailIncludeDel(c, email); const userRow = await userService.selectByEmailIncludeDel(c, email);
if (!userRow) { if (!userRow) {
throw new BizError('该邮箱不存在'); throw new BizError('该用户不存在');
} }
if(userRow.isDel === isDel.DELETE) { if(userRow.isDel === isDel.DELETE) {
throw new BizError('该邮箱已被注销'); throw new BizError('该用户已被注销');
} }
if(userRow.status === userConst.status.BAN) { if(userRow.status === userConst.status.BAN) {
throw new BizError('该邮箱已被禁用'); throw new BizError('该用户已被禁用');
} }
if (!await cryptoUtils.verifyPassword(password, userRow.salt, userRow.password)) { if (!await cryptoUtils.verifyPassword(password, userRow.salt, userRow.password)) {

View File

@@ -1,4 +1,5 @@
import BizError from '../error/biz-error'; import BizError from '../error/biz-error';
import settingService from './setting-service';
const turnstileService = { const turnstileService = {
@@ -7,13 +8,16 @@ const turnstileService = {
if (!token) { if (!token) {
throw new BizError('验证token不能为空'); throw new BizError('验证token不能为空');
} }
const settingRow = await settingService.query(c)
const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded' 'Content-Type': 'application/x-www-form-urlencoded'
}, },
body: new URLSearchParams({ body: new URLSearchParams({
secret: c.env.secret_key, secret: settingRow.secretKey,
response: token, response: token,
remoteip: c.req.header('cf-connecting-ip') remoteip: c.req.header('cf-connecting-ip')
}) })

View File

@@ -103,6 +103,7 @@ const userService = {
const { userId } = params const { userId } = params
await accountService.physicsDeleteByUserIds(c, [userId]) await accountService.physicsDeleteByUserIds(c, [userId])
await orm(c).delete(user).where(eq(user.userId, userId)).run(); await orm(c).delete(user).where(eq(user.userId, userId)).run();
await c.env.kv.delete(kvConst.AUTH_INFO + userId);
}, },
async list(c, params, userId) { async list(c, params, userId) {
@@ -281,7 +282,7 @@ const userService = {
.run(); .run();
if (status === userConst.status.BAN) { if (status === userConst.status.BAN) {
c.env.kv.delete(KvConst.AUTH_INFO + userId); await c.env.kv.delete(KvConst.AUTH_INFO + userId);
} }
}, },
@@ -301,14 +302,6 @@ const userService = {
.where(eq(user.userId, userId)) .where(eq(user.userId, userId))
.run(); .run();
if (type) {
const authInfo = await c.env.kv.get(KvConst.AUTH_INFO + userId, { type: 'json' });
if (authInfo) {
authInfo.user.type = type;
await c.env.kv.put(KvConst.AUTH_INFO + userId, JSON.stringify(authInfo));
}
}
}, },
async incrUserService(c, quantity, userId) { async incrUserService(c, quantity, userId) {