优化删除
This commit is contained in:
@@ -55,6 +55,10 @@ export interface UpdateQrCodePayload {
|
||||
clear_expires_at?: boolean
|
||||
}
|
||||
|
||||
export interface BatchDeleteQrCodeResult {
|
||||
deleted: number
|
||||
}
|
||||
|
||||
export async function fetchQrCodes(query: QrCodeListQuery = {}) {
|
||||
const { data } = await apiClient.get<ApiResponse<PaginatedResult<ChatQrCode>>>(
|
||||
'/admin/chats/qrcodes',
|
||||
@@ -111,3 +115,11 @@ export async function deleteQrCode(id: number) {
|
||||
const { data } = await apiClient.delete<ApiResponse<null>>(`/admin/chats/qrcodes/${id}`)
|
||||
return data.data
|
||||
}
|
||||
|
||||
export async function batchDeleteQrCodes(ids: number[]) {
|
||||
const { data } = await apiClient.post<ApiResponse<BatchDeleteQrCodeResult>>(
|
||||
'/admin/chats/qrcodes/batch-delete',
|
||||
{ ids }
|
||||
)
|
||||
return data.data
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { Check, CopyDocument, Plus, Refresh, Search, UploadFilled } from '@element-plus/icons-vue'
|
||||
import {
|
||||
Check,
|
||||
CopyDocument,
|
||||
Delete,
|
||||
Plus,
|
||||
Refresh,
|
||||
Search,
|
||||
UploadFilled,
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
import {
|
||||
batchCreateQrCodes,
|
||||
batchDeleteQrCodes,
|
||||
deleteQrCode,
|
||||
fetchQrCodeStats,
|
||||
fetchQrCodes,
|
||||
@@ -88,6 +97,9 @@ const uploading = computed(() => uploadPendingCount.value > 0)
|
||||
const uploadBusy = computed(() => uploading.value || uploadSaving.value)
|
||||
const uploadedImageCountText = computed(() => `${uploadedImages.value.length}/${maxBatchUploadCount}`)
|
||||
const renameLoadingIds = ref(new Set<number>())
|
||||
const selectedRows = ref<ChatQrCode[]>([])
|
||||
const selectedCount = computed(() => selectedRows.value.length)
|
||||
const selectedIssuedCount = computed(() => selectedRows.value.filter(qrcodeWasIssued).length)
|
||||
|
||||
async function loadList() {
|
||||
loading.value = true
|
||||
@@ -99,6 +111,7 @@ async function loadList() {
|
||||
})
|
||||
qrcodes.value = res.items
|
||||
total.value = res.total
|
||||
selectedRows.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -121,6 +134,10 @@ function handlePageChange() {
|
||||
loadList()
|
||||
}
|
||||
|
||||
function handleSelectionChange(rows: ChatQrCode[]) {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
|
||||
function parseGroupNameFromOcrText(text: string) {
|
||||
const lines = text
|
||||
.split(/\r?\n/)
|
||||
@@ -324,6 +341,10 @@ function boundConversationLabel(row: ChatQrCode) {
|
||||
return ''
|
||||
}
|
||||
|
||||
function qrcodeWasIssued(row: ChatQrCode) {
|
||||
return row.status === 'used' || Boolean(row.conversation_id || row.used_at)
|
||||
}
|
||||
|
||||
function setRenameLoading(id: number, loading: boolean) {
|
||||
const next = new Set(renameLoadingIds.value)
|
||||
if (loading) {
|
||||
@@ -360,7 +381,11 @@ async function handleDisable(row: ChatQrCode) {
|
||||
}
|
||||
|
||||
async function handleDelete(row: ChatQrCode) {
|
||||
await ElMessageBox.confirm('确定删除该二维码?仅未使用的二维码可删除。', '删除确认', {
|
||||
const tip =
|
||||
qrcodeWasIssued(row)
|
||||
? '确定删除这条已发放二维码记录?删除后仅清理二维码池旧记录,不会影响已发送到群聊里的图片消息。'
|
||||
: '确定删除该二维码?删除后将从二维码池移除。'
|
||||
await ElMessageBox.confirm(tip, '删除确认', {
|
||||
type: 'warning',
|
||||
})
|
||||
await deleteQrCode(row.id)
|
||||
@@ -368,6 +393,25 @@ async function handleDelete(row: ChatQrCode) {
|
||||
await reloadAll()
|
||||
}
|
||||
|
||||
async function handleBatchDelete() {
|
||||
if (!selectedCount.value) {
|
||||
ElMessage.warning('请先选择要删除的二维码')
|
||||
return
|
||||
}
|
||||
|
||||
const tip = selectedIssuedCount.value
|
||||
? `确定删除选中的 ${selectedCount.value} 条二维码记录?其中 ${selectedIssuedCount.value} 条已发放,删除后仅清理二维码池旧记录,不会影响已发送到群聊里的图片消息。`
|
||||
: `确定删除选中的 ${selectedCount.value} 条二维码?删除后将从二维码池移除。`
|
||||
await ElMessageBox.confirm(tip, '批量删除确认', {
|
||||
type: 'warning',
|
||||
})
|
||||
|
||||
const result = await batchDeleteQrCodes(selectedRows.value.map(row => row.id))
|
||||
selectedRows.value = []
|
||||
ElMessage.success(`已删除 ${result.deleted} 条`)
|
||||
await reloadAll()
|
||||
}
|
||||
|
||||
onMounted(reloadAll)
|
||||
</script>
|
||||
|
||||
@@ -414,6 +458,15 @@ onMounted(reloadAll)
|
||||
<el-button :icon="Search" @click="handleFilter">筛选</el-button>
|
||||
</div>
|
||||
<div class="action-area">
|
||||
<span v-if="selectedCount" class="selection-summary">已选 {{ selectedCount }} 条</span>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
:disabled="!selectedCount"
|
||||
@click="handleBatchDelete"
|
||||
>
|
||||
批量删除
|
||||
</el-button>
|
||||
<el-button :icon="Refresh" @click="reloadAll">刷新</el-button>
|
||||
<el-button type="primary" :icon="Plus" @click="openUpload">添加二维码</el-button>
|
||||
</div>
|
||||
@@ -422,7 +475,15 @@ onMounted(reloadAll)
|
||||
|
||||
<!-- 列表 -->
|
||||
<el-card shadow="never" class="table-card">
|
||||
<el-table v-loading="loading" :data="qrcodes" class="table-panel qrcode-table" :fit="true">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="qrcodes"
|
||||
class="table-panel qrcode-table"
|
||||
:fit="true"
|
||||
row-key="id"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" class-name="selection-col" align="center" />
|
||||
<el-table-column label="二维码" class-name="qr-col" align="center">
|
||||
<template #default="{ row }">
|
||||
<div class="qrcode-thumb">
|
||||
@@ -512,7 +573,6 @@ onMounted(reloadAll)
|
||||
>停用</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="row.status === 'unused'"
|
||||
text
|
||||
type="danger"
|
||||
size="small"
|
||||
@@ -798,6 +858,10 @@ onMounted(reloadAll)
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.selection-col) {
|
||||
width: 4%;
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.qr-col) {
|
||||
width: 8%;
|
||||
}
|
||||
@@ -807,15 +871,15 @@ onMounted(reloadAll)
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.name-col) {
|
||||
width: 18%;
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.note-col) {
|
||||
width: 18%;
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.group-col) {
|
||||
width: 18%;
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
.qrcode-table :deep(.rename-col) {
|
||||
|
||||
Reference in New Issue
Block a user