Files
gao-customer-h5/src/pages/point/PointRedeemSkuList.vue
T
2026-09-15 10:44:29 +08:00

135 lines
3.7 KiB
Vue

<template>
<div v-can="permissionCodes.pointRedeemSku.manage" class="redeem-sku-list">
<t-pull-down-refresh v-model="isRefreshing" :refresh-timeout="30000" @refresh="reload" @scrolltolower="load">
<t-cell-group v-if="result.list.length" theme="card">
<t-cell
v-for="(item, index) in result.list"
:key="item.id"
arrow
v-entrance-transition="index * 30"
@click="toEdit(item)"
>
<template #title>
<div class="title">
<strong v-text="item.product?.name || item.sku?.name || '未命名产品'" />
<t-tag
size="small"
:theme="item.status === 'ACTIVE' ? 'success' : 'default'"
:content="statusText(item.status)"
/>
</div>
</template>
<template #description>
<span
v-text="`${item.sku?.code || item.sku?.specSummary || '默认 SKU'} · ${item.unit?.name || '单位未知'} · ${formatPoint(item.defaultPointCost)} / 单位`"
/>
</template>
</t-cell>
</t-cell-group>
<t-empty v-else :description="isLoading ? '正在加载兑换配置' : '暂无兑换配置'" />
<div class="tips" v-text="isNoMore ? `共 ${result.total} 条配置` : '上拉加载更多'" />
</t-pull-down-refresh>
</div>
<nav-bar-action-menu
v-can="permissionCodes.pointRedeemSku.manage"
:actions="[{ key: 'create', icon: 'add', text: '新增兑换配置', theme: 'primary', action: toCreate }]"
/>
</template>
<script setup lang="ts">
import PointAPI from "@/api/PointAPI";
import { useNavBarStore } from "@/store/navBarStore";
import type { PointRedeemSku, PointRedeemSkuStatus } from "@/types/Point";
import { Message } from "@/utils/message";
import { permissionCodes } from "@/utils/permission";
defineOptions({ name: "PointRedeemSkuList" });
const router = useRouter();
const navBarStore = useNavBarStore();
const result = reactive({ total: 0, list: [] as PointRedeemSku[] });
const index = ref(0);
const isLoading = ref(false);
const isRefreshing = ref(false);
const isNoMore = ref(false);
async function reload(): Promise<void> {
index.value = 0;
result.total = 0;
result.list = [];
isNoMore.value = false;
try {
await load();
} finally {
isRefreshing.value = false;
}
}
async function load(): Promise<void> {
if (isLoading.value || isNoMore.value) {
return;
}
isLoading.value = true;
try {
const page = await PointAPI.redeemSkuList({ index: index.value, size: 20 });
const list = page.list || [];
result.list = result.list.concat(list);
result.total = page.total || 0;
index.value++;
isNoMore.value = result.total <= result.list.length || list.length < 20;
} catch {
Message.error("兑换配置加载失败");
} finally {
isLoading.value = false;
}
}
function formatPoint(value?: number): string {
return `${(value || 0).toLocaleString("zh-CN")} 分`;
}
function statusText(status?: PointRedeemSkuStatus): string {
return ({
DRAFT: "草稿",
ACTIVE: "启用",
INACTIVE: "停用",
DELETED: "已删除"
} as Record<string, string>)[status || ""] || "未知";
}
async function toCreate(): Promise<void> {
await router.push({ name: "PointRedeemSkuCreate" });
}
async function toEdit(item: PointRedeemSku): Promise<void> {
if (item.id) {
await router.push({ name: "PointRedeemSkuEdit", params: { id: item.id } });
}
}
onMounted(async () => {
navBarStore.setCustomRightVisible(true);
await reload();
});
onUnmounted(() => navBarStore.clearRight());
</script>
<style scoped lang="less">
.redeem-sku-list {
padding: calc(var(--app-nav-height) + 1rem) 0 5rem;
.title {
gap: .5rem;
display: flex;
align-items: center;
justify-content: space-between;
}
.tips {
color: var(--td-text-color-secondary);
padding: 1rem;
text-align: center;
}
}
</style>