131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
import { create } from "zustand";
|
|
import { loadDataApi, saveDataApi, getUniqueIdApi } from "@/request/api";
|
|
import { useUserStore } from "./user";
|
|
|
|
interface FavoriteState {
|
|
/** 当前家庭已收藏的 app_id 集合 */
|
|
favorites: Set<string>;
|
|
/** 是否已加载 */
|
|
loaded: boolean;
|
|
/** 操作中的 app_id */
|
|
loadingIds: Set<string>;
|
|
|
|
/** 拉取收藏列表 */
|
|
fetchFavorites: (familyId: number) => Promise<void>;
|
|
/** 切换收藏状态 */
|
|
toggleFavorite: (familyId: number, appId: string) => Promise<boolean>;
|
|
/** 是否已收藏 */
|
|
isFavorite: (appId: string) => boolean;
|
|
/** 清空 */
|
|
clear: () => void;
|
|
}
|
|
|
|
export const useFavoriteStore = create<FavoriteState>()((set, get) => ({
|
|
favorites: new Set(),
|
|
loaded: false,
|
|
loadingIds: new Set(),
|
|
|
|
fetchFavorites: async (familyId: number) => {
|
|
if (familyId === 0) return;
|
|
const res = await loadDataApi({
|
|
view_name: "b_app_favorite",
|
|
search_condition: "family_id = ?",
|
|
order_by: "id ASC",
|
|
search_columns: [],
|
|
args: [familyId],
|
|
});
|
|
if (res.isSuccess) {
|
|
const ids = new Set(res.data.map((item: any) => item.app_id));
|
|
set({ favorites: ids, loaded: true });
|
|
}
|
|
},
|
|
|
|
toggleFavorite: async (familyId: number, appId: string) => {
|
|
const { loadingIds, favorites } = get();
|
|
if (loadingIds.has(appId)) return favorites.has(appId);
|
|
|
|
const newLoading = new Set(loadingIds);
|
|
newLoading.add(appId);
|
|
set({ loadingIds: newLoading });
|
|
|
|
const isFav = get().favorites.has(appId);
|
|
|
|
if (isFav) {
|
|
// 已收藏 → 查 id → 删
|
|
const checkRes = await loadDataApi({
|
|
view_name: "b_app_favorite",
|
|
search_condition: "family_id = ? AND app_id = ?",
|
|
order_by: "",
|
|
search_columns: [],
|
|
args: [familyId, appId],
|
|
});
|
|
|
|
const nextLoading = new Set(get().loadingIds);
|
|
nextLoading.delete(appId);
|
|
set({ loadingIds: nextLoading });
|
|
|
|
if (checkRes.isSuccess && checkRes.data.length > 0) {
|
|
const row = checkRes.data[0];
|
|
const delRes = await saveDataApi([
|
|
{
|
|
table_name: "b_app_favorite",
|
|
key_field: "id",
|
|
inserts: [],
|
|
updates: [],
|
|
deletes: [{ id: row.id }],
|
|
},
|
|
]);
|
|
|
|
if (delRes.isSuccess) {
|
|
const newFavorites = new Set(get().favorites);
|
|
newFavorites.delete(appId);
|
|
set({ favorites: newFavorites });
|
|
return false;
|
|
}
|
|
}
|
|
return true; // 失败时保持原状态
|
|
} else {
|
|
// 未收藏 → 取 id → 插入
|
|
const userId = useUserStore.getState().userInfo.id;
|
|
|
|
const idRes = await getUniqueIdApi(1);
|
|
|
|
const nextLoading = new Set(get().loadingIds);
|
|
nextLoading.delete(appId);
|
|
set({ loadingIds: nextLoading });
|
|
|
|
if (idRes.isSuccess && idRes.data.length > 0) {
|
|
const newId = idRes.data[0];
|
|
const saveRes = await saveDataApi([
|
|
{
|
|
table_name: "b_app_favorite",
|
|
key_field: "id",
|
|
inserts: [
|
|
{
|
|
id: newId,
|
|
family_id: familyId,
|
|
user_id: userId,
|
|
app_id: appId,
|
|
},
|
|
],
|
|
updates: [],
|
|
deletes: [],
|
|
},
|
|
]);
|
|
|
|
if (saveRes.isSuccess) {
|
|
const newFavorites = new Set(get().favorites);
|
|
newFavorites.add(appId);
|
|
set({ favorites: newFavorites });
|
|
return true;
|
|
}
|
|
}
|
|
return false; // 失败时保持原状态
|
|
}
|
|
},
|
|
|
|
isFavorite: (appId: string) => get().favorites.has(appId),
|
|
|
|
clear: () => set({ favorites: new Set(), loaded: false, loadingIds: new Set() }),
|
|
}));
|