113 lines
3.4 KiB
JavaScript
113 lines
3.4 KiB
JavaScript
/**
|
|
* 权益状态:权益中心 / 我的权益 / 领取 / 使用
|
|
*/
|
|
import { defineStore } from "pinia";
|
|
import { BENEFIT_STATUS } from "@/constant";
|
|
import * as benefitApi from "@/api/benefit";
|
|
|
|
export const useBenefitStore = defineStore("benefit", {
|
|
state: () => ({
|
|
/** 权益中心列表 */
|
|
centerList: [],
|
|
/** 我的权益列表(全部,筛选在 getter 完成) */
|
|
myList: [],
|
|
/** 页头数据行文案 */
|
|
headline: "",
|
|
/** 权益中心筛选类型 all | scenic | stay | food | specialty */
|
|
filterType: "all",
|
|
/** 我的权益子分段 all | usable | invalid */
|
|
subTab: "all",
|
|
loading: false,
|
|
/** 缓存标记:分别标记两个列表是否已从服务端拉过(onShow 重复进入不再打接口) */
|
|
centerLoaded: false,
|
|
mineLoaded: false,
|
|
}),
|
|
|
|
getters: {
|
|
/** 权益中心:按类别筛选后的列表 */
|
|
filteredCenter: (state) =>
|
|
state.filterType === "all"
|
|
? state.centerList
|
|
: state.centerList.filter((b) => b.type === state.filterType),
|
|
|
|
/** 我的权益:按状态子分段筛选后的列表 */
|
|
filteredMine: (state) => {
|
|
if (state.subTab === "usable") return state.myList.filter((b) => b.status === BENEFIT_STATUS.CLAIMED);
|
|
if (state.subTab === "invalid") return state.myList.filter((b) => b.status === BENEFIT_STATUS.EXPIRED);
|
|
return state.myList;
|
|
},
|
|
|
|
/** 我的权益数量角标(Tab3「我的权益」右栏数字) */
|
|
usableCount: (state) => state.myList.filter((b) => b.status === BENEFIT_STATUS.CLAIMED).length,
|
|
|
|
counts: (state) => ({
|
|
all: state.myList.length,
|
|
usable: state.myList.filter((b) => b.status === BENEFIT_STATUS.CLAIMED).length,
|
|
invalid: state.myList.filter((b) => b.status === BENEFIT_STATUS.EXPIRED).length,
|
|
}),
|
|
},
|
|
|
|
actions: {
|
|
async loadCenter(force = false) {
|
|
if (this.centerLoaded && !force) return this.centerList;
|
|
this.loading = true;
|
|
try {
|
|
const [list, headline] = await Promise.all([
|
|
benefitApi.getBenefitList(),
|
|
benefitApi.getBenefitHeadline(),
|
|
]);
|
|
this.centerList = list || [];
|
|
this.headline = headline || "";
|
|
this.centerLoaded = true;
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
return this.centerList;
|
|
},
|
|
|
|
async loadMine(force = false) {
|
|
if (this.mineLoaded && !force) return this.myList;
|
|
const list = await benefitApi.getMyBenefitList();
|
|
this.myList = list || [];
|
|
this.mineLoaded = true;
|
|
return this.myList;
|
|
},
|
|
|
|
async loadAll(force = false) {
|
|
await Promise.all([this.loadCenter(force), this.loadMine(force)]);
|
|
},
|
|
|
|
setFilterType(type) {
|
|
this.filterType = type;
|
|
},
|
|
|
|
setSubTab(tab) {
|
|
this.subTab = tab;
|
|
},
|
|
|
|
/** 领取权益 → 落本地,强制重拉两侧列表 */
|
|
async claim(id) {
|
|
await benefitApi.claimBenefit(id);
|
|
await Promise.all([this.loadCenter(true), this.loadMine(true)]);
|
|
},
|
|
|
|
/**
|
|
* 记录一次使用(可多次使用,不失效,无幂等约束)
|
|
*/
|
|
async use(id) {
|
|
await benefitApi.useBenefit(id);
|
|
await Promise.all([this.loadCenter(true), this.loadMine(true)]);
|
|
},
|
|
|
|
reset() {
|
|
this.centerList = [];
|
|
this.myList = [];
|
|
this.headline = "";
|
|
this.centerLoaded = false;
|
|
this.mineLoaded = false;
|
|
this.filterType = "all";
|
|
this.subTab = "all";
|
|
},
|
|
},
|
|
});
|