feat(account-management): optimize account loading with async validation
- Add new /getAccounts API for fast account retrieval without validation - Update frontend to use fast API for initial load, showing accounts immediately - Add '验证中' status with loading animation to indicate validation progress - Implement background validation process that doesn't block UI - Add Loading icon from Element Plus for visual feedback during validation - Update status display logic to handle '验证中', '正常', and invalid states - Improve user experience with immediate feedback and async validation
This commit is contained in:
@@ -186,6 +186,37 @@ def get_all_files():
|
|||||||
}), 500
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/getAccounts", methods=['GET'])
|
||||||
|
def getAccounts():
|
||||||
|
"""快速获取所有账号信息,不进行cookie验证"""
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(Path(BASE_DIR / "db" / "database.db")) as conn:
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT * FROM user_info''')
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
rows_list = [list(row) for row in rows]
|
||||||
|
|
||||||
|
print("\n📋 当前数据表内容(快速获取):")
|
||||||
|
for row in rows:
|
||||||
|
print(row)
|
||||||
|
|
||||||
|
return jsonify(
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": None,
|
||||||
|
"data": rows_list
|
||||||
|
}), 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取账号列表时出错: {str(e)}")
|
||||||
|
return jsonify({
|
||||||
|
"code": 500,
|
||||||
|
"msg": f"获取账号列表失败: {str(e)}",
|
||||||
|
"data": None
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
@app.route("/getValidAccounts",methods=['GET'])
|
@app.route("/getValidAccounts",methods=['GET'])
|
||||||
async def getValidAccounts():
|
async def getValidAccounts():
|
||||||
with sqlite3.connect(Path(BASE_DIR / "db" / "database.db")) as conn:
|
with sqlite3.connect(Path(BASE_DIR / "db" / "database.db")) as conn:
|
||||||
|
|||||||
@@ -2,11 +2,16 @@ import { http } from '@/utils/request'
|
|||||||
|
|
||||||
// 账号管理相关API
|
// 账号管理相关API
|
||||||
export const accountApi = {
|
export const accountApi = {
|
||||||
// 获取有效账号列表
|
// 获取有效账号列表(带验证)
|
||||||
getValidAccounts() {
|
getValidAccounts() {
|
||||||
return http.get('/getValidAccounts')
|
return http.get('/getValidAccounts')
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取账号列表(不带验证,快速加载)
|
||||||
|
getAccounts() {
|
||||||
|
return http.get('/getAccounts')
|
||||||
|
},
|
||||||
|
|
||||||
// 添加账号
|
// 添加账号
|
||||||
addAccount(data) {
|
addAccount(data) {
|
||||||
return http.post('/account', data)
|
return http.post('/account', data)
|
||||||
|
|||||||
@@ -47,9 +47,12 @@
|
|||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag
|
||||||
:type="scope.row.status === '正常' ? 'success' : 'danger'"
|
:type="getStatusTagType(scope.row.status)"
|
||||||
effect="plain"
|
effect="plain"
|
||||||
>
|
>
|
||||||
|
<el-icon :class="scope.row.status === '验证中' ? 'is-loading' : ''" v-if="scope.row.status === '验证中'">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
{{ scope.row.status }}
|
{{ scope.row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -112,9 +115,12 @@
|
|||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag
|
||||||
:type="scope.row.status === '正常' ? 'success' : 'danger'"
|
:type="getStatusTagType(scope.row.status)"
|
||||||
effect="plain"
|
effect="plain"
|
||||||
>
|
>
|
||||||
|
<el-icon :class="scope.row.status === '验证中' ? 'is-loading' : ''" v-if="scope.row.status === '验证中'">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
{{ scope.row.status }}
|
{{ scope.row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -177,9 +183,12 @@
|
|||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag
|
||||||
:type="scope.row.status === '正常' ? 'success' : 'danger'"
|
:type="getStatusTagType(scope.row.status)"
|
||||||
effect="plain"
|
effect="plain"
|
||||||
>
|
>
|
||||||
|
<el-icon :class="scope.row.status === '验证中' ? 'is-loading' : ''" v-if="scope.row.status === '验证中'">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
{{ scope.row.status }}
|
{{ scope.row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -242,9 +251,12 @@
|
|||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag
|
||||||
:type="scope.row.status === '正常' ? 'success' : 'danger'"
|
:type="getStatusTagType(scope.row.status)"
|
||||||
effect="plain"
|
effect="plain"
|
||||||
>
|
>
|
||||||
|
<el-icon :class="scope.row.status === '验证中' ? 'is-loading' : ''" v-if="scope.row.status === '验证中'">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
{{ scope.row.status }}
|
{{ scope.row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -307,9 +319,12 @@
|
|||||||
<el-table-column prop="status" label="状态">
|
<el-table-column prop="status" label="状态">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag
|
||||||
:type="scope.row.status === '正常' ? 'success' : 'danger'"
|
:type="getStatusTagType(scope.row.status)"
|
||||||
effect="plain"
|
effect="plain"
|
||||||
>
|
>
|
||||||
|
<el-icon :class="scope.row.status === '验证中' ? 'is-loading' : ''" v-if="scope.row.status === '验证中'">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
{{ scope.row.status }}
|
{{ scope.row.status }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -403,7 +418,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'
|
import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||||
import { Refresh, CircleCheckFilled, CircleCloseFilled, Download, Upload } from '@element-plus/icons-vue'
|
import { Refresh, CircleCheckFilled, CircleCloseFilled, Download, Upload, Loading } from '@element-plus/icons-vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { accountApi } from '@/api/account'
|
import { accountApi } from '@/api/account'
|
||||||
import { useAccountStore } from '@/stores/account'
|
import { useAccountStore } from '@/stores/account'
|
||||||
@@ -420,7 +435,26 @@ const activeTab = ref('all')
|
|||||||
// 搜索关键词
|
// 搜索关键词
|
||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
|
|
||||||
// 获取账号数据
|
// 获取账号数据(快速,不验证)
|
||||||
|
const fetchAccountsQuick = async () => {
|
||||||
|
try {
|
||||||
|
const res = await accountApi.getAccounts()
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
// 将所有账号的状态暂时设为"验证中"
|
||||||
|
const accountsWithPendingStatus = res.data.map(account => {
|
||||||
|
// account[4] 是状态字段,暂时设为"验证中"
|
||||||
|
const updatedAccount = [...account];
|
||||||
|
updatedAccount[4] = '验证中'; // 临时状态
|
||||||
|
return updatedAccount;
|
||||||
|
});
|
||||||
|
accountStore.setAccounts(accountsWithPendingStatus);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('快速获取账号数据失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取账号数据(带验证)
|
||||||
const fetchAccounts = async () => {
|
const fetchAccounts = async () => {
|
||||||
if (appStore.isAccountRefreshing) return
|
if (appStore.isAccountRefreshing) return
|
||||||
|
|
||||||
@@ -446,12 +480,30 @@ const fetchAccounts = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 后台验证所有账号(优化版本,使用setTimeout避免阻塞UI)
|
||||||
|
const validateAllAccountsInBackground = async () => {
|
||||||
|
// 使用setTimeout将验证过程放在下一个事件循环,避免阻塞UI
|
||||||
|
setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
const res = await accountApi.getValidAccounts()
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
accountStore.setAccounts(res.data)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('后台验证账号失败:', error)
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// 页面加载时获取账号数据
|
// 页面加载时获取账号数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 只有第一次进入时才获取数据
|
// 快速获取账号列表(不验证),立即显示
|
||||||
if (appStore.isFirstTimeAccountManagement) {
|
fetchAccountsQuick()
|
||||||
fetchAccounts()
|
|
||||||
}
|
// 在后台验证所有账号
|
||||||
|
setTimeout(() => {
|
||||||
|
validateAllAccountsInBackground()
|
||||||
|
}, 100) // 稍微延迟一下,让用户看到快速加载的效果
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取平台标签类型
|
// 获取平台标签类型
|
||||||
@@ -465,6 +517,17 @@ const getPlatformTagType = (platform) => {
|
|||||||
return typeMap[platform] || 'info'
|
return typeMap[platform] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取状态标签类型
|
||||||
|
const getStatusTagType = (status) => {
|
||||||
|
if (status === '验证中') {
|
||||||
|
return 'info'; // 验证中使用灰色
|
||||||
|
} else if (status === '正常') {
|
||||||
|
return 'success'; // 正常使用绿色
|
||||||
|
} else {
|
||||||
|
return 'danger'; // 无效使用红色
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 过滤后的账号列表
|
// 过滤后的账号列表
|
||||||
const filteredAccounts = computed(() => {
|
const filteredAccounts = computed(() => {
|
||||||
if (!searchKeyword.value) return accountStore.accounts
|
if (!searchKeyword.value) return accountStore.accounts
|
||||||
|
|||||||
Reference in New Issue
Block a user