mirror of
https://github.com/schroinerxy/cloud-mail.git
synced 2026-06-21 19:35:50 +08:00
新增邮箱列表置顶排序
This commit is contained in:
@@ -227,8 +227,7 @@ let skeletonRows = 0
|
|||||||
const timePaddingRight = ref('');
|
const timePaddingRight = ref('');
|
||||||
const keyCount = ref(0)
|
const keyCount = ref(0)
|
||||||
const queryParam = reactive({
|
const queryParam = reactive({
|
||||||
emailId: 0,
|
size: 50
|
||||||
size: 50,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@@ -507,7 +506,7 @@ function addItem(email) {
|
|||||||
emailList.push(email);
|
emailList.push(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (email.emailId > latestEmail.value.emailId) {
|
if (email.emailId > latestEmail.value?.emailId) {
|
||||||
latestEmail.value = email
|
latestEmail.value = email
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +527,7 @@ function addItem(email) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (email.emailId > latestEmail.value.emailId) {
|
if (email.emailId > latestEmail.value?.emailId) {
|
||||||
latestEmail.value = email
|
latestEmail.value = email
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,6 +565,8 @@ function getEmailList(refresh = false) {
|
|||||||
|
|
||||||
if (reqLock) return;
|
if (reqLock) return;
|
||||||
|
|
||||||
|
let emailId = emailList.length > 0 ? emailList.at(-1).emailId : 0;
|
||||||
|
|
||||||
reqLock = true
|
reqLock = true
|
||||||
|
|
||||||
if (!refresh) {
|
if (!refresh) {
|
||||||
@@ -577,6 +578,7 @@ function getEmailList(refresh = false) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
getSkeletonRows()
|
getSkeletonRows()
|
||||||
|
emailId = 0
|
||||||
loading.value = true
|
loading.value = true
|
||||||
scrollTop = 0
|
scrollTop = 0
|
||||||
}
|
}
|
||||||
@@ -587,10 +589,11 @@ function getEmailList(refresh = false) {
|
|||||||
followLoading.value = !refresh;
|
followLoading.value = !refresh;
|
||||||
}
|
}
|
||||||
let start = Date.now();
|
let start = Date.now();
|
||||||
props.getEmailList(queryParam.emailId, queryParam.size).then(async data => {
|
|
||||||
|
props.getEmailList(emailId, queryParam.size).then(async data => {
|
||||||
let end = Date.now();
|
let end = Date.now();
|
||||||
let duration = end - start;
|
let duration = end - start;
|
||||||
if (duration < 300 && !queryParam.emailId) {
|
if (duration < 300 && !emailId) {
|
||||||
await sleep(300 - duration)
|
await sleep(300 - duration)
|
||||||
}
|
}
|
||||||
firstLoad.value = false
|
firstLoad.value = false
|
||||||
@@ -615,7 +618,6 @@ function getEmailList(refresh = false) {
|
|||||||
followLoading.value = data.list.length >= queryParam.size;
|
followLoading.value = data.list.length >= queryParam.size;
|
||||||
|
|
||||||
total.value = data.total;
|
total.value = data.total;
|
||||||
queryParam.emailId = data.list.length > 0 ? data.list.at(-1).emailId : 0
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
reqLock = false
|
reqLock = false
|
||||||
@@ -653,7 +655,6 @@ function refresh() {
|
|||||||
function refreshList() {
|
function refreshList() {
|
||||||
checkAll.value = false;
|
checkAll.value = false;
|
||||||
isIndeterminate.value = false;
|
isIndeterminate.value = false;
|
||||||
queryParam.emailId = 0;
|
|
||||||
getEmailList(true);
|
getEmailList(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-scrollbar class="scrollbar" ref="scrollbarRef">
|
<el-scrollbar class="scrollbar" ref="scrollbarRef">
|
||||||
<div v-infinite-scroll="getAccountList" :infinite-scroll-distance="600" :infinite-scroll-immediate="false">
|
<div v-infinite-scroll="getAccountList" :infinite-scroll-distance="600" :infinite-scroll-immediate="false">
|
||||||
<el-card class="item" :class="itemBg(item.accountId)" v-for="item in accounts" :key="item.accountId"
|
<el-card class="item" :class="itemBg(item.accountId)" v-for="(item, index) in accounts" :key="item.accountId"
|
||||||
@click="changeAccount(item)">
|
@click="changeAccount(item)">
|
||||||
<div class="account">
|
<div class="account">
|
||||||
{{ item.email }}
|
{{ item.email }}
|
||||||
@@ -24,8 +24,8 @@
|
|||||||
<Icon icon="fluent:settings-24-filled" width="21" height="21" color="#909399"/>
|
<Icon icon="fluent:settings-24-filled" width="21" height="21" color="#909399"/>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item v-if="hasPerm('email:send')" @click="openSetName(item)">{{ $t('rename') }}
|
<el-dropdown-item v-if="hasPerm('email:send')" @click="openSetName(item)">{{ $t('rename') }}</el-dropdown-item>
|
||||||
</el-dropdown-item>
|
<el-dropdown-item v-if="item.accountId !== userStore.user.account.accountId" @click="setAsTop(item, index)">{{ $t('置顶') }}</el-dropdown-item>
|
||||||
<el-dropdown-item v-if="item.accountId !== userStore.user.account.accountId && hasPerm('account:delete')"
|
<el-dropdown-item v-if="item.accountId !== userStore.user.account.accountId && hasPerm('account:delete')"
|
||||||
@click="remove(item)">{{ $t('delete') }}
|
@click="remove(item)">{{ $t('delete') }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
@@ -128,7 +128,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {Icon} from "@iconify/vue";
|
import {Icon} from "@iconify/vue";
|
||||||
import {nextTick, reactive, ref, watch} from "vue";
|
import {nextTick, reactive, ref, watch} from "vue";
|
||||||
import {accountList, accountAdd, accountDelete, accountSetName, accountSetAllReceive} from "@/request/account.js";
|
import {
|
||||||
|
accountList,
|
||||||
|
accountAdd,
|
||||||
|
accountDelete,
|
||||||
|
accountSetName,
|
||||||
|
accountSetAllReceive,
|
||||||
|
accountSetAsTop
|
||||||
|
} from "@/request/account.js";
|
||||||
import {sleep} from "@/utils/time-utils.js"
|
import {sleep} from "@/utils/time-utils.js"
|
||||||
import {isEmail} from "@/utils/verify-utils.js";
|
import {isEmail} from "@/utils/verify-utils.js";
|
||||||
import {useSettingStore} from "@/store/setting.js";
|
import {useSettingStore} from "@/store/setting.js";
|
||||||
@@ -169,8 +176,7 @@ const addForm = reactive({
|
|||||||
})
|
})
|
||||||
let skeletonRows = 10
|
let skeletonRows = 10
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
accountId: 0,
|
size: 10
|
||||||
size: 20
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mySelect = ref()
|
const mySelect = ref()
|
||||||
@@ -288,6 +294,8 @@ function itemBg(accountId) {
|
|||||||
return accountStore.currentAccountId === accountId ? 'item-choose' : ''
|
return accountStore.currentAccountId === accountId ? 'item-choose' : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function remove(account) {
|
function remove(account) {
|
||||||
ElMessageBox.confirm(t('delConfirm', {msg: account.email}), {
|
ElMessageBox.confirm(t('delConfirm', {msg: account.email}), {
|
||||||
confirmButtonText: t('confirm'),
|
confirmButtonText: t('confirm'),
|
||||||
@@ -317,6 +325,7 @@ function refresh() {
|
|||||||
followLoading.value = false
|
followLoading.value = false
|
||||||
noLoading.value = false
|
noLoading.value = false
|
||||||
queryParams.accountId = 0
|
queryParams.accountId = 0
|
||||||
|
queryParams.lastSort = null
|
||||||
getSkeletonRows();
|
getSkeletonRows();
|
||||||
scrollbarRef.value.setScrollTop(0)
|
scrollbarRef.value.setScrollTop(0)
|
||||||
accounts.splice(0, accounts.length)
|
accounts.splice(0, accounts.length)
|
||||||
@@ -335,6 +344,20 @@ function add() {
|
|||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setAsTop(account, index) {
|
||||||
|
accountSetAsTop(account.accountId).then(() => {
|
||||||
|
ElMessage({
|
||||||
|
message: t('setSuccess'),
|
||||||
|
type: 'success',
|
||||||
|
plain: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const [item] = accounts.splice(index, 1);
|
||||||
|
accounts.splice(1, 0, item);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function copyAccount(account) {
|
async function copyAccount(account) {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(account);
|
await navigator.clipboard.writeText(account);
|
||||||
@@ -365,7 +388,10 @@ function getAccountList() {
|
|||||||
|
|
||||||
let start = Date.now();
|
let start = Date.now();
|
||||||
|
|
||||||
accountList(queryParams.accountId, queryParams.size).then(async list => {
|
const accountId = accounts.length > 0 ? accounts.at(-1).accountId : 0;
|
||||||
|
const lastSort = accounts.length > 0 ? accounts.at(-1).sort : null;
|
||||||
|
|
||||||
|
accountList(accountId, queryParams.size, lastSort).then(async list => {
|
||||||
|
|
||||||
let end = Date.now();
|
let end = Date.now();
|
||||||
let duration = end - start;
|
let duration = end - start;
|
||||||
@@ -379,7 +405,7 @@ function getAccountList() {
|
|||||||
if (accounts.length === 0) {
|
if (accounts.length === 0) {
|
||||||
accountStore.currentAccount = list[0]
|
accountStore.currentAccount = list[0]
|
||||||
}
|
}
|
||||||
queryParams.accountId = list.at(-1).accountId
|
|
||||||
accounts.push(...list)
|
accounts.push(...list)
|
||||||
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import http from '@/axios/index.js'
|
import http from '@/axios/index.js'
|
||||||
|
|
||||||
export function accountList(accountId, size) {
|
export function accountList(accountId, size, lastSort) {
|
||||||
return http.get('/account/list', {params: {accountId, size}});
|
return http.get('/account/list', {params: {accountId, size, lastSort}});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function accountAdd(email,token) {
|
export function accountAdd(email,token) {
|
||||||
@@ -20,3 +20,6 @@ export function accountSetAllReceive(accountId) {
|
|||||||
return http.put('/account/setAllReceive', {accountId})
|
return http.put('/account/setAllReceive', {accountId})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function accountSetAsTop(accountId) {
|
||||||
|
return http.put('/account/setAsTop', {accountId})
|
||||||
|
}
|
||||||
@@ -27,3 +27,8 @@ app.put('/account/setAllReceive', async (c) => {
|
|||||||
await accountService.setAllReceive(c, await c.req.json(), userContext.getUserId(c));
|
await accountService.setAllReceive(c, await c.req.json(), userContext.getUserId(c));
|
||||||
return c.json(result.ok());
|
return c.json(result.ok());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.put('/account/setAsTop', async (c) => {
|
||||||
|
await accountService.setAsTop(c, await c.req.json(), userContext.getUserId(c));
|
||||||
|
return c.json(result.ok());
|
||||||
|
});
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export const account = sqliteTable('account', {
|
|||||||
createTime: text('create_time').default(sql`CURRENT_TIMESTAMP`),
|
createTime: text('create_time').default(sql`CURRENT_TIMESTAMP`),
|
||||||
userId: integer('user_id').notNull(),
|
userId: integer('user_id').notNull(),
|
||||||
allReceive: integer('all_receive').default(0).notNull(),
|
allReceive: integer('all_receive').default(0).notNull(),
|
||||||
|
sort: integer('sort').default(0).notNull(),
|
||||||
isDel: integer('is_del').default(0).notNull(),
|
isDel: integer('is_del').default(0).notNull(),
|
||||||
});
|
});
|
||||||
export default account
|
export default account
|
||||||
|
|||||||
@@ -26,10 +26,21 @@ const dbInit = {
|
|||||||
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 this.v2_7DB(c);
|
||||||
|
await this.v2_8DB(c);
|
||||||
await settingService.refresh(c);
|
await settingService.refresh(c);
|
||||||
return c.text('success');
|
return c.text('success');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async v2_8DB(c) {
|
||||||
|
try {
|
||||||
|
await c.env.db.batch([
|
||||||
|
c.env.db.prepare(`ALTER TABLE account ADD COLUMN sort INTEGER NOT NULL DEFAULT 0;`)
|
||||||
|
]);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`跳过字段:${e.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async v2_7DB(c) {
|
async v2_7DB(c) {
|
||||||
try {
|
try {
|
||||||
await c.env.db.batch([
|
await c.env.db.batch([
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import userService from './user-service';
|
|||||||
import emailService from './email-service';
|
import emailService from './email-service';
|
||||||
import orm from '../entity/orm';
|
import orm from '../entity/orm';
|
||||||
import account from '../entity/account';
|
import account from '../entity/account';
|
||||||
import { and, asc, eq, gt, inArray, count, sql, ne } from 'drizzle-orm';
|
import { and, asc, eq, gt, inArray, count, sql, ne, or, lt, desc } from 'drizzle-orm';
|
||||||
import {accountConst, isDel, settingConst} from '../const/entity-const';
|
import {accountConst, isDel, settingConst} from '../const/entity-const';
|
||||||
import settingService from './setting-service';
|
import settingService from './setting-service';
|
||||||
import turnstileService from './turnstile-service';
|
import turnstileService from './turnstile-service';
|
||||||
@@ -105,10 +105,11 @@ const accountService = {
|
|||||||
|
|
||||||
list(c, params, userId) {
|
list(c, params, userId) {
|
||||||
|
|
||||||
let { accountId, size } = params;
|
let { accountId, size, lastSort } = params;
|
||||||
|
|
||||||
accountId = Number(accountId);
|
accountId = Number(accountId);
|
||||||
size = Number(size);
|
size = Number(size);
|
||||||
|
lastSort = Number(lastSort);
|
||||||
|
|
||||||
if (size > 30) {
|
if (size > 30) {
|
||||||
size = 30;
|
size = 30;
|
||||||
@@ -117,12 +118,24 @@ const accountService = {
|
|||||||
if (!accountId) {
|
if (!accountId) {
|
||||||
accountId = 0;
|
accountId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Number.isNaN(lastSort)) {
|
||||||
|
lastSort = 9999999999;
|
||||||
|
}
|
||||||
|
|
||||||
return orm(c).select().from(account).where(
|
return orm(c).select().from(account).where(
|
||||||
and(
|
and(
|
||||||
eq(account.userId, userId),
|
eq(account.userId, userId),
|
||||||
eq(account.isDel, isDel.NORMAL),
|
eq(account.isDel, isDel.NORMAL),
|
||||||
gt(account.accountId, accountId)))
|
or(
|
||||||
.orderBy(asc(account.accountId))
|
lt(account.sort, lastSort),
|
||||||
|
and(
|
||||||
|
eq(account.sort, lastSort),
|
||||||
|
gt(account.accountId, accountId)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
.orderBy(desc(account.sort), asc(account.accountId))
|
||||||
.limit(size)
|
.limit(size)
|
||||||
.all();
|
.all();
|
||||||
},
|
},
|
||||||
@@ -242,6 +255,16 @@ const accountService = {
|
|||||||
}
|
}
|
||||||
await orm(c).update(account).set({ allReceive: accountConst.allReceive.CLOSE }).where(eq(account.userId, userId)).run();
|
await orm(c).update(account).set({ allReceive: accountConst.allReceive.CLOSE }).where(eq(account.userId, userId)).run();
|
||||||
await orm(c).update(account).set({ allReceive: accountRow.allReceive ? 0 : 1 }).where(eq(account.accountId, accountId)).run();
|
await orm(c).update(account).set({ allReceive: accountRow.allReceive ? 0 : 1 }).where(eq(account.accountId, accountId)).run();
|
||||||
|
},
|
||||||
|
|
||||||
|
async setAsTop(c, params, userId) {
|
||||||
|
const { accountId } = params;
|
||||||
|
console.log(accountId);
|
||||||
|
const userRow = await userService.selectById(c, userId);
|
||||||
|
const mainAccountRow = await accountService.selectByEmailIncludeDel(c, userRow.email);
|
||||||
|
let mainSort = mainAccountRow.sort === 0 ? 2 : mainAccountRow.sort + 1;
|
||||||
|
await orm(c).update(account).set({ sort: mainSort }).where(eq(account.email, userRow.email )).run();
|
||||||
|
await orm(c).update(account).set({ sort: mainSort - 1 }).where(and(eq(account.accountId, accountId),eq(account.userId,userId))).run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -457,12 +457,12 @@ const emailService = {
|
|||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
|
gt(email.emailId, emailId),
|
||||||
eq(email.userId, userId),
|
eq(email.userId, userId),
|
||||||
eq(email.isDel, isDel.NORMAL),
|
eq(email.isDel, isDel.NORMAL),
|
||||||
eq(account.isDel, isDel.NORMAL),
|
eq(account.isDel, isDel.NORMAL),
|
||||||
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
allReceive ? eq(1,1) : eq(email.accountId, accountId),
|
||||||
eq(email.type, emailConst.type.RECEIVE),
|
eq(email.type, emailConst.type.RECEIVE)
|
||||||
gt(email.emailId, emailId)
|
|
||||||
))
|
))
|
||||||
.orderBy(desc(email.emailId))
|
.orderBy(desc(email.emailId))
|
||||||
.limit(20);
|
.limit(20);
|
||||||
|
|||||||
Reference in New Issue
Block a user