shop-wx/doc/examples/store-example.ts

434 lines
9.3 KiB
TypeScript
Raw Normal View History

/**
* Pinia Store
*
*/
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { getUserList, createUser, updateUser, deleteUser, type User, type UserParams } from '@/api/user';
/**
* Store
* 使 Composition API Store
*/
export const useUserStore = defineStore('user', () => {
/**
* 使 ref
*/
// 用户列表
const userList = ref<User[]>([]);
// 当前用户
const currentUser = ref<User | null>(null);
// 加载状态
const loading = ref(false);
// 搜索关键词
const searchKeyword = ref('');
// 分页信息
const pagination = ref({
current: 1,
size: 10,
total: 0,
});
// 选中的用户ID列表
const selectedUserIds = ref<number[]>([]);
// 错误信息
const error = ref<string | null>(null);
/**
*
*/
// 是否全选
const isAllSelected = computed(() => {
return userList.value.length > 0 && selectedUserIds.value.length === userList.value.length;
});
// 是否部分选中
const isIndeterminate = computed(() => {
return selectedUserIds.value.length > 0 && selectedUserIds.value.length < userList.value.length;
});
// 选中的用户列表
const selectedUsers = computed(() => {
return userList.value.filter(user => selectedUserIds.value.includes(user.id));
});
// 正常状态用户数
const activeUserCount = computed(() => {
return userList.value.filter(user => user.status === 0).length;
});
// 禁用状态用户数
const inactiveUserCount = computed(() => {
return userList.value.filter(user => user.status === 1).length;
});
/**
* Actions
*/
// ✅ 获取用户列表
/**
*
* @param params
*/
const fetchUserList = async (params?: UserParams) => {
loading.value = true;
error.value = null;
try {
const result = await getUserList(params);
userList.value = result.data;
pagination.value = {
current: result.page,
size: result.size,
total: result.total,
};
// 清空选中状态
selectedUserIds.value = [];
return result;
} catch (err: any) {
error.value = err.message || '获取用户列表失败';
console.error('获取用户列表失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 创建用户
/**
*
* @param data
*/
const createNewUser = async (data: any) => {
loading.value = true;
error.value = null;
try {
const newUser = await createUser(data);
// 添加到列表开头
userList.value.unshift(newUser);
return newUser;
} catch (err: any) {
error.value = err.message || '创建用户失败';
console.error('创建用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 更新用户
/**
*
* @param data
*/
const updateUserInfo = async (data: any) => {
loading.value = true;
error.value = null;
try {
const updatedUser = await updateUser(data);
// 更新列表中的用户
const index = userList.value.findIndex(user => user.id === data.id);
if (index !== -1) {
userList.value[index] = updatedUser;
}
return updatedUser;
} catch (err: any) {
error.value = err.message || '更新用户失败';
console.error('更新用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 删除用户
/**
*
* @param id ID
*/
const removeUser = async (id: number) => {
loading.value = true;
error.value = null;
try {
await deleteUser(id);
// 从列表中移除
userList.value = userList.value.filter(user => user.id !== id);
// 移除选中状态
selectedUserIds.value = selectedUserIds.value.filter(userId => userId !== id);
} catch (err: any) {
error.value = err.message || '删除用户失败';
console.error('删除用户失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 批量删除用户
/**
*
* @param ids ID列表
*/
const batchRemoveUsers = async (ids: number[]) => {
loading.value = true;
error.value = null;
try {
// 这里应该调用批量删除 API
// await batchDeleteUsers(ids);
// 模拟批量删除
for (const id of ids) {
await deleteUser(id);
}
// 从列表中移除
userList.value = userList.value.filter(user => !ids.includes(user.id));
// 清空选中状态
selectedUserIds.value = [];
} catch (err: any) {
error.value = err.message || '批量删除失败';
console.error('批量删除失败:', err);
throw err;
} finally {
loading.value = false;
}
};
// ✅ 切换用户状态
/**
*
* @param id ID
*/
const toggleUserStatus = async (id: number) => {
const user = userList.value.find(u => u.id === id);
if (!user) return;
const newStatus = user.status === 0 ? 1 : 0;
try {
await updateUser({ id, status: newStatus });
// 更新本地状态
user.status = newStatus;
} catch (err: any) {
error.value = err.message || '状态切换失败';
console.error('状态切换失败:', err);
throw err;
}
};
// ✅ 刷新用户列表
/**
* 使
*/
const refreshUserList = () => {
return fetchUserList({
keyword: searchKeyword.value,
page: pagination.value.current,
size: pagination.value.size,
});
};
/**
* Actions
*/
// ✅ 设置当前用户
/**
*
* @param user
*/
const setCurrentUser = (user: User | null) => {
currentUser.value = user;
};
// ✅ 设置搜索关键词
/**
*
* @param keyword
*/
const setSearchKeyword = (keyword: string) => {
searchKeyword.value = keyword;
};
// ✅ 设置分页
/**
*
* @param page
* @param size
*/
const setPagination = (page: number, size?: number) => {
pagination.value.current = page;
if (size) {
pagination.value.size = size;
}
};
// ✅ 全选/取消全选
/**
*
*/
const toggleSelectAll = () => {
if (isAllSelected.value) {
selectedUserIds.value = [];
} else {
selectedUserIds.value = userList.value.map(user => user.id);
}
};
// ✅ 选择/取消选择用户
/**
*
* @param userId ID
*/
const toggleUserSelection = (userId: number) => {
const index = selectedUserIds.value.indexOf(userId);
if (index === -1) {
selectedUserIds.value.push(userId);
} else {
selectedUserIds.value.splice(index, 1);
}
};
// ✅ 清空选中状态
/**
*
*/
const clearSelection = () => {
selectedUserIds.value = [];
};
// ✅ 清空错误信息
/**
*
*/
const clearError = () => {
error.value = null;
};
// ✅ 重置状态
/**
* Store
*/
const resetState = () => {
userList.value = [];
currentUser.value = null;
selectedUserIds.value = [];
searchKeyword.value = '';
pagination.value = {
current: 1,
size: 10,
total: 0,
};
error.value = null;
loading.value = false;
};
/**
*
*/
return {
// 状态
userList,
currentUser,
loading,
searchKeyword,
pagination,
selectedUserIds,
error,
// 计算属性
isAllSelected,
isIndeterminate,
selectedUsers,
activeUserCount,
inactiveUserCount,
// 异步操作
fetchUserList,
createNewUser,
updateUserInfo,
removeUser,
batchRemoveUsers,
toggleUserStatus,
refreshUserList,
// 同步操作
setCurrentUser,
setSearchKeyword,
setPagination,
toggleSelectAll,
toggleUserSelection,
clearSelection,
clearError,
resetState,
};
});
/**
* Store
*/
// ✅ 主题管理 Store
export const useThemeStore = defineStore('theme', () => {
const theme = ref<'light' | 'dark'>('light');
const primaryColor = ref('#4a90ff');
const setTheme = (newTheme: 'light' | 'dark') => {
theme.value = newTheme;
};
const setPrimaryColor = (color: string) => {
primaryColor.value = color;
};
return {
theme,
primaryColor,
setTheme,
setPrimaryColor,
};
});
// ✅ 购物车 Store参考现有项目
export const useCartStore = defineStore('cart', () => {
const items = ref<any[]>([]);
const total = ref(0);
const addItem = (product: any) => {
// 添加商品到购物车逻辑
items.value.push(product);
calculateTotal();
};
const removeItem = (productId: string) => {
items.value = items.value.filter(item => item.id !== productId);
calculateTotal();
};
const calculateTotal = () => {
total.value = items.value.reduce((sum, item) => sum + item.price, 0);
};
return {
items,
total,
addItem,
removeItem,
};
});