Skip to content

Commit 9a3253a

Browse files
author
dongshanshan
committed
feat: 会员商品收藏
1 parent 5d760d5 commit 9a3253a

File tree

6 files changed

+253
-3
lines changed

6 files changed

+253
-3
lines changed

src/api/mall/product/favorite.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import request from '@/config/axios'
2+
3+
export interface Favorite {
4+
id?: number
5+
userId?: string // 用户编号
6+
spuId?: number | null // 商品 SPU 编号
7+
}
8+
9+
// 获得 ProductFavorite 列表
10+
export const getFavoritePage = (params: PageParam) => {
11+
params.keyword = params.name
12+
return request.get({ url: '/product/favorite/page', params })
13+
}
14+
15+
// 收藏商品 Favorite
16+
export const createFavorite = (data: Favorite) => {
17+
return request.post({ url: '/product/favorite/create', data })
18+
}
19+
20+
// 取消商品收藏 Favorite
21+
export const delFavorite = (data: Favorite) => {
22+
return request.delete({ url: '/product/favorite/delete', data })
23+
}
24+
25+
// 是否收藏过商品 Favorite
26+
export const exitsFavorite = (data: Favorite) => {
27+
return request.post({ url: '/product/favorite/exits', data })
28+
}

src/hooks/web/useMessage.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ export const useMessage = () => {
9090
cancelButtonText: t('common.cancel'),
9191
type: 'warning'
9292
})
93+
},
94+
// 取消收藏窗体
95+
delStarConfirm(content?: string, tip?: string) {
96+
return ElMessageBox.confirm(
97+
content ? content : t('common.confirmDelStar'),
98+
tip ? tip : t('common.confirmTitle'),
99+
{
100+
confirmButtonText: t('common.ok'),
101+
cancelButtonText: t('common.cancel'),
102+
type: 'warning'
103+
}
104+
)
93105
}
94106
}
95107
}

src/locales/en.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ export default {
5454
updateTime: 'Update Time',
5555
copy: 'Copy',
5656
copySuccess: 'Copy Success',
57-
copyError: 'Copy Error'
57+
copyError: 'Copy Error',
58+
confirmDelStar: 'Delete the Star?',
59+
starSuccess: 'Star Success',
60+
starFail: 'Star Error',
61+
delStarSuccess: 'Del Star Success',
62+
delStarFail: 'Del Star Error',
63+
existStar: 'exist Star'
5864
},
5965
error: {
6066
noPermission: `Sorry, you don't have permission to access this page.`,

src/locales/zh-CN.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ export default {
5454
updateTime: '更新时间',
5555
copy: '复制',
5656
copySuccess: '复制成功',
57-
copyError: '复制失败'
57+
copyError: '复制失败',
58+
confirmDelStar: '是否取消收藏?',
59+
starSuccess: '收藏成功',
60+
starFail: '收藏失败',
61+
delStarSuccess: '取消收藏成功',
62+
delStarFail: '取消收藏失败',
63+
existStar: '收藏已存在'
5864
},
5965
error: {
6066
noPermission: `抱歉,您无权访问此页面。`,
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<template>
2+
<ContentWrap>
3+
<!-- 搜索工作栏 -->
4+
<el-form
5+
class="-mb-15px"
6+
:model="queryParams"
7+
ref="queryFormRef"
8+
:inline="true"
9+
label-width="68px"
10+
>
11+
<el-form-item label="商品名称" prop="name">
12+
<el-input
13+
v-model="queryParams.name"
14+
placeholder="请输入商品名称"
15+
clearable
16+
@keyup.enter="handleQuery"
17+
class="!w-240px"
18+
/>
19+
</el-form-item>
20+
<el-form-item label="收藏时间" prop="createTime">
21+
<el-date-picker
22+
v-model="queryParams.createTime"
23+
value-format="YYYY-MM-DD HH:mm:ss"
24+
type="daterange"
25+
start-placeholder="开始日期"
26+
end-placeholder="结束日期"
27+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
28+
class="!w-240px"
29+
/>
30+
</el-form-item>
31+
<el-form-item>
32+
<el-button @click="handleQuery">
33+
<Icon icon="ep:search" class="mr-5px" />
34+
搜索
35+
</el-button>
36+
<el-button @click="resetQuery">
37+
<Icon icon="ep:refresh" class="mr-5px" />
38+
重置
39+
</el-button>
40+
</el-form-item>
41+
</el-form>
42+
</ContentWrap>
43+
44+
<!-- 列表 -->
45+
<ContentWrap>
46+
<el-table v-loading="loading" :data="list">
47+
<el-table-column key="id" align="center" label="商品编号" width="180" prop="id" />
48+
<el-table-column label="商品图" min-width="80">
49+
<template #default="{ row }">
50+
<el-image :src="row.picUrl" class="h-30px w-30px" @click="imagePreview(row.picUrl)" />
51+
</template>
52+
</el-table-column>
53+
<el-table-column :show-overflow-tooltip="true" label="商品名称" min-width="300" prop="name" />
54+
<el-table-column align="center" label="商品售价" min-width="90" prop="price">
55+
<template #default="{ row }"> {{ floatToFixed2(row.price) }}元</template>
56+
</el-table-column>
57+
<el-table-column align="center" label="销量" min-width="90" prop="salesCount" />
58+
<el-table-column
59+
:formatter="dateFormatter"
60+
align="center"
61+
label="收藏时间"
62+
prop="createTime"
63+
width="180"
64+
/>
65+
<el-table-column align="center" label="状态" min-width="80">
66+
<template #default="scope">
67+
<dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.status" />
68+
</template>
69+
</el-table-column>
70+
<el-table-column align="center" fixed="right" label="操作" min-width="200">
71+
<template #default="{ row }">
72+
<el-button
73+
v-if="row.favoriteStatus === 0"
74+
v-hasPermi="['product:spu:delete']"
75+
link
76+
type="danger"
77+
@click="handleAdd(row)"
78+
>
79+
收藏
80+
</el-button>
81+
<el-button
82+
v-if="row.favoriteStatus === 1"
83+
v-hasPermi="['product:spu:delete']"
84+
link
85+
type="danger"
86+
@click="handleDelete(row)"
87+
>
88+
取消收藏
89+
</el-button>
90+
</template>
91+
</el-table-column>
92+
</el-table>
93+
<!-- 分页 -->
94+
<Pagination
95+
:total="total"
96+
v-model:page="queryParams.pageNo"
97+
v-model:limit="queryParams.pageSize"
98+
@pagination="getList"
99+
/>
100+
</ContentWrap>
101+
</template>
102+
103+
<script lang="ts" setup>
104+
import { DICT_TYPE } from '@/utils/dict'
105+
import { dateFormatter } from '@/utils/formatTime'
106+
import * as FavoriteApi from '@/api/mall/product/favorite'
107+
import { floatToFixed2 } from '@/utils'
108+
109+
const message = useMessage() // 消息弹窗
110+
const { t } = useI18n() // 国际化
111+
112+
const loading = ref(true) // 列表的加载中
113+
const total = ref(0) // 列表的总页数
114+
const list = ref([]) // 列表的数据
115+
const queryParams = reactive({
116+
pageNo: 1,
117+
pageSize: 10,
118+
name: null,
119+
createTime: [],
120+
userId: NaN
121+
})
122+
const queryFormRef = ref() // 搜索的表单
123+
124+
/** 查询列表 */
125+
const getList = async () => {
126+
loading.value = true
127+
try {
128+
const data = await FavoriteApi.getFavoritePage(queryParams)
129+
list.value = data.list
130+
total.value = data.total
131+
} finally {
132+
loading.value = false
133+
}
134+
}
135+
136+
/** 搜索按钮操作 */
137+
const handleQuery = () => {
138+
queryParams.pageNo = 1
139+
getList()
140+
}
141+
142+
/** 重置按钮操作 */
143+
const resetQuery = () => {
144+
queryFormRef.value.resetFields()
145+
handleQuery()
146+
}
147+
148+
/** 取消收藏按钮操作 */
149+
const handleDelete = async (row: object) => {
150+
try {
151+
console.log(row)
152+
// 取消的二次确认
153+
await message.delStarConfirm()
154+
// 发起取消
155+
await FavoriteApi.delFavorite({ userId: queryParams.userId, spuId: row.spuId })
156+
message.success(t('common.delStarSuccess'))
157+
row.favoriteStatus = 0
158+
// 刷新列表
159+
// await getList()
160+
} catch {}
161+
}
162+
163+
/** 收藏按钮操作 */
164+
const handleAdd = async (row: object) => {
165+
try {
166+
const data = { userId: queryParams.userId, spuId: row.spuId }
167+
// 发起收藏
168+
const result = await FavoriteApi.exitsFavorite(data)
169+
if (result === false) {
170+
// 发起收藏
171+
await FavoriteApi.createFavorite(data)
172+
message.success(t('common.starSuccess'))
173+
row.favoriteStatus = 1
174+
// 刷新列表
175+
// await getList()
176+
} else {
177+
message.warning(t('common.existStar'))
178+
row.favoriteStatus = 1
179+
}
180+
} catch {}
181+
}
182+
183+
const { userId } = defineProps({
184+
userId: {
185+
type: Number,
186+
required: true
187+
}
188+
})
189+
190+
/** 初始化 **/
191+
onMounted(() => {
192+
queryParams.userId = userId
193+
getList()
194+
})
195+
</script>

src/views/member/user/detail/index.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@
4848
<UserOrderList :user-id="id" />
4949
</el-tab-pane>
5050
<el-tab-pane label="售后管理" lazy>售后管理(WIP)</el-tab-pane>
51-
<el-tab-pane label="收藏记录" lazy>收藏记录(WIP)</el-tab-pane>
51+
<el-tab-pane label="收藏记录" lazy>
52+
<UserFavoriteList :user-id="id" />
53+
</el-tab-pane>
5254
<el-tab-pane label="优惠劵" lazy>
5355
<UserCouponList :user-id="id" />
5456
</el-tab-pane>
@@ -76,6 +78,7 @@ import UserExperienceRecordList from './UserExperienceRecordList.vue'
7678
import UserOrderList from './UserOrderList.vue'
7779
import UserPointList from './UserPointList.vue'
7880
import UserSignList from './UserSignList.vue'
81+
import UserFavoriteList from './UserFavoriteList.vue'
7982
import { CardTitle } from '@/components/Card/index'
8083
import { ElMessage } from 'element-plus'
8184

0 commit comments

Comments
 (0)