135 lines
3.7 KiB
Vue
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>
|