|
|
@@ -2,7 +2,9 @@
|
|
|
<div class="page-container">
|
|
|
<div class="page-header">
|
|
|
<PageTitle title="我的收藏" />
|
|
|
- <el-button type="danger" link @click="handleAddCategory"><el-icon><Plus /></el-icon>添加分类</el-button>
|
|
|
+ <el-button type="danger" link @click="handleAddCategory"
|
|
|
+ ><el-icon><Plus /></el-icon>添加分类</el-button
|
|
|
+ >
|
|
|
</div>
|
|
|
<!-- 分类Tab -->
|
|
|
<StatusTabs v-model="activeCategory" :tabs="categoryTabs" type="pill" />
|
|
|
@@ -28,7 +30,13 @@
|
|
|
/>
|
|
|
</div>
|
|
|
<el-empty v-if="productList.length === 0" description="暂无收藏商品" />
|
|
|
- <TablePagination v-if="productList.length > 0" v-model:page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :total="total" @change="handleQuery" />
|
|
|
+ <TablePagination
|
|
|
+ v-if="productList.length > 0"
|
|
|
+ v-model:page="queryParams.pageNum"
|
|
|
+ v-model:page-size="queryParams.pageSize"
|
|
|
+ :total="total"
|
|
|
+ @change="handleQuery"
|
|
|
+ />
|
|
|
<!-- 添加分类弹窗 -->
|
|
|
<el-dialog v-model="categoryDialogVisible" title="添加分类" width="400px">
|
|
|
<el-form ref="categoryFormRef" :model="categoryForm" :rules="categoryRules">
|
|
|
@@ -43,49 +51,188 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive, watch } from 'vue'
|
|
|
-import { Plus } from '@element-plus/icons-vue'
|
|
|
-import { ElMessage, ElMessageBox, type CheckboxValueType } from 'element-plus'
|
|
|
-import { PageTitle, StatusTabs, ProductCard, TablePagination } from '@/components'
|
|
|
+import { ref, reactive, watch, onMounted } from 'vue';
|
|
|
+import { Plus } from '@element-plus/icons-vue';
|
|
|
+import { ElMessage, ElMessageBox, type CheckboxValueType } from 'element-plus';
|
|
|
+import { PageTitle, StatusTabs, ProductCard, TablePagination } from '@/components';
|
|
|
+import { favoritesList, favoritesProductList, cancelProductCollect, addProductShoppingCart } from '@/api/goods/index';
|
|
|
|
|
|
-const activeCategory = ref('all')
|
|
|
-const selectAll = ref(false)
|
|
|
-const categoryDialogVisible = ref(false)
|
|
|
-const categoryFormRef = ref()
|
|
|
+const activeCategory = ref('all');
|
|
|
+const selectAll = ref(false);
|
|
|
+const categoryDialogVisible = ref(false);
|
|
|
+const categoryFormRef = ref();
|
|
|
+const loading = ref(false);
|
|
|
|
|
|
-const categoryTabs = ref([
|
|
|
- { key: 'all', label: '全部' }, { key: 'computer', label: '电脑办公(2)' }, { key: 'industrial', label: '工业品(2)' },
|
|
|
- { key: 'decoration', label: '家装建材(2)' }, { key: 'appliance', label: '家用电器(2)' }, { key: 'digital', label: '数码(2)' }
|
|
|
-])
|
|
|
-const categoryForm = reactive({ name: '' })
|
|
|
-const categoryRules = { name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }] }
|
|
|
-const queryParams = reactive({ pageNum: 1, pageSize: 15 })
|
|
|
-const total = ref(100)
|
|
|
+const categoryTabs = ref<any[]>([{ key: 'all', label: '全部' }]);
|
|
|
+const categoryForm = reactive({ name: '' });
|
|
|
+const categoryRules = { name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }] };
|
|
|
+const queryParams = reactive({ pageNum: 1, pageSize: 15, favoritesId: '' as any });
|
|
|
+const total = ref(0);
|
|
|
+const productList = ref<any[]>([]);
|
|
|
|
|
|
-const productList = ref([
|
|
|
- { id: 1, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '协议价', image: '', checked: false },
|
|
|
- { id: 2, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 3, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 4, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 5, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 6, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 7, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false },
|
|
|
- { id: 8, name: '格力KFR-72LW/定频冷暖空调柜机3P', price: '1,299', originalPrice: '1,899', tag: '', image: '', checked: false }
|
|
|
-])
|
|
|
+/** 获取收藏夹列表(分类Tab) */
|
|
|
+const getFavoritesTabs = () => {
|
|
|
+ favoritesList({}).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ const tabs = [{ key: 'all', label: '全部' }];
|
|
|
+ if (res.rows && res.rows.length > 0) {
|
|
|
+ res.rows.forEach((item: any) => {
|
|
|
+ tabs.push({ key: String(item.id), label: item.title || '未命名' });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ categoryTabs.value = tabs;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
|
|
|
-watch(activeCategory, () => { queryParams.pageNum = 1; handleQuery() })
|
|
|
-const handleQuery = () => {}
|
|
|
-const handleSelectAll = (val: CheckboxValueType) => { productList.value.forEach(item => { item.checked = !!val }) }
|
|
|
-const handleAddCategory = () => { categoryForm.name = ''; categoryDialogVisible.value = true }
|
|
|
-const handleSaveCategory = async () => { const valid = await categoryFormRef.value?.validate(); if (!valid) return; categoryTabs.value.push({ key: categoryForm.name, label: `${categoryForm.name}(0)` }); ElMessage.success('添加成功'); categoryDialogVisible.value = false }
|
|
|
-const handleAddCart = (_item: any) => { ElMessage.success('已加入购物车') }
|
|
|
-const handleBatchAddCart = () => { const selected = productList.value.filter(item => item.checked); if (selected.length === 0) { ElMessage.warning('请先选择商品'); return }; ElMessage.success(`已将${selected.length}件商品加入购物车`) }
|
|
|
-const handleCancelCollection = (item: any) => { ElMessageBox.confirm('确定要取消收藏该商品吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { const index = productList.value.findIndex(i => i.id === item.id); if (index > -1) productList.value.splice(index, 1); ElMessage.success('已取消收藏') }) }
|
|
|
-const handleBatchCancel = () => { const selected = productList.value.filter(item => item.checked); if (selected.length === 0) { ElMessage.warning('请先选择商品'); return }; ElMessageBox.confirm(`确定要取消收藏选中的${selected.length}件商品吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { productList.value = productList.value.filter(item => !item.checked); selectAll.value = false; ElMessage.success('已取消收藏') }) }
|
|
|
+/** 获取收藏商品列表 */
|
|
|
+const getProductList = () => {
|
|
|
+ loading.value = true;
|
|
|
+ const params: any = { pageNum: queryParams.pageNum, pageSize: queryParams.pageSize };
|
|
|
+ if (activeCategory.value !== 'all') {
|
|
|
+ params.favoritesId = activeCategory.value;
|
|
|
+ }
|
|
|
+ favoritesProductList(params)
|
|
|
+ .then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ productList.value = (res.rows || []).map((item: any) => ({
|
|
|
+ ...item,
|
|
|
+ name: item.itemName || item.productName || item.name || '',
|
|
|
+ image: item.productImage || item.image || '',
|
|
|
+ price: item.price || item.memberPrice || item.minSellingPrice || '',
|
|
|
+ originalPrice: item.marketPrice || item.originalPrice || '',
|
|
|
+ tag: item.tag || '',
|
|
|
+ checked: false
|
|
|
+ }));
|
|
|
+ total.value = res.total || 0;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ loading.value = false;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleQuery = () => {
|
|
|
+ selectAll.value = false;
|
|
|
+ getProductList();
|
|
|
+};
|
|
|
+
|
|
|
+watch(activeCategory, () => {
|
|
|
+ queryParams.pageNum = 1;
|
|
|
+ handleQuery();
|
|
|
+});
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getFavoritesTabs();
|
|
|
+ getProductList();
|
|
|
+});
|
|
|
+
|
|
|
+const handleSelectAll = (val: CheckboxValueType) => {
|
|
|
+ productList.value.forEach((item) => {
|
|
|
+ item.checked = !!val;
|
|
|
+ });
|
|
|
+};
|
|
|
+const handleAddCategory = () => {
|
|
|
+ categoryForm.name = '';
|
|
|
+ categoryDialogVisible.value = true;
|
|
|
+};
|
|
|
+const handleSaveCategory = async () => {
|
|
|
+ const valid = await categoryFormRef.value?.validate();
|
|
|
+ if (!valid) return;
|
|
|
+ // TODO: 调用后端新增收藏夹接口
|
|
|
+ categoryTabs.value.push({ key: categoryForm.name, label: categoryForm.name });
|
|
|
+ ElMessage.success('添加成功');
|
|
|
+ categoryDialogVisible.value = false;
|
|
|
+ getFavoritesTabs();
|
|
|
+};
|
|
|
+
|
|
|
+/** 单个加入购物车 */
|
|
|
+const handleAddCart = (item: any) => {
|
|
|
+ addProductShoppingCart({ productId: item.id, productNum: 1 }).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ ElMessage.success('已加入购物车');
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** 批量加入购物车 */
|
|
|
+const handleBatchAddCart = () => {
|
|
|
+ const selected = productList.value.filter((item) => item.checked);
|
|
|
+ if (selected.length === 0) {
|
|
|
+ ElMessage.warning('请先选择商品');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const promises = selected.map((item) => addProductShoppingCart({ productId: item.id, productNum: 1 }));
|
|
|
+ Promise.all(promises).then(() => {
|
|
|
+ ElMessage.success(`已将${selected.length}件商品加入购物车`);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** 单个取消收藏 */
|
|
|
+const handleCancelCollection = (item: any) => {
|
|
|
+ ElMessageBox.confirm('确定要取消收藏该商品吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
|
|
+ const params: any = { productId: item.id || item.productId };
|
|
|
+ if (activeCategory.value !== 'all') {
|
|
|
+ params.favoritesId = activeCategory.value;
|
|
|
+ }
|
|
|
+ cancelProductCollect(params).then((res: any) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ ElMessage.success('已取消收藏');
|
|
|
+ getProductList();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** 批量取消收藏 */
|
|
|
+const handleBatchCancel = () => {
|
|
|
+ const selected = productList.value.filter((item) => item.checked);
|
|
|
+ if (selected.length === 0) {
|
|
|
+ ElMessage.warning('请先选择商品');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ElMessageBox.confirm(`确定要取消收藏选中的${selected.length}件商品吗?`, '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ const promises = selected.map((item) => {
|
|
|
+ const params: any = { productId: item.id || item.productId };
|
|
|
+ if (activeCategory.value !== 'all') {
|
|
|
+ params.favoritesId = activeCategory.value;
|
|
|
+ }
|
|
|
+ return cancelProductCollect(params);
|
|
|
+ });
|
|
|
+ Promise.all(promises).then(() => {
|
|
|
+ selectAll.value = false;
|
|
|
+ ElMessage.success('已取消收藏');
|
|
|
+ getProductList();
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; :deep(.page-title) { margin-bottom: 0; } }
|
|
|
-.action-bar { display: flex; align-items: center; gap: 20px; padding: 10px 0; border-bottom: 1px solid #eee; margin-bottom: 15px; }
|
|
|
-.product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; }
|
|
|
+.page-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ :deep(.page-title) {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+.action-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px;
|
|
|
+ padding: 10px 0;
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ margin-bottom: 15px;
|
|
|
+}
|
|
|
+.product-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(4, 1fr);
|
|
|
+ gap: 15px;
|
|
|
+}
|
|
|
</style>
|