新增全部邮件自动刷新

This commit is contained in:
eoao
2026-01-13 00:42:34 +08:00
parent 454cde670c
commit 1cdca9107a
7 changed files with 174 additions and 48 deletions

View File

@@ -30,7 +30,7 @@
<div ref="scroll" class="scroll">
<el-scrollbar ref="scrollbarRef" style="height: 100%">
<div class="scroll-box" :infinite-scroll-immediate="false" v-infinite-scroll="loadData"
infinite-scroll-distance="600">
infinite-scroll-distance="3000">
<div v-if="(skeleton && !loading)" v-for="item in emailList" :key="item.emailId">
<div class="email-row"
:data-checked="item.checked"
@@ -252,7 +252,7 @@ let isMobile = ref(innerWidth < 1367)
let skeletonRows = 0
const queryParam = reactive({
emailId: 0,
size: 30,
size: 50,
});
defineExpose({

View File

@@ -11,3 +11,7 @@ export function allEmailDelete(emailIds) {
export function allEmailBatchDelete(params) {
return http.delete('/allEmail/batchDelete', {params: params} )
}
export function allEmailLatest(emailId) {
return http.get('/allEmail/latest', {params: {emailId}, noMsg: true, timeout: 35 * 1000})
}

View File

@@ -10,6 +10,7 @@
show-status
actionLeft="4px"
:show-account-icon="false"
:time-sort="params.timeSort"
@jump="jumpContent"
@refresh-before="refreshBefore"
:type="'all-email'"
@@ -87,24 +88,31 @@
<script setup>
import {starAdd, starCancel} from "@/request/star.js";
import emailScroll from "@/components/email-scroll/index.vue"
import {computed, defineOptions, reactive, ref, watch} from "vue";
import {computed, defineOptions, reactive, ref, watch, onMounted} from "vue";
import {useEmailStore} from "@/store/email.js";
import {
allEmailList,
allEmailDelete,
allEmailBatchDelete
allEmailBatchDelete,
allEmailLatest
} from "@/request/all-email.js";
import {Icon} from "@iconify/vue";
import router from "@/router/index.js";
import {useI18n} from 'vue-i18n';
import {toUtc} from "@/utils/day.js";
import {AutoRefreshEnum} from "@/enums/setting-enum.js";
import {sleep} from "@/utils/time-utils.js";
import {useSettingStore} from "@/store/setting.js";
import { useRoute } from 'vue-router'
defineOptions({
name: 'all-email'
})
const route = useRoute()
const {t} = useI18n();
const emailStore = useEmailStore();
const settingStore = useSettingStore();
const clearTime = ref('')
const sysEmailScroll = ref({})
const searchValue = ref('')
@@ -112,6 +120,10 @@ const mySelect = ref()
const showBathDelete = ref(false)
const clearLoading = ref(false)
onMounted(() => {
latest();
})
const openSelect = () => {
mySelect.value.toggleMenu()
}
@@ -272,6 +284,67 @@ function jumpContent(email) {
function getEmailList(emailId, size) {
return allEmailList({emailId, size, ...params})
}
async function latest() {
while (true) {
await sleep(1000)
const latestId = sysEmailScroll.value.latestEmail?.emailId
if (settingStore.settings.autoRefresh === AutoRefreshEnum.DISABLED) {
continue
}
if (!latestId && latestId !== 0) {
continue
}
if (route.name !== 'all-email') {
continue
}
if (params.type !== 'receive') {
continue
}
try {
const curTimeSort = params.timeSort
let list = await allEmailLatest(latestId)
if (list.length === 0) {
continue
}
if (params.type !== 'receive') {
continue
}
// 确保回来之后条件没变
if (params.timeSort !== curTimeSort) {
continue
}
for (let email of list) {
sysEmailScroll.value.addItem(email)
await sleep(50)
}
} catch (e) {
if (e.code === 401) {
settingStore.settings.autoRefresh = AutoRefreshEnum.DISABLED;
}
console.error(e)
}
}
}
</script>
<style>

View File

@@ -33,13 +33,14 @@ import {defineOptions, h, onMounted, reactive, ref, watch} from "vue";
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 { useRoute } from 'vue-router'
import {AutoRefreshEnum} from "@/enums/setting-enum.js";
defineOptions({
name: 'email'
})
const route = useRoute();
const emailStore = useEmailStore();
const accountStore = useAccountStore();
const settingStore = useSettingStore();
@@ -76,6 +77,13 @@ const existIds = new Set();
async function latest() {
while (true) {
await sleep(1000)
if (route.name !== 'email') {
continue;
}
const latestId = scroll.value.latestEmail?.emailId
if (!scroll.value.firstLoad && settingStore.settings.autoRefresh === AutoRefreshEnum.ENABLED) {
@@ -125,10 +133,12 @@ async function latest() {
}
} catch (e) {
if (e.code === 401) {
settingStore.settings.autoRefresh = AutoRefreshEnum.DISABLED;
}
console.error(e)
}
}
await sleep(500)
}
}

View File

@@ -2,17 +2,22 @@ import app from '../hono/hono';
import emailService from '../service/email-service';
import result from '../model/result';
app.get('/allEmail/list',async (c) => {
app.get('/allEmail/list', async (c) => {
const data = await emailService.allList(c, c.req.query());
return c.json(result.ok(data));
})
app.delete('/allEmail/delete',async (c) => {
app.delete('/allEmail/delete', async (c) => {
const list = await emailService.physicsDelete(c, c.req.query());
return c.json(result.ok(list));
})
app.delete('/allEmail/batchDelete',async (c) => {
app.delete('/allEmail/batchDelete', async (c) => {
await emailService.batchDelete(c, c.req.query());
return c.json(result.ok());
})
app.get('/allEmail/latest', async (c) => {
const list = await emailService.allEmailLatest(c, c.req.query());
return c.json(result.ok(list));
})

View File

@@ -74,7 +74,7 @@ const premKey = {
'user:set-status': ['/user/setStatus'],
'user:set-type': ['/user/setType'],
'user:delete': ['/user/delete','/user/deleteAccount'],
'all-email:query': ['/allEmail/list'],
'all-email:query': ['/allEmail/list','/allEmail/latest'],
'all-email:delete': ['/allEmail/delete','/allEmail/batchDelete'],
'setting:query': ['/setting/query'],
'setting:set': ['/setting/set', '/setting/setBackground','/setting/deleteBackground'],

View File

@@ -33,8 +33,8 @@ const emailService = {
accountId = Number(accountId);
allReceive = Number(allReceive);
if (size > 30) {
size = 30;
if (size > 50) {
size = 50;
}
if (!emailId) {
@@ -109,7 +109,7 @@ const emailService = {
eq(email.type, type),
eq(email.isDel, isDel.NORMAL)
))
.orderBy(desc(email.emailId)).limit(size).get();
.orderBy(desc(email.emailId)).limit(1).get();
let [list, totalRow, latestEmail] = await Promise.all([listQuery, totalQuery, latestEmailQuery]);
@@ -118,14 +118,8 @@ const emailService = {
isStar: item.starId != null ? 1 : 0
}));
const emailIds = list.map(item => item.emailId);
const attsList = await attService.selectByEmailIds(c, emailIds);
list.forEach(emailRow => {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts;
});
await this.emailAddAtt(c, list);
if (!latestEmail) {
latestEmail = {
@@ -477,17 +471,7 @@ const emailService = {
count++
}
const emailIds = list.map(item => item.emailId);
if (emailIds.length > 0) {
const attsList = await attService.selectByEmailIds(c, emailIds);
list.forEach(emailRow => {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts;
});
}
await this.emailAddAtt(c, list);
return list;
},
@@ -539,8 +523,8 @@ const emailService = {
emailId = Number(emailId);
timeSort = Number(timeSort);
if (size > 30) {
size = 30;
if (size > 50) {
size = 50;
}
if (!emailId) {
@@ -555,6 +539,11 @@ const emailService = {
const conditions = [];
if (timeSort) {
conditions.push(gt(email.emailId, emailId));
} else {
conditions.push(lt(email.emailId, emailId));
}
if (type === 'send') {
conditions.push(eq(email.type, emailConst.type.SEND));
@@ -597,12 +586,6 @@ const emailService = {
const countConditions = [...conditions];
if (timeSort) {
conditions.push(gt(email.emailId, emailId));
} else {
conditions.push(lt(email.emailId, emailId));
}
const query = orm(c).select({ ...email, userEmail: user.email })
.from(email)
.leftJoin(user, eq(email.userId, user.userId))
@@ -621,18 +604,69 @@ const emailService = {
const listQuery = await query.limit(size).all();
const totalQuery = await queryCount.get();
const latestEmailQuery = await orm(c).select().from(email)
.where(and(
eq(email.type, emailConst.type.RECEIVE),
ne(email.status, emailConst.status.SAVING)
))
.orderBy(desc(email.emailId)).limit(1).get();
const [list, totalRow] = await Promise.all([listQuery, totalQuery]);
let [list, totalRow, latestEmail] = await Promise.all([listQuery, totalQuery, latestEmailQuery]);
await this.emailAddAtt(c, list);
if (!latestEmail) {
latestEmail = {
emailId: 0,
accountId: 0,
userId: 0,
}
}
return { list: list, total: totalRow.total, latestEmail };
},
async allEmailLatest(c, params) {
const { emailId } = params;
let count = 0
let list = []
while ((count < 10) && list.length === 0) {
list = await orm(c).select({...email, userEmail: user.email}).from(email)
.leftJoin(user, eq(email.userId, user.userId))
.where(
and(
gt(email.emailId, emailId),
eq(email.type, emailConst.type.RECEIVE),
ne(email.status, emailConst.status.SAVING)
))
.orderBy(desc(email.emailId))
.limit(20);
await sleep(3000);
count++
}
await this.emailAddAtt(c, list);
return list;
},
async emailAddAtt(c, list) {
const emailIds = list.map(item => item.emailId);
const attsList = await attService.selectByEmailIds(c, emailIds);
list.forEach(emailRow => {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts;
});
if (emailIds.length > 0) {
return { list: list, total: totalRow.total };
const attsList = await attService.selectByEmailIds(c, emailIds);
list.forEach(emailRow => {
const atts = attsList.filter(attsRow => attsRow.emailId === emailRow.emailId);
emailRow.attList = atts;
});
}
},
async restoreByUserId(c, userId) {
@@ -647,8 +681,8 @@ const emailService = {
},
async completeReceiveAll(c) {
await c.env.db.prepare(`UPDATE email as e SET status = ${emailConst.status.RECEIVE} WHERE status = ${emailConst.status.SAVING} AND EXISTS (SELECT 1 FROM account WHERE account_id = e.account_id)`).run();
await c.env.db.prepare(`UPDATE email as e SET status = ${emailConst.status.NOONE} WHERE status = ${emailConst.status.SAVING} AND NOT EXISTS (SELECT 1 FROM account WHERE account_id = e.account_id)`).run();
await c.env.db.prepare(`UPDATE email as e SET status = ${emailConst.status.RECEIVE} WHERE status = ${emailConst.status.SAVING} AND EXISTS (SELECT 1 FROM account WHERE account_id = e.account_id)`).run();
await c.env.db.prepare(`UPDATE email as e SET status = ${emailConst.status.NOONE} WHERE status = ${emailConst.status.SAVING} AND NOT EXISTS (SELECT 1 FROM account WHERE account_id = e.account_id)`).run();
},
async batchDelete(c, params) {