通知中心游标分页
This commit is contained in:
1 parent
172577f668
commit
f5db2f6e77
4 files changed
+160
-64
No files matched your search
@@ -28,7 +28,6 @@ const activeTab = ref<'inbox' | 'compose' | 'sent'>('inbox')
|
||||
const notifications = ref<any[]>([])
|
||||
const sentMessages = ref<any[]>([])
|
||||
const unreadCount = ref(0)
|
||||
const sentTotal = ref(0)
|
||||
const loading = ref(false)
|
||||
const markingAllRead = ref(false)
|
||||
const sending = ref(false)
|
||||
@@ -39,7 +38,13 @@ const inboxCursors = ref<string[]>([])
|
||||
const nextInboxCursor = ref<string>()
|
||||
const inboxHasMore = ref(false)
|
||||
const sentPage = ref(1)
|
||||
const sentCursors = ref<string[]>([])
|
||||
const nextSentCursor = ref<string>()
|
||||
const sentHasMore = ref(false)
|
||||
const recipientPage = ref(1)
|
||||
const recipientCursors = ref<string[]>([])
|
||||
const nextRecipientCursor = ref<string>()
|
||||
const recipientHasMore = ref(false)
|
||||
const pageSize = 20
|
||||
const recipientPageSize = 30
|
||||
const unreadOnly = ref(false)
|
||||
@@ -169,14 +174,19 @@ async function previousInboxPage() {
|
||||
}
|
||||
|
||||
async function loadSent(reset = false) {
|
||||
if (reset) sentPage.value = 1
|
||||
if (reset) {
|
||||
sentPage.value = 1
|
||||
sentCursors.value = []
|
||||
nextSentCursor.value = undefined
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
const { data } = await http.get('/notifications/sent', {
|
||||
params: { page: sentPage.value, pageSize },
|
||||
params: { cursor: sentCursors.value.at(-1), pageSize },
|
||||
})
|
||||
sentMessages.value = data.items
|
||||
sentTotal.value = data.total
|
||||
sentHasMore.value = data.hasMore
|
||||
nextSentCursor.value = data.nextCursor
|
||||
} catch (error) {
|
||||
ElMessage.error(apiErrorMessage(error))
|
||||
} finally {
|
||||
@@ -184,6 +194,20 @@ async function loadSent(reset = false) {
|
||||
}
|
||||
}
|
||||
|
||||
async function nextSentPage() {
|
||||
if (!nextSentCursor.value || loading.value) return
|
||||
sentCursors.value.push(nextSentCursor.value)
|
||||
sentPage.value++
|
||||
await loadSent()
|
||||
}
|
||||
|
||||
async function previousSentPage() {
|
||||
if (!sentCursors.value.length || loading.value) return
|
||||
sentCursors.value.pop()
|
||||
sentPage.value--
|
||||
await loadSent()
|
||||
}
|
||||
|
||||
async function loadComposer() {
|
||||
if (!canSend.value || composer.value) return
|
||||
composerLoading.value = true
|
||||
@@ -206,14 +230,18 @@ function recipientParams() {
|
||||
administrativeClassId: recipientFilters.administrativeClassId || undefined,
|
||||
teachingTaskId: recipientFilters.teachingTaskId || undefined,
|
||||
keyword: recipientFilters.keyword.trim() || undefined,
|
||||
page: recipientPage.value,
|
||||
cursor: recipientCursors.value.at(-1),
|
||||
pageSize: recipientPageSize,
|
||||
}
|
||||
}
|
||||
|
||||
async function loadRecipients(reset = false) {
|
||||
if (!isAdministratorComposer.value) return
|
||||
if (reset) recipientPage.value = 1
|
||||
if (reset) {
|
||||
recipientPage.value = 1
|
||||
recipientCursors.value = []
|
||||
nextRecipientCursor.value = undefined
|
||||
}
|
||||
recipientLoading.value = true
|
||||
try {
|
||||
const { data } = await http.get('/notifications/recipients', {
|
||||
@@ -221,6 +249,8 @@ async function loadRecipients(reset = false) {
|
||||
})
|
||||
recipientItems.value = data.items
|
||||
recipientTotal.value = data.total
|
||||
recipientHasMore.value = data.hasMore
|
||||
nextRecipientCursor.value = data.nextCursor
|
||||
} catch (error) {
|
||||
ElMessage.error(apiErrorMessage(error))
|
||||
} finally {
|
||||
@@ -228,6 +258,20 @@ async function loadRecipients(reset = false) {
|
||||
}
|
||||
}
|
||||
|
||||
async function nextRecipientPage() {
|
||||
if (!nextRecipientCursor.value || recipientLoading.value) return
|
||||
recipientCursors.value.push(nextRecipientCursor.value)
|
||||
recipientPage.value++
|
||||
await loadRecipients()
|
||||
}
|
||||
|
||||
async function previousRecipientPage() {
|
||||
if (!recipientCursors.value.length || recipientLoading.value) return
|
||||
recipientCursors.value.pop()
|
||||
recipientPage.value--
|
||||
await loadRecipients()
|
||||
}
|
||||
|
||||
async function changeRecipientMode(value: 'Scope' | 'Filtered' | 'Selected') {
|
||||
recipientMode.value = value
|
||||
if (value !== 'Scope') await loadRecipients(true)
|
||||
@@ -685,16 +729,11 @@ onMounted(() => load())
|
||||
description="没有符合条件的可用账号"
|
||||
/>
|
||||
</div>
|
||||
<el-pagination
|
||||
v-if="recipientTotal > recipientPageSize"
|
||||
v-model:current-page="recipientPage"
|
||||
small
|
||||
background
|
||||
:page-size="recipientPageSize"
|
||||
:total="recipientTotal"
|
||||
layout="prev, pager, next"
|
||||
@current-change="loadRecipients()"
|
||||
/>
|
||||
<div v-if="recipientCursors.length || recipientHasMore" class="cursor-pager">
|
||||
<el-button size="small" :disabled="!recipientCursors.length || recipientLoading" @click="previousRecipientPage">上一批</el-button>
|
||||
<span>第 {{ recipientPage }} 批</span>
|
||||
<el-button size="small" type="primary" :disabled="!recipientHasMore || recipientLoading" @click="nextRecipientPage">下一批</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -828,14 +867,14 @@ onMounted(() => load())
|
||||
<el-empty v-if="!loading && !sentMessages.length" description="还没有发送记录" />
|
||||
</section>
|
||||
|
||||
<div v-if="sentTotal > pageSize" class="message-pager">
|
||||
<el-pagination
|
||||
v-model:current-page="sentPage"
|
||||
:page-size="pageSize"
|
||||
:total="sentTotal"
|
||||
layout="prev, pager, next, total"
|
||||
@current-change="loadSent()"
|
||||
/>
|
||||
<div v-if="sentCursors.length || sentHasMore" class="message-pager">
|
||||
<el-button :disabled="!sentCursors.length || loading" @click="previousSentPage">
|
||||
上一批
|
||||
</el-button>
|
||||
<span>第 {{ sentPage }} 批</span>
|
||||
<el-button type="primary" :disabled="!sentHasMore || loading" @click="nextSentPage">
|
||||
下一批
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@ const loading = ref(false)
|
||||
const detecting = ref(false)
|
||||
const filterType = ref('')
|
||||
const recordsPage = ref(1)
|
||||
const recordsTotal = ref(0)
|
||||
const recordsCursors = ref<string[]>([])
|
||||
const nextRecordsCursor = ref<string>()
|
||||
const recordsHasMore = ref(false)
|
||||
const recordsPageSize = 20
|
||||
const riskCases = ref<any[]>([])
|
||||
const riskDialogVisible = ref(false)
|
||||
@@ -49,7 +51,11 @@ const ruleRows = reactive([
|
||||
])
|
||||
|
||||
async function load(resetRecordsPage = false) {
|
||||
if (resetRecordsPage) recordsPage.value = 1
|
||||
if (resetRecordsPage) {
|
||||
recordsPage.value = 1
|
||||
recordsCursors.value = []
|
||||
nextRecordsCursor.value = undefined
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
if (isWarningManager.value && termId.value) {
|
||||
@@ -77,16 +83,13 @@ async function load(resetRecordsPage = false) {
|
||||
params: {
|
||||
academicTermId: termId.value || undefined,
|
||||
type: filterType.value || undefined,
|
||||
page: recordsPage.value,
|
||||
cursor: recordsCursors.value.at(-1),
|
||||
pageSize: recordsPageSize,
|
||||
},
|
||||
})
|
||||
records.value = response.data.items
|
||||
recordsTotal.value = response.data.total
|
||||
if (records.value.length === 0 && recordsPage.value > 1) {
|
||||
recordsPage.value--
|
||||
await load()
|
||||
}
|
||||
recordsHasMore.value = response.data.hasMore
|
||||
nextRecordsCursor.value = response.data.nextCursor
|
||||
riskCases.value = (await http.get('/warnings/risk-cases', { params: { mineOnly: isCounselor.value } })).data
|
||||
}
|
||||
if (isStudent.value) {
|
||||
@@ -96,6 +99,20 @@ async function load(resetRecordsPage = false) {
|
||||
} catch (e) { ElMessage.error(apiErrorMessage(e)) } finally { loading.value = false }
|
||||
}
|
||||
|
||||
async function nextRecordsPage() {
|
||||
if (!nextRecordsCursor.value || loading.value) return
|
||||
recordsCursors.value.push(nextRecordsCursor.value)
|
||||
recordsPage.value++
|
||||
await load()
|
||||
}
|
||||
|
||||
async function previousRecordsPage() {
|
||||
if (!recordsCursors.value.length || loading.value) return
|
||||
recordsCursors.value.pop()
|
||||
recordsPage.value--
|
||||
await load()
|
||||
}
|
||||
|
||||
async function saveRules() {
|
||||
try {
|
||||
const payload = ruleRows.map(r => ({ type: r.type, name: r.name, threshold: r.threshold, isEnabled: r.isEnabled, notifyStudent: r.notifyStudent, notifyCounselor: r.notifyCounselor, description: r.description, autoCheckEnabled: r.autoCheckEnabled, checkDayOfWeek: r.checkDayOfWeek, checkHour: r.checkHour, checkMinute: r.checkMinute }))
|
||||
@@ -220,15 +237,11 @@ onMounted(async () => {
|
||||
<el-table-column label="阈值/详情" min-width="200"><template #default="{row}"><span>{{ row.triggerValue }}</span><p style="margin:0;font-size:11px;color:var(--muted)">{{ row.detail }}</p></template></el-table-column>
|
||||
<el-table-column label="状态" width="100"><template #default="{row}"><el-tag size="small" :type="row.status===1?'danger':row.status===2?'success':'info'">{{ statusLabels[row.status] }}</el-tag></template></el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-if="recordsTotal > recordsPageSize"
|
||||
v-model:current-page="recordsPage"
|
||||
:page-size="recordsPageSize"
|
||||
:total="recordsTotal"
|
||||
layout="total, prev, pager, next"
|
||||
class="table-pagination"
|
||||
@current-change="() => load()"
|
||||
/>
|
||||
<div v-if="recordsCursors.length || recordsHasMore" class="table-pagination cursor-pager">
|
||||
<el-button :disabled="!recordsCursors.length || loading" @click="previousRecordsPage">上一批</el-button>
|
||||
<span>第 {{ recordsPage }} 批</span>
|
||||
<el-button type="primary" :disabled="!recordsHasMore || loading" @click="nextRecordsPage">下一批</el-button>
|
||||
</div>
|
||||
<el-empty v-if="!records.length" description="暂无预警记录,请先执行检测。" />
|
||||
</section>
|
||||
|
||||
|
||||
Reference in new issue
Block a user