优化自动刷新邮件请求次数

This commit is contained in:
eoao
2026-01-12 22:33:00 +08:00
parent 97b2be8d25
commit 7694278045
10 changed files with 161 additions and 129 deletions

View File

@@ -0,0 +1,4 @@
export const AutoRefreshEnum = {
DISABLED: 0,
ENABLED: 1
}

View File

@@ -9,7 +9,7 @@ export function emailDelete(emailIds) {
} }
export function emailLatest(emailId, accountId, allReceive) { export function emailLatest(emailId, accountId, allReceive) {
return http.get('/email/latest', {params: {emailId, accountId, allReceive}, noMsg: true }) return http.get('/email/latest', {params: {emailId, accountId, allReceive}, noMsg: true, timeout: 35 * 1000})
} }
export function emailRead(emailIds) { export function emailRead(emailIds) {

View File

@@ -34,6 +34,7 @@ import {sleep} from "@/utils/time-utils.js";
import router from "@/router/index.js"; import router from "@/router/index.js";
import {Icon} from "@iconify/vue"; import {Icon} from "@iconify/vue";
import {AccountAllReceiveEnum} from "@/enums/account-enum.js"; import {AccountAllReceiveEnum} from "@/enums/account-enum.js";
import {AutoRefreshEnum} from "@/enums/setting-enum.js";
defineOptions({ defineOptions({
name: 'email' name: 'email'
@@ -77,7 +78,7 @@ async function latest() {
while (true) { while (true) {
const latestId = scroll.value.latestEmail?.emailId const latestId = scroll.value.latestEmail?.emailId
if (!scroll.value.firstLoad && settingStore.settings.autoRefreshTime) { if (!scroll.value.firstLoad && settingStore.settings.autoRefresh === AutoRefreshEnum.ENABLED) {
try { try {
const accountId = accountStore.currentAccountId const accountId = accountStore.currentAccountId
const allReceive = scroll.value.latestEmail?.allReceive const allReceive = scroll.value.latestEmail?.allReceive
@@ -127,7 +128,7 @@ async function latest() {
console.error(e) console.error(e)
} }
} }
await sleep(settingStore.settings.autoRefreshTime * 1000) await sleep(500)
} }
} }

View File

@@ -145,11 +145,11 @@
<el-select <el-select
@change="change" @change="change"
:style="`width: ${ locale === 'en' ? 100 : 80 }px;`" :style="`width: ${ locale === 'en' ? 100 : 80 }px;`"
v-model="setting.autoRefreshTime" v-model="setting.autoRefresh"
placeholder="Select" placeholder="Select"
> >
<el-option <el-option
v-for="item in options" v-for="item in authRefreshOptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
@@ -827,14 +827,9 @@ const regKeyOptions = computed(() => [
{label: t('optional'), value: 2}, {label: t('optional'), value: 2},
]) ])
const options = computed(() => [ const authRefreshOptions = computed(() => [
{label: t('disable'), value: 0}, {label: t('disable'), value: 0},
{label: '3s', value: 3}, {label: t('enable'), value: 1},
{label: '5s', value: 5},
{label: '7s', value: 7},
{label: '10s', value: 10},
{label: '15s', value: 15},
{label: '20s', value: 20}
]) ])
const tgChatId = ref([]) const tgChatId = ref([])

View File

@@ -127,6 +127,10 @@ export const settingConst = {
forcePathStyle: { forcePathStyle: {
OPEN: 0, OPEN: 0,
CLOSE: 1 CLOSE: 1
},
authRefresh: {
OPEN: 1,
CLOSE: 0
} }
} }

View File

@@ -5,7 +5,7 @@ export const setting = sqliteTable('setting', {
title: text('title').default('').notNull(), title: text('title').default('').notNull(),
manyEmail: integer('many_email').default(0).notNull(), manyEmail: integer('many_email').default(0).notNull(),
addEmail: integer('add_email').default(0).notNull(), addEmail: integer('add_email').default(0).notNull(),
autoRefreshTime: integer('auto_refresh_time').default(0).notNull(), autoRefresh: integer('auto_refresh').default(0).notNull(),
addEmailVerify: integer('add_email_verify').default(1).notNull(), addEmailVerify: integer('add_email_verify').default(1).notNull(),
registerVerify: integer('register_verify').default(1).notNull(), registerVerify: integer('register_verify').default(1).notNull(),
regVerifyCount: integer('reg_verify_count').default(1).notNull(), regVerifyCount: integer('reg_verify_count').default(1).notNull(),

View File

@@ -26,15 +26,27 @@ const init = {
await this.v2_4DB(c); await this.v2_4DB(c);
await this.v2_5DB(c); await this.v2_5DB(c);
await this.v2_6DB(c); await this.v2_6DB(c);
await this.v2_7DB(c);
await settingService.refresh(c); await settingService.refresh(c);
return c.text(t('initSuccess')); return c.text(t('initSuccess'));
}, },
async v2_7DB(c) {
try {
await c.env.db.batch([
c.env.db.prepare(`ALTER TABLE setting RENAME COLUMN auto_refresh_time TO auto_refresh;`),
c.env.db.prepare(`UPDATE setting SET auto_refresh = 1 WHERE auto_refresh != 0;`)
]);
} catch (e) {
console.warn(`跳过字段:${e.message}`);
}
},
async v2_6DB(c) { async v2_6DB(c) {
try { try {
await c.env.db.prepare(`ALTER TABLE account ADD COLUMN all_receive INTEGER NOT NULL DEFAULT 0;`).run(); await c.env.db.prepare(`ALTER TABLE account ADD COLUMN all_receive INTEGER NOT NULL DEFAULT 0;`).run();
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -43,16 +55,16 @@ const init = {
try { try {
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN email_prefix_filter text NOT NULL DEFAULT '';`).run(); await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN email_prefix_filter text NOT NULL DEFAULT '';`).run();
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
try { try {
await c.env.db.batch([ await c.env.db.batch([
c.env.db.prepare(`ALTER TABLE email ADD COLUMN unread INTEGER NOT NULL DEFAULT 0;`).run(), c.env.db.prepare(`ALTER TABLE email ADD COLUMN unread INTEGER NOT NULL DEFAULT 0;`),
c.env.db.prepare(`UPDATE email SET unread = 1;`).run() c.env.db.prepare(`UPDATE email SET unread = 1;`)
]); ]);
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -75,13 +87,13 @@ const init = {
) )
`).run(); `).run();
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
try { try {
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN min_email_prefix INTEGER NOT NULL DEFAULT 1;`).run(); await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN min_email_prefix INTEGER NOT NULL DEFAULT 1;`).run();
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -95,13 +107,13 @@ const init = {
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_from TEXT NOT NULL DEFAULT 'only-name';`) c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_from TEXT NOT NULL DEFAULT 'only-name';`)
]); ]);
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
try { try {
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_text TEXT NOT NULL DEFAULT 'show';`).run(); await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_text TEXT NOT NULL DEFAULT 'show';`).run();
} catch (e) { } catch (e) {
console.error(e) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -117,7 +129,7 @@ const init = {
c.env.db.prepare(`DELETE FROM perm WHERE perm_key = 'setting:clean'`) c.env.db.prepare(`DELETE FROM perm WHERE perm_key = 'setting:clean'`)
]); ]);
} catch (e) { } catch (e) {
console.error(e.message) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -125,7 +137,7 @@ const init = {
try { try {
await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN login_domain INTEGER NOT NULL DEFAULT 0;`).run(); await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN login_domain INTEGER NOT NULL DEFAULT 0;`).run();
} catch (e) { } catch (e) {
console.error(e.message) console.warn(`跳过字段:${e.message}`);
} }
}, },
@@ -162,7 +174,7 @@ const init = {
try { try {
await c.env.db.prepare(sql).run(); await c.env.db.prepare(sql).run();
} catch (e) { } catch (e) {
console.warn(`过字段,原因${e.message}`); console.warn(`过字段:${e.message}`);
} }
}); });
@@ -176,7 +188,7 @@ const init = {
c.env.db.prepare(`CREATE UNIQUE INDEX IF NOT EXISTS idx_user_email_nocase ON user (email COLLATE NOCASE)`) c.env.db.prepare(`CREATE UNIQUE INDEX IF NOT EXISTS idx_user_email_nocase ON user (email COLLATE NOCASE)`)
]); ]);
} catch (e) { } catch (e) {
console.error(e.message) console.warn(e.message)
} }
}, },
@@ -187,7 +199,7 @@ const init = {
try { try {
await c.env.db.prepare(`ALTER TABLE role ADD COLUMN avail_domain TEXT NOT NULL DEFAULT ''`).run(); await c.env.db.prepare(`ALTER TABLE role ADD COLUMN avail_domain TEXT NOT NULL DEFAULT ''`).run();
} catch (e) { } catch (e) {
console.warn(`跳过字段添加,原因${e.message}`); console.warn(`跳过字段添加:${e.message}`);
} }
}, },
@@ -210,7 +222,7 @@ const init = {
CREATE UNIQUE INDEX IF NOT EXISTS idx_setting_code ON reg_key(code COLLATE NOCASE) CREATE UNIQUE INDEX IF NOT EXISTS idx_setting_code ON reg_key(code COLLATE NOCASE)
`).run(); `).run();
} catch (e) { } catch (e) {
console.warn(`跳过创建索引,原因${e.message}`); console.warn(`跳过创建索引:${e.message}`);
} }
@@ -222,7 +234,7 @@ const init = {
(35,'密钥添加', 'reg-key:add', 33, 2, 1), (35,'密钥添加', 'reg-key:add', 33, 2, 1),
(36,'密钥删除', 'reg-key:delete', 33, 2, 2)`).run(); (36,'密钥删除', 'reg-key:delete', 33, 2, 2)`).run();
} catch (e) { } catch (e) {
console.warn(`跳过数据,原因${e.message}`); console.warn(`跳过数据:${e.message}`);
} }
const ADD_COLUMN_SQL_LIST = [ const ADD_COLUMN_SQL_LIST = [
@@ -236,7 +248,7 @@ const init = {
try { try {
await c.env.db.prepare(sql).run(); await c.env.db.prepare(sql).run();
} catch (e) { } catch (e) {
console.warn(`跳过字段添加,原因${e.message}`); console.warn(`跳过字段添加:${e.message}`);
} }
}); });
@@ -264,7 +276,7 @@ const init = {
try { try {
await c.env.db.prepare(sql).run(); await c.env.db.prepare(sql).run();
} catch (e) { } catch (e) {
console.warn(`跳过字段添加,原因${e.message}`); console.warn(`跳过字段添加:${e.message}`);
} }
}); });
@@ -301,7 +313,7 @@ const init = {
try { try {
await c.env.db.prepare(sql).run(); await c.env.db.prepare(sql).run();
} catch (e) { } catch (e) {
console.warn(`跳过字段添加,原因${e.message}`); console.warn(`跳过字段添加:${e.message}`);
} }
}); });
@@ -316,7 +328,7 @@ const init = {
(31,'分析页', NULL, 0, 1, 2.1), (31,'分析页', NULL, 0, 1, 2.1),
(32,'数据查看', 'analysis:query', 31, 2, 1)`).run(); (32,'数据查看', 'analysis:query', 31, 2, 1)`).run();
} catch (e) { } catch (e) {
console.warn(`跳过数据,原因${e.message}`); console.warn(`跳过数据:${e.message}`);
} }
}, },
@@ -335,7 +347,7 @@ const init = {
`ALTER TABLE setting ADD COLUMN site_key TEXT;`, `ALTER TABLE setting ADD COLUMN site_key TEXT;`,
`ALTER TABLE setting ADD COLUMN secret_key TEXT;`, `ALTER TABLE setting ADD COLUMN secret_key TEXT;`,
`ALTER TABLE setting ADD COLUMN background TEXT;`, `ALTER TABLE setting ADD COLUMN background TEXT;`,
`ALTER TABLE setting ADD COLUMN login_opacity INTEGER NOT NULL DEFAULT 0.88;`, `ALTER TABLE setting ADD COLUMN login_opacity INTEGER NOT NULL DEFAULT 0.90;`,
`ALTER TABLE user ADD COLUMN create_ip TEXT;`, `ALTER TABLE user ADD COLUMN create_ip TEXT;`,
`ALTER TABLE user ADD COLUMN active_ip TEXT;`, `ALTER TABLE user ADD COLUMN active_ip TEXT;`,
@@ -353,7 +365,7 @@ const init = {
try { try {
await c.env.db.prepare(sql).run(); await c.env.db.prepare(sql).run();
} catch (e) { } catch (e) {
console.warn(`跳过字段添加,原因${e.message}`); console.warn(`跳过字段添加:${e.message}`);
} }
}); });
@@ -467,93 +479,98 @@ const init = {
async intDB(c) { async intDB(c) {
// 初始化数据库表结构 // 初始化数据库表结构
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS email ( CREATE TABLE IF NOT EXISTS email (
email_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, email_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
send_email TEXT, send_email TEXT,
name TEXT, name TEXT,
account_id INTEGER NOT NULL, account_id INTEGER NOT NULL,
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
subject TEXT, subject TEXT,
content TEXT, content TEXT,
text TEXT, text TEXT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_del INTEGER DEFAULT 0 NOT NULL is_del INTEGER DEFAULT 0 NOT NULL
) )
`).run(); `).run();
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS star ( CREATE TABLE IF NOT EXISTS star (
star_id INTEGER PRIMARY KEY AUTOINCREMENT, star_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
email_id INTEGER NOT NULL, email_id INTEGER NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL
) )
`).run(); `).run();
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS attachments ( CREATE TABLE IF NOT EXISTS attachments (
att_id INTEGER PRIMARY KEY AUTOINCREMENT, att_id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
email_id INTEGER NOT NULL, email_id INTEGER NOT NULL,
account_id INTEGER NOT NULL, account_id INTEGER NOT NULL,
key TEXT NOT NULL, key TEXT NOT NULL,
filename TEXT, filename TEXT,
mime_type TEXT, mime_type TEXT,
size INTEGER, size INTEGER,
disposition TEXT, disposition TEXT,
related TEXT, related TEXT,
content_id TEXT, content_id TEXT,
encoding TEXT, encoding TEXT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL
) )
`).run(); `).run();
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS user ( CREATE TABLE IF NOT EXISTS user (
user_id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL, email TEXT NOT NULL,
type INTEGER DEFAULT 1 NOT NULL, type INTEGER DEFAULT 1 NOT NULL,
password TEXT NOT NULL, password TEXT NOT NULL,
salt TEXT NOT NULL, salt TEXT NOT NULL,
status INTEGER DEFAULT 0 NOT NULL, status INTEGER DEFAULT 0 NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
active_time DATETIME, active_time DATETIME,
is_del INTEGER DEFAULT 0 NOT NULL is_del INTEGER DEFAULT 0 NOT NULL
) )
`).run(); `).run();
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS account ( CREATE TABLE IF NOT EXISTS account (
account_id INTEGER PRIMARY KEY AUTOINCREMENT, account_id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL, email TEXT NOT NULL,
status INTEGER DEFAULT 0 NOT NULL, status INTEGER DEFAULT 0 NOT NULL,
latest_email_time DATETIME, latest_email_time DATETIME,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP, create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
user_id INTEGER NOT NULL, user_id INTEGER NOT NULL,
is_del INTEGER DEFAULT 0 NOT NULL is_del INTEGER DEFAULT 0 NOT NULL
) )
`).run(); `).run();
await c.env.db.prepare(` await c.env.db.prepare(`
CREATE TABLE IF NOT EXISTS setting ( CREATE TABLE IF NOT EXISTS setting (
register INTEGER NOT NULL, register INTEGER NOT NULL,
receive INTEGER NOT NULL, receive INTEGER NOT NULL,
add_email INTEGER NOT NULL, add_email INTEGER NOT NULL,
many_email INTEGER NOT NULL, many_email INTEGER NOT NULL,
title TEXT NOT NULL, title TEXT NOT NULL,
auto_refresh_time INTEGER NOT NULL, auto_refresh INTEGER NOT NULL,
register_verify INTEGER NOT NULL, register_verify INTEGER NOT NULL,
add_email_verify INTEGER NOT NULL add_email_verify INTEGER NOT NULL
) )
`).run(); `).run();
try {
await c.env.db.prepare(`
INSERT INTO setting (
register, receive, add_email, many_email, title, auto_refresh, register_verify, add_email_verify
)
SELECT 0, 0, 0, 0, 'Cloud Mail', 1, 1, 1
WHERE NOT EXISTS (SELECT 1 FROM setting)
`).run();
} catch (e) {
console.warn(e)
}
await c.env.db.prepare(`
INSERT INTO setting (
register, receive, add_email, many_email, title, auto_refresh_time, register_verify, add_email_verify
)
SELECT 0, 0, 0, 0, 'Cloud Mail', 0, 1, 1
WHERE NOT EXISTS (SELECT 1 FROM setting)
`).run();
}, },
async receiveEmailToRecipient(c) { async receiveEmailToRecipient(c) {

View File

@@ -17,9 +17,9 @@ import starService from './star-service';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import kvConst from '../const/kv-const'; import kvConst from '../const/kv-const';
import { t } from '../i18n/i18n' import { t } from '../i18n/i18n'
import r2Service from './r2-service';
import domainUtils from '../utils/domain-uitls'; import domainUtils from '../utils/domain-uitls';
import account from "../entity/account"; import account from "../entity/account";
import {sleep} from "../utils/time-utils";
const emailService = { const emailService = {
@@ -452,22 +452,30 @@ const emailService = {
allReceive = accountRow.allReceive; allReceive = accountRow.allReceive;
} }
const list = await orm(c).select({...email}).from(email) let count = 0
.leftJoin( let list = []
account,
eq(account.accountId, email.accountId) while ((count < 10) && list.length === 0) {
) list = await orm(c).select({...email}).from(email)
.where( .leftJoin(
and( account,
eq(email.userId, userId), eq(account.accountId, email.accountId)
eq(email.isDel, isDel.NORMAL), )
eq(account.isDel, isDel.NORMAL), .where(
allReceive ? eq(1,1) : eq(email.accountId, accountId), and(
eq(email.type, emailConst.type.RECEIVE), eq(email.userId, userId),
gt(email.emailId, emailId) eq(email.isDel, isDel.NORMAL),
)) eq(account.isDel, isDel.NORMAL),
.orderBy(desc(email.emailId)) allReceive ? eq(1,1) : eq(email.accountId, accountId),
.limit(20); eq(email.type, emailConst.type.RECEIVE),
gt(email.emailId, emailId)
))
.orderBy(desc(email.emailId))
.limit(20);
await sleep(3000);
count++
}
const emailIds = list.map(item => item.emailId); const emailIds = list.map(item => item.emailId);

View File

@@ -176,7 +176,7 @@ const settingService = {
title: settingRow.title, title: settingRow.title,
manyEmail: settingRow.manyEmail, manyEmail: settingRow.manyEmail,
addEmail: settingRow.addEmail, addEmail: settingRow.addEmail,
autoRefreshTime: settingRow.autoRefreshTime, autoRefresh: settingRow.autoRefresh,
addEmailVerify: settingRow.addEmailVerify, addEmailVerify: settingRow.addEmailVerify,
registerVerify: settingRow.registerVerify, registerVerify: settingRow.registerVerify,
send: settingRow.send, send: settingRow.send,

View File

@@ -0,0 +1,3 @@
export function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}