diff --git a/mail-vue/src/enums/setting-enum.js b/mail-vue/src/enums/setting-enum.js new file mode 100644 index 0000000..9ea24bb --- /dev/null +++ b/mail-vue/src/enums/setting-enum.js @@ -0,0 +1,4 @@ +export const AutoRefreshEnum = { + DISABLED: 0, + ENABLED: 1 +} \ No newline at end of file diff --git a/mail-vue/src/request/email.js b/mail-vue/src/request/email.js index b37cc61..7f1ece7 100644 --- a/mail-vue/src/request/email.js +++ b/mail-vue/src/request/email.js @@ -9,7 +9,7 @@ export function emailDelete(emailIds) { } 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) { diff --git a/mail-vue/src/views/email/index.vue b/mail-vue/src/views/email/index.vue index d559eed..da2e5fe 100644 --- a/mail-vue/src/views/email/index.vue +++ b/mail-vue/src/views/email/index.vue @@ -34,6 +34,7 @@ import {sleep} from "@/utils/time-utils.js"; import router from "@/router/index.js"; import {Icon} from "@iconify/vue"; import {AccountAllReceiveEnum} from "@/enums/account-enum.js"; +import {AutoRefreshEnum} from "@/enums/setting-enum.js"; defineOptions({ name: 'email' @@ -77,7 +78,7 @@ async function latest() { while (true) { const latestId = scroll.value.latestEmail?.emailId - if (!scroll.value.firstLoad && settingStore.settings.autoRefreshTime) { + if (!scroll.value.firstLoad && settingStore.settings.autoRefresh === AutoRefreshEnum.ENABLED) { try { const accountId = accountStore.currentAccountId const allReceive = scroll.value.latestEmail?.allReceive @@ -127,7 +128,7 @@ async function latest() { console.error(e) } } - await sleep(settingStore.settings.autoRefreshTime * 1000) + await sleep(500) } } diff --git a/mail-vue/src/views/sys-setting/index.vue b/mail-vue/src/views/sys-setting/index.vue index 221a331..df9072c 100644 --- a/mail-vue/src/views/sys-setting/index.vue +++ b/mail-vue/src/views/sys-setting/index.vue @@ -145,11 +145,11 @@ [ {label: t('optional'), value: 2}, ]) -const options = computed(() => [ +const authRefreshOptions = computed(() => [ {label: t('disable'), value: 0}, - {label: '3s', value: 3}, - {label: '5s', value: 5}, - {label: '7s', value: 7}, - {label: '10s', value: 10}, - {label: '15s', value: 15}, - {label: '20s', value: 20} + {label: t('enable'), value: 1}, ]) const tgChatId = ref([]) diff --git a/mail-worker/src/const/entity-const.js b/mail-worker/src/const/entity-const.js index 3afcb18..946b108 100644 --- a/mail-worker/src/const/entity-const.js +++ b/mail-worker/src/const/entity-const.js @@ -127,6 +127,10 @@ export const settingConst = { forcePathStyle: { OPEN: 0, CLOSE: 1 + }, + authRefresh: { + OPEN: 1, + CLOSE: 0 } } diff --git a/mail-worker/src/entity/setting.js b/mail-worker/src/entity/setting.js index 31bdd38..1100547 100644 --- a/mail-worker/src/entity/setting.js +++ b/mail-worker/src/entity/setting.js @@ -5,7 +5,7 @@ export const setting = sqliteTable('setting', { title: text('title').default('').notNull(), manyEmail: integer('many_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(), registerVerify: integer('register_verify').default(1).notNull(), regVerifyCount: integer('reg_verify_count').default(1).notNull(), diff --git a/mail-worker/src/init/init.js b/mail-worker/src/init/init.js index 4385763..bfb514f 100644 --- a/mail-worker/src/init/init.js +++ b/mail-worker/src/init/init.js @@ -26,15 +26,27 @@ const init = { await this.v2_4DB(c); await this.v2_5DB(c); await this.v2_6DB(c); + await this.v2_7DB(c); await settingService.refresh(c); 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) { try { await c.env.db.prepare(`ALTER TABLE account ADD COLUMN all_receive INTEGER NOT NULL DEFAULT 0;`).run(); } catch (e) { - console.error(e) + console.warn(`跳过字段:${e.message}`); } }, @@ -43,16 +55,16 @@ const init = { try { await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN email_prefix_filter text NOT NULL DEFAULT '';`).run(); } catch (e) { - console.error(e) + console.warn(`跳过字段:${e.message}`); } try { 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(`UPDATE email SET unread = 1;`).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;`) ]); } catch (e) { - console.error(e) + console.warn(`跳过字段:${e.message}`); } }, @@ -75,13 +87,13 @@ const init = { ) `).run(); } catch (e) { - console.error(e) + console.warn(`跳过字段:${e.message}`); } try { await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN min_email_prefix INTEGER NOT NULL DEFAULT 1;`).run(); } 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';`) ]); } catch (e) { - console.error(e) + console.warn(`跳过字段:${e.message}`); } try { await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_text TEXT NOT NULL DEFAULT 'show';`).run(); } 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'`) ]); } catch (e) { - console.error(e.message) + console.warn(`跳过字段:${e.message}`); } }, @@ -125,7 +137,7 @@ const init = { try { await c.env.db.prepare(`ALTER TABLE setting ADD COLUMN login_domain INTEGER NOT NULL DEFAULT 0;`).run(); } catch (e) { - console.error(e.message) + console.warn(`跳过字段:${e.message}`); } }, @@ -162,7 +174,7 @@ const init = { try { await c.env.db.prepare(sql).run(); } 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)`) ]); } catch (e) { - console.error(e.message) + console.warn(e.message) } }, @@ -187,7 +199,7 @@ const init = { try { await c.env.db.prepare(`ALTER TABLE role ADD COLUMN avail_domain TEXT NOT NULL DEFAULT ''`).run(); } 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) `).run(); } catch (e) { - console.warn(`跳过创建索引,原因:${e.message}`); + console.warn(`跳过创建索引:${e.message}`); } @@ -222,7 +234,7 @@ const init = { (35,'密钥添加', 'reg-key:add', 33, 2, 1), (36,'密钥删除', 'reg-key:delete', 33, 2, 2)`).run(); } catch (e) { - console.warn(`跳过数据,原因:${e.message}`); + console.warn(`跳过数据:${e.message}`); } const ADD_COLUMN_SQL_LIST = [ @@ -236,7 +248,7 @@ const init = { try { await c.env.db.prepare(sql).run(); } catch (e) { - console.warn(`跳过字段添加,原因:${e.message}`); + console.warn(`跳过字段添加:${e.message}`); } }); @@ -264,7 +276,7 @@ const init = { try { await c.env.db.prepare(sql).run(); } catch (e) { - console.warn(`跳过字段添加,原因:${e.message}`); + console.warn(`跳过字段添加:${e.message}`); } }); @@ -301,7 +313,7 @@ const init = { try { await c.env.db.prepare(sql).run(); } catch (e) { - console.warn(`跳过字段添加,原因:${e.message}`); + console.warn(`跳过字段添加:${e.message}`); } }); @@ -316,7 +328,7 @@ const init = { (31,'分析页', NULL, 0, 1, 2.1), (32,'数据查看', 'analysis:query', 31, 2, 1)`).run(); } 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 secret_key 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 active_ip TEXT;`, @@ -353,7 +365,7 @@ const init = { try { await c.env.db.prepare(sql).run(); } catch (e) { - console.warn(`跳过字段添加,原因:${e.message}`); + console.warn(`跳过字段添加:${e.message}`); } }); @@ -467,93 +479,98 @@ const init = { async intDB(c) { // 初始化数据库表结构 await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS email ( - email_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - send_email TEXT, - name TEXT, - account_id INTEGER NOT NULL, - user_id INTEGER NOT NULL, - subject TEXT, - content TEXT, - text TEXT, - create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - is_del INTEGER DEFAULT 0 NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS email ( + email_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + send_email TEXT, + name TEXT, + account_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + subject TEXT, + content TEXT, + text TEXT, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, + is_del INTEGER DEFAULT 0 NOT NULL + ) + `).run(); await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS star ( - star_id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - email_id INTEGER NOT NULL, - create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS star ( + star_id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + email_id INTEGER NOT NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL + ) + `).run(); await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS attachments ( - att_id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - email_id INTEGER NOT NULL, - account_id INTEGER NOT NULL, - key TEXT NOT NULL, - filename TEXT, - mime_type TEXT, - size INTEGER, - disposition TEXT, - related TEXT, - content_id TEXT, - encoding TEXT, - create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS attachments ( + att_id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + email_id INTEGER NOT NULL, + account_id INTEGER NOT NULL, + key TEXT NOT NULL, + filename TEXT, + mime_type TEXT, + size INTEGER, + disposition TEXT, + related TEXT, + content_id TEXT, + encoding TEXT, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL + ) + `).run(); await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS user ( - user_id INTEGER PRIMARY KEY AUTOINCREMENT, - email TEXT NOT NULL, - type INTEGER DEFAULT 1 NOT NULL, - password TEXT NOT NULL, - salt TEXT NOT NULL, - status INTEGER DEFAULT 0 NOT NULL, - create_time DATETIME DEFAULT CURRENT_TIMESTAMP, - active_time DATETIME, - is_del INTEGER DEFAULT 0 NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS user ( + user_id INTEGER PRIMARY KEY AUTOINCREMENT, + email TEXT NOT NULL, + type INTEGER DEFAULT 1 NOT NULL, + password TEXT NOT NULL, + salt TEXT NOT NULL, + status INTEGER DEFAULT 0 NOT NULL, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + active_time DATETIME, + is_del INTEGER DEFAULT 0 NOT NULL + ) + `).run(); await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS account ( - account_id INTEGER PRIMARY KEY AUTOINCREMENT, - email TEXT NOT NULL, - status INTEGER DEFAULT 0 NOT NULL, - latest_email_time DATETIME, - create_time DATETIME DEFAULT CURRENT_TIMESTAMP, - user_id INTEGER NOT NULL, - is_del INTEGER DEFAULT 0 NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS account ( + account_id INTEGER PRIMARY KEY AUTOINCREMENT, + email TEXT NOT NULL, + status INTEGER DEFAULT 0 NOT NULL, + latest_email_time DATETIME, + create_time DATETIME DEFAULT CURRENT_TIMESTAMP, + user_id INTEGER NOT NULL, + is_del INTEGER DEFAULT 0 NOT NULL + ) + `).run(); await c.env.db.prepare(` - CREATE TABLE IF NOT EXISTS setting ( - register INTEGER NOT NULL, - receive INTEGER NOT NULL, - add_email INTEGER NOT NULL, - many_email INTEGER NOT NULL, - title TEXT NOT NULL, - auto_refresh_time INTEGER NOT NULL, - register_verify INTEGER NOT NULL, - add_email_verify INTEGER NOT NULL - ) - `).run(); + CREATE TABLE IF NOT EXISTS setting ( + register INTEGER NOT NULL, + receive INTEGER NOT NULL, + add_email INTEGER NOT NULL, + many_email INTEGER NOT NULL, + title TEXT NOT NULL, + auto_refresh INTEGER NOT NULL, + register_verify INTEGER NOT NULL, + add_email_verify INTEGER NOT NULL + ) + `).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) { diff --git a/mail-worker/src/service/email-service.js b/mail-worker/src/service/email-service.js index b2238a5..f9f860b 100644 --- a/mail-worker/src/service/email-service.js +++ b/mail-worker/src/service/email-service.js @@ -17,9 +17,9 @@ import starService from './star-service'; import dayjs from 'dayjs'; import kvConst from '../const/kv-const'; import { t } from '../i18n/i18n' -import r2Service from './r2-service'; import domainUtils from '../utils/domain-uitls'; import account from "../entity/account"; +import {sleep} from "../utils/time-utils"; const emailService = { @@ -452,22 +452,30 @@ const emailService = { allReceive = accountRow.allReceive; } - const list = await orm(c).select({...email}).from(email) - .leftJoin( - account, - eq(account.accountId, email.accountId) - ) - .where( - and( - eq(email.userId, userId), - eq(email.isDel, isDel.NORMAL), - eq(account.isDel, isDel.NORMAL), - allReceive ? eq(1,1) : eq(email.accountId, accountId), - eq(email.type, emailConst.type.RECEIVE), - gt(email.emailId, emailId) - )) - .orderBy(desc(email.emailId)) - .limit(20); + let count = 0 + let list = [] + + while ((count < 10) && list.length === 0) { + list = await orm(c).select({...email}).from(email) + .leftJoin( + account, + eq(account.accountId, email.accountId) + ) + .where( + and( + eq(email.userId, userId), + eq(email.isDel, isDel.NORMAL), + eq(account.isDel, isDel.NORMAL), + allReceive ? eq(1,1) : eq(email.accountId, accountId), + 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); diff --git a/mail-worker/src/service/setting-service.js b/mail-worker/src/service/setting-service.js index cccc6d5..294b942 100644 --- a/mail-worker/src/service/setting-service.js +++ b/mail-worker/src/service/setting-service.js @@ -176,7 +176,7 @@ const settingService = { title: settingRow.title, manyEmail: settingRow.manyEmail, addEmail: settingRow.addEmail, - autoRefreshTime: settingRow.autoRefreshTime, + autoRefresh: settingRow.autoRefresh, addEmailVerify: settingRow.addEmailVerify, registerVerify: settingRow.registerVerify, send: settingRow.send, diff --git a/mail-worker/src/utils/time-utils.js b/mail-worker/src/utils/time-utils.js new file mode 100644 index 0000000..82e7951 --- /dev/null +++ b/mail-worker/src/utils/time-utils.js @@ -0,0 +1,3 @@ +export function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)) +}