<template>
<div class="admin-page-stack">
<AdminPageHeader
title="访问申请"
subtitle="处理用户对客户端应用的访问权限申请。"
icon="approval"
accent="amber"
:metrics="pageMetrics"
>
<template #actions>
<q-btn icon="refresh" round flat :loading="loading" @click="reload" />
</template>
</AdminPageHeader>
<AdminFilterPanel :loading="loading" @search="search" @reset="resetFilters">
<q-input
v-model="filters.account"
class="col-12 col-sm-6 col-md-4"
outlined
dense
clearable
label="申请用户"
:disable="loading"
@keyup.enter="search"
/>
<q-input
v-model="filters.clientId"
class="col-12 col-sm-6 col-md-4"
outlined
dense
clearable
label="客户端 ID"
:disable="loading"
@keyup.enter="search"
/>
</AdminFilterPanel>
<AdminDataTable
:rows="rows"
:columns="columns"
:pagination="pagination"
:loading="loading"
:error-message="errorMessage"
:page-count="pageCount"
:action-busy="actionBusy"
:actions-for="actionsFor"
@request="onTableRequest"
@reload="reload"
@page="setPage"
@action="runAction"
/>
<AdminDangerDialog
v-model="dialog.open"
:title="
dialog.action === 'approve-access-request'
? '通过访问申请'
: '拒绝访问申请'
"
message="填写处理备注后将更新申请状态。"
remark-mode
:busy="!!actionBusy"
:icon="
dialog.action === 'approve-access-request' ? 'check_circle' : 'cancel'
"
@confirm="confirmHandle"
/>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive } from "vue";
import type { QTableColumn } from "quasar";
import type { AuthAccessRequestItem } from "../../../models/AuthModels";
import { AdminApiService } from "../../../services/AdminApiService";
import AdminDataTable from "../components/AdminDataTable.vue";
import AdminDangerDialog from "../components/AdminDangerDialog.vue";
import AdminFilterPanel from "../components/AdminFilterPanel.vue";
import AdminPageHeader from "../components/AdminPageHeader.vue";
import { useAdminActions } from "../composables/useAdminActions";
import { usePagedQuery } from "../composables/usePagedQuery";
import type { AdminAction, AdminMetric, AdminRow } from "../types";
const api = new AdminApiService();
const query = usePagedQuery<AuthAccessRequestItem>(
(values) => api.accessRequests(values),
20,
);
const {
rows,
loading,
errorMessage,
filters,
pagination,
pageCount,
metrics,
reload,
search,
resetFilters,
onTableRequest,
} = query;
const { actionBusy, runWithState } = useAdminActions(reload);
const dialog = reactive<{
open: boolean;
action: AdminAction;
row: AuthAccessRequestItem | null;
}>({ open: false, action: "approve-access-request", row: null });
const columns: QTableColumn<AdminRow>[] = [
{ name: "primary", field: "id", label: "申请", align: "left" },
{ name: "status", field: "id", label: "状态", align: "left" },
{ name: "meta", field: "id", label: "时间", align: "left" },
{ name: "actions", field: "id", label: "操作", align: "right" },
];
const pageMetrics = computed<AdminMetric[]>(() => [
{ label: "申请总数", value: metrics.value.total, icon: "approval" },
{ label: "当前范围", value: metrics.value.range, icon: "view_timeline" },
{ label: "已加载", value: metrics.value.loaded, icon: "data_object" },
{
label: "筛选项",
value: metrics.value.activeFilters,
icon: "filter_alt",
tone: "muted",
},
]);
onMounted(() => {
void reload();
});
function actionsFor(row: AdminRow) {
const item = row as AuthAccessRequestItem;
const disabled = item.status !== 0;
return disabled
? []
: [
{
key: "approve-access-request" as const,
icon: "check_circle",
label: "通过",
color: "positive",
},
{
key: "reject-access-request" as const,
icon: "cancel",
label: "拒绝",
color: "negative",
},
];
}
function runAction(action: AdminAction, row: AdminRow) {
if (
action !== "approve-access-request" &&
action !== "reject-access-request"
) {
return;
}
dialog.action = action;
dialog.row = row as AuthAccessRequestItem;
dialog.open = true;
}
function confirmHandle(remark: string) {
if (!dialog.row) {
return;
}
const row = dialog.row;
const approved = dialog.action === "approve-access-request";
void runWithState(`${dialog.action}:${row.id}`, () =>
api.handleAccessRequest(row.id, approved ? 1 : 2, remark),
).then((success) => {
if (success) {
dialog.open = false;
dialog.row = null;
}
});
}
function setPage(page: number) {
pagination.value.page = page;
void reload();
}
</script>
AI 正在分析代码…
评论加载中...