refactor event

This commit is contained in:
Timi
2026-08-06 20:53:22 +08:00
parent 1243068fc3
commit 9df6dfaf59
37 changed files with 1584 additions and 2316 deletions
+110 -73
View File
@@ -1,47 +1,55 @@
<template>
<div v-can="{ value: [permissionCodes.event.read, permissionCodes.user.read], mode: 'and' }" class="registration-event-list">
<t-cell-group theme="card">
<t-cell
class="item"
v-for="item in eventList"
:key="item.id"
:arrow="canUpdateEventItem"
:hover="canUpdateEventItem"
@click="handleEventClick(item)"
>
<template #title>
<div class="header">
<div class="color" :style="{ background: item.color || defaultColor }" />
<div class="title" v-text="item.name || '未命名事件'" />
<t-tag
class="status"
:theme="getStatusTag(item).theme"
variant="outline"
:content="getStatusTag(item).text"
/>
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
</div>
</template>
<template #description>
<div class="description">
<div class="line">
<span>可登记角色</span>
<t-pull-down-refresh
v-model="isRefreshing"
:refresh-timeout="30000"
@refresh="refresh"
@scrolltolower="fetch"
>
<t-cell-group theme="card">
<t-cell
class="item"
v-for="item in pageResult.list"
:key="item.id"
:arrow="canUpdateEventItem"
:hover="canUpdateEventItem"
@click="toEventItem(item)"
>
<template #title>
<div class="header">
<div class="color" :style="{ background: item.color || defaultColor }" />
<div class="title" v-text="item.name || '未命名事件'" />
<t-tag
v-for="roleCode in item.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
class="status"
:theme="getStatusTag(item).theme"
variant="outline"
:content="getStatusTag(item).text"
/>
<span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" />
<t-tag v-if="item.requirePhoto" theme="warning" variant="outline">需拍照</t-tag>
</div>
<div class="line" v-text="getLimitText(item)" />
</div>
</template>
</t-cell>
</t-cell-group>
<div v-if="!eventList.length" class="empty-block">暂无登记事件</div>
<t-button v-can="permissionCodes.event.create" class="create" theme="primary" @click="createEventItem">
</template>
<template #description>
<div class="description">
<div class="line">
<span>可登记角色</span>
<t-tag
v-for="roleCode in item.roleCodeList"
:key="roleCode"
theme="primary"
variant="light-outline"
:content="getRoleName(roleCode)"
/>
<span v-if="!(item.roleCodeList || []).length" class="muted" v-text="'未配置'" />
</div>
<div class="line" v-text="getLimitText(item)" />
</div>
</template>
</t-cell>
</t-cell-group>
<div v-if="!pageResult.list.length" class="empty-block" v-text="isLoading ? '正在加载登记事件' : '暂无登记事件'" />
<div v-if="pageResult.list.length" class="load-state" v-text="isNoMore ? '已经到底了' : '上拉加载更多'" />
</t-pull-down-refresh>
<t-button v-can="permissionCodes.event.create" class="create" theme="primary" @click="router.push('/management/registration-events/create')">
<template #icon>
<t-icon name="add" />
</template>
@@ -52,11 +60,11 @@
<script setup lang="ts">
import { Toast } from "tdesign-mobile-vue";
import { useUserStore, type Role } from "timi-web";
import { type Page, type PageResult, type Role, useUserStore } from "timi-web";
import EventAPI from "@/api/EventAPI";
import ManagedUserAPI from "@/api/ManagedUserAPI";
import { useNavBarStore } from "@/store/navBarStore";
import type { EventItem, EventStatus, EventLimitType } from "@/types/EventItem";
import type { EventItem, EventLimitType, EventStatus } from "@/types/EventItem";
import { permissionCodes } from "@/utils/permission";
defineOptions({
@@ -66,9 +74,22 @@ defineOptions({
const router = useRouter();
const navBarStore = useNavBarStore();
const userStore = useUserStore();
// ---------- 列表数据 ----------
const defaultColor = "#2f88ff";
const eventList = ref<EventItem[]>([]);
const roleOptions = ref<Role[]>([]);
const isRefreshing = ref(false);
const isLoading = ref(false);
const isNoMore = ref(false);
const page = reactive<Page<EventItem>>({
index: 0,
size: 15
});
const pageResult = reactive<PageResult<EventItem>>({
total: 0,
list: []
});
const canUpdateEventItem = computed(() => userStore.hasPermissions(permissionCodes.event.update));
type StatusTag = {
@@ -85,30 +106,18 @@ const activeStatusTag: StatusTag = { text: "可登记", theme: "primary" };
const notEffectiveStatusTag: StatusTag = { text: "未生效", theme: "default" };
const expiredStatusTag: StatusTag = { text: "已过期", theme: "danger" };
function createEventItem(): void {
router.push("/management/registration-events/create");
}
async function goSort(): Promise<void> {
await router.push("/management/registration-events/sort");
}
function editEventItem(item: EventItem): void {
if (!item.id) {
return;
}
router.push(`/management/registration-events/${item.id}/edit`);
}
function handleEventClick(item: EventItem): void {
function toEventItem(item: EventItem): void {
if (!canUpdateEventItem.value) {
return;
}
editEventItem(item);
if (!item.id) {
return;
}
router.push(`/management/registration-events/${item.id}/edit`);
}
// ---------- 展示文案 ----------
function getStatusTag(item: EventItem): StatusTag {
const status = item.status || "ACTIVE";
const fixedStatusTag = fixedStatusTagMap[status];
@@ -143,31 +152,60 @@ function getRoleName(code: string): string {
return role?.name || code;
}
// ---------- 页面数据 ----------
async function fetch(): Promise<void> {
if (isLoading.value || isNoMore.value) {
return;
}
isLoading.value = true;
try {
const result = await EventAPI.list(page);
pageResult.total = result.total;
pageResult.list = pageResult.list.concat(result.list || []);
page.index += 1;
isNoMore.value = (result.list || []).length < page.size || pageResult.total <= pageResult.list.length;
} finally {
isLoading.value = false;
}
}
async function refresh(): Promise<void> {
isRefreshing.value = true;
try {
page.index = 0;
pageResult.total = 0;
pageResult.list = [];
isNoMore.value = false;
await fetch();
} finally {
isRefreshing.value = false;
}
}
async function loadData(): Promise<void> {
const [eventResult, roles] = await Promise.all([
EventAPI.list({
index: 0,
size: 100
}),
EventAPI.list(page),
ManagedUserAPI.roleList()
]);
roleOptions.value = roles || [];
eventList.value = eventResult.list || [];
pageResult.total = eventResult.total;
pageResult.list = eventResult.list || [];
page.index = 1;
isNoMore.value = pageResult.list.length >= pageResult.total || pageResult.list.length < page.size;
}
onMounted(async () => {
navBarStore.clearRight();
if (canUpdateEventItem.value) {
navBarStore.setRightText("排序", "var(--td-brand-color)", goSort);
navBarStore.setRightText("排序", "var(--td-brand-color)", () => {
router.push("/management/registration-events/sort");
});
}
try {
await loadData();
} catch {
Toast({
theme: "error",
direction: "row",
message: "登记事件加载失败"
});
Toast.error("登记事件加载失败");
}
});
@@ -245,4 +283,3 @@ onUnmounted(() => {
}
}
</style>