Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
52bfc4da
authored
May 17, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 进一步完善商品列表,修复TODO
parent
50b18131
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
115 deletions
+110
-115
src/api/mall/product/spu.ts
+10
-12
src/views/mall/product/spu/index.vue
+100
-103
No files found.
src/api/mall/product/spu.ts
View file @
52bfc4da
...
@@ -33,7 +33,7 @@ export interface SpuType {
...
@@ -33,7 +33,7 @@ export interface SpuType {
picUrl
?:
string
// 商品封面图
picUrl
?:
string
// 商品封面图
sliderPicUrls
?:
string
[]
// 商品轮播图
sliderPicUrls
?:
string
[]
// 商品轮播图
introduction
?:
string
// 商品简介
introduction
?:
string
// 商品简介
deliveryTemplateId
?:
number
// 运费模版
deliveryTemplateId
?:
number
|
null
// 运费模版
specType
?:
boolean
// 商品规格
specType
?:
boolean
// 商品规格
subCommissionType
?:
boolean
// 分销类型
subCommissionType
?:
boolean
// 分销类型
skus
:
SkuType
[]
// sku数组
skus
:
SkuType
[]
// sku数组
...
@@ -48,39 +48,37 @@ export interface SpuType {
...
@@ -48,39 +48,37 @@ export interface SpuType {
recommendGood
?:
boolean
// 是否优品
recommendGood
?:
boolean
// 是否优品
}
}
// TODO @puhui999:中英文之间有空格
// 获得 Spu 列表
// 获得spu列表 TODO @puhui999:这个是 getSpuPage 哈
export
const
getSpuPage
=
(
params
:
PageParam
)
=>
{
export
const
getSpuPage
=
(
params
:
PageParam
)
=>
{
return
request
.
get
({
url
:
'/product/spu/page'
,
params
})
return
request
.
get
({
url
:
'/product/spu/page'
,
params
})
}
}
// 获得
spu列表
tabsCount
// 获得
Spu 列表
tabsCount
export
const
getTabsCount
=
()
=>
{
export
const
getTabsCount
=
()
=>
{
return
request
.
get
({
url
:
'/product/spu/
tabsC
ount'
})
return
request
.
get
({
url
:
'/product/spu/
get-c
ount'
})
}
}
// 创建商品
s
pu
// 创建商品
S
pu
export
const
createSpu
=
(
data
:
SpuType
)
=>
{
export
const
createSpu
=
(
data
:
SpuType
)
=>
{
return
request
.
post
({
url
:
'/product/spu/create'
,
data
})
return
request
.
post
({
url
:
'/product/spu/create'
,
data
})
}
}
// 更新商品
s
pu
// 更新商品
S
pu
export
const
updateSpu
=
(
data
:
SpuType
)
=>
{
export
const
updateSpu
=
(
data
:
SpuType
)
=>
{
return
request
.
put
({
url
:
'/product/spu/update'
,
data
})
return
request
.
put
({
url
:
'/product/spu/update'
,
data
})
}
}
// 更新商品
s
pu status
// 更新商品
S
pu status
export
const
updateStatus
=
(
data
:
{
id
:
number
;
status
:
number
})
=>
{
export
const
updateStatus
=
(
data
:
{
id
:
number
;
status
:
number
})
=>
{
return
request
.
put
({
url
:
'/product/spu/update
S
tatus'
,
data
})
return
request
.
put
({
url
:
'/product/spu/update
-s
tatus'
,
data
})
}
}
// 获得商品
s
pu
// 获得商品
S
pu
export
const
getSpu
=
(
id
:
number
)
=>
{
export
const
getSpu
=
(
id
:
number
)
=>
{
return
request
.
get
({
url
:
`/product/spu/get-detail?id=
${
id
}
`
})
return
request
.
get
({
url
:
`/product/spu/get-detail?id=
${
id
}
`
})
}
}
// 删除商品Spu
// 删除商品
Spu
export
const
deleteSpu
=
(
id
:
number
)
=>
{
export
const
deleteSpu
=
(
id
:
number
)
=>
{
return
request
.
delete
({
url
:
`/product/spu/delete?id=
${
id
}
`
})
return
request
.
delete
({
url
:
`/product/spu/delete?id=
${
id
}
`
})
}
}
src/views/mall/product/spu/index.vue
View file @
52bfc4da
...
@@ -18,15 +18,17 @@
...
@@ -18,15 +18,17 @@
@
keyup
.
enter=
"handleQuery"
@
keyup
.
enter=
"handleQuery"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"状态"
prop=
"status"
>
<!-- TODO 分类只能选择二级分类目前还没做,还是先以联调通顺为主 -->
<el-select
v-model=
"queryParams.status"
class=
"!w-240px"
clearable
placeholder=
"请选择状态"
>
<el-form-item
label=
"商品分类"
prop=
"categoryId"
>
<el-option
<el-tree-select
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
v-model=
"queryParams.categoryId"
:key=
"dict.value"
:data=
"categoryList"
:label=
"dict.label"
:props=
"defaultProps"
:value=
"dict.value"
check-strictly
/>
class=
"w-1/1"
</el-select>
node-key=
"id"
placeholder=
"请选择商品分类"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-form-item
label=
"创建时间"
prop=
"createTime"
>
<el-date-picker
<el-date-picker
...
@@ -59,7 +61,7 @@
...
@@ -59,7 +61,7 @@
<!-- 列表 -->
<!-- 列表 -->
<ContentWrap>
<ContentWrap>
<el-tabs
v-model=
"queryParams.tabType"
@
tab-click=
"handleClick"
>
<el-tabs
v-model=
"queryParams.tabType"
@
tab-click=
"handle
Tab
Click"
>
<el-tab-pane
<el-tab-pane
v-for=
"item in tabsData"
v-for=
"item in tabsData"
:key=
"item.type"
:key=
"item.type"
...
@@ -68,28 +70,29 @@
...
@@ -68,28 +70,29 @@
/>
/>
</el-tabs>
</el-tabs>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table
v-loading=
"loading"
:data=
"list"
>
<!-- TODO puhui999: ID 编号的展示 -->
<!-- TODO 折叠数据按需增加暂定以下三个 -->
<!-- TODO 暂时不做折叠数据 -->
<el-table-column
type=
"expand"
width=
"30"
>
<!--
<el-table-column
type=
"expand"
>
-->
<template
#
default=
"
{ row }">
<!--
<template
#
default=
"
{ row }">-->
<el-form
class=
"demo-table-expand"
inline
label-position=
"left"
>
<!--
<el-form
inline
label-position=
"left"
>
-->
<el-form-item
label=
"市场价:"
>
<!--
<el-form-item
label=
"市场价:"
>
-->
<span>
{{
row
.
marketPrice
}}
</span>
<!--
<span>
{{
row
.
marketPrice
}}
</span>
-->
</el-form-item>
<!--
</el-form-item>
-->
<el-form-item
label=
"成本价:"
>
<!--
<el-form-item
label=
"成本价:"
>
-->
<span>
{{
row
.
costPrice
}}
</span>
<!--
<span>
{{
row
.
costPrice
}}
</span>
-->
</el-form-item>
<!--
</el-form-item>
-->
<el-form-item
label=
"虚拟销量:"
>
<!--
<el-form-item
label=
"虚拟销量:"
>
-->
<span>
{{
row
.
virtualSalesCount
}}
</span>
<!--
<span>
{{
row
.
virtualSalesCount
}}
</span>
-->
</el-form-item>
<!--
</el-form-item>
-->
</el-form>
<!--
</el-form>
-->
</
template
>
<!--
</
template
>
-->
</el-table-column>
<!-- </el-table-column>-->
<!-- TODO puhui999: ID 编号的展示 fix-->
<el-table-column
key=
"id"
align=
"center"
label=
"商品编号"
prop=
"id"
/>
<el-table-column
label=
"商品图"
min-width=
"80"
>
<el-table-column
label=
"商品图"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<el-image
<el-image
:src=
"row.picUrl"
:src=
"row.picUrl"
style=
"width: 3
6px; height: 36
px"
style=
"width: 3
0px; height: 30
px"
@
click=
"imagePreview(row.picUrl)"
@
click=
"imagePreview(row.picUrl)"
/>
/>
</
template
>
</
template
>
...
@@ -107,19 +110,23 @@
...
@@ -107,19 +110,23 @@
prop=
"createTime"
prop=
"createTime"
width=
"180"
width=
"180"
/>
/>
<el-table-column
fixed=
"right
"
label=
"状态"
min-width=
"80"
>
<el-table-column
align=
"center
"
label=
"状态"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<!-- TODO @puhui:是不是不用 Number(row.status) 去比较哈,直接 row.status
<
0
--
>
<!-- fix: 修复打开回收站时商品误触改变商品状态的事件,因为el-switch只用0和1没有-1所以当商品状态为-1时状态使用el-tag显示 -->
<el-switch
<template
v-if=
"row.status >= 0"
>
v-model=
"row.status"
<el-switch
:active-value=
"1"
v-model=
"row.status"
:disabled=
"Number(row.status)
<
0
"
:active-value=
"1"
:inactive-value=
"0"
:inactive-value=
"0"
active-text=
"上架"
active-text=
"上架"
inactive-text=
"下架"
inactive-text=
"下架"
inline-prompt
inline-prompt
@
change=
"changeStatus(row)"
@
change=
"changeStatus(row)"
/>
/>
</
template
>
<
template
v-else
>
<el-tag
type=
"info"
>
回收站
</el-tag>
</
template
>
</template>
</template>
</el-table-column>
</el-table-column>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"150"
>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"150"
>
...
@@ -138,7 +145,7 @@
...
@@ -138,7 +145,7 @@
v-hasPermi=
"['product:spu:update']"
v-hasPermi=
"['product:spu:update']"
link
link
type=
"primary"
type=
"primary"
@
click=
"
addToTrash
(row, ProductSpuStatusEnum.DISABLE.status)"
@
click=
"
changeStatus
(row, ProductSpuStatusEnum.DISABLE.status)"
>
>
恢复到仓库
恢复到仓库
</el-button>
</el-button>
...
@@ -156,7 +163,7 @@
...
@@ -156,7 +163,7 @@
v-hasPermi=
"['product:spu:update']"
v-hasPermi=
"['product:spu:update']"
link
link
type=
"primary"
type=
"primary"
@
click=
"
addToTrash
(row, ProductSpuStatusEnum.RECYCLE.status)"
@
click=
"
changeStatus
(row, ProductSpuStatusEnum.RECYCLE.status)"
>
>
加入回收站
加入回收站
</el-button>
</el-button>
...
@@ -172,21 +179,17 @@
...
@@ -172,21 +179,17 @@
@
pagination=
"getList"
@
pagination=
"getList"
/>
/>
</ContentWrap>
</ContentWrap>
<!-- https://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/image-viewer.html,可以用这个么? -->
<!-- 必须在表格外面展示。不然单元格会遮挡图层 -->
<el-image-viewer
v-if=
"imgViewVisible"
:url-list=
"imageViewerList"
@
close=
"imgViewVisible = false"
/>
</template>
</template>
<
script
lang=
"ts"
name=
"ProductList"
setup
>
<
script
lang=
"ts"
name=
"ProductSpu"
setup
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
TabsPaneContext
}
from
'element-plus'
import
{
cloneDeep
}
from
'lodash-es'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
dateFormatter
}
from
'@/utils/formatTime'
// TODO @puhui999:managementApi=》ProductSpuApi
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
*
as
managementApi
from
'@/api/mall/product/management/spu'
import
{
ProductSpuStatusEnum
}
from
'@/utils/constants'
import
{
ProductSpuStatusEnum
}
from
'@/utils/constants'
import
{
TabsPaneContext
}
from
'element-plus'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
ProductCategoryApi
from
'@/api/mall/product/category'
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
{
currentRoute
,
push
}
=
useRouter
()
// 路由跳转
const
{
currentRoute
,
push
}
=
useRouter
()
// 路由跳转
...
@@ -225,26 +228,21 @@ const tabsData = ref([
...
@@ -225,26 +228,21 @@ const tabsData = ref([
/** 获得每个 Tab 的数量 */
/** 获得每个 Tab 的数量 */
const
getTabsCount
=
async
()
=>
{
const
getTabsCount
=
async
()
=>
{
// TODO @puhui999:这里是不是可以不要 try catch 哈
// TODO @puhui999:这里是不是可以不要 try catch 哈 fix
try
{
const
res
=
await
ProductSpuApi
.
getTabsCount
()
const
res
=
await
managementApi
.
getTabsCount
()
for
(
let
objName
in
res
)
{
for
(
let
objName
in
res
)
{
tabsData
.
value
[
Number
(
objName
)].
count
=
res
[
objName
]
tabsData
.
value
[
Number
(
objName
)].
count
=
res
[
objName
]
}
}
}
catch
{}
}
}
const
imgViewVisible
=
ref
(
false
)
// 商品图预览
const
imageViewerList
=
ref
<
string
[]
>
([])
// 商品图预览列表
const
queryParams
=
ref
({
const
queryParams
=
ref
({
pageNo
:
1
,
pageNo
:
1
,
pageSize
:
10
,
pageSize
:
10
,
tabType
:
0
tabType
:
0
})
})
// 查询参数
const
queryFormRef
=
ref
()
// 搜索的表单
const
queryFormRef
=
ref
()
// 搜索的表单
Ref
// TODO @puhui999:可以改成 handleTabClick:更准确一点;
// TODO @puhui999:可以改成 handleTabClick:更准确一点;
fix
const
handleClick
=
(
tab
:
TabsPaneContext
)
=>
{
const
handle
Tab
Click
=
(
tab
:
TabsPaneContext
)
=>
{
queryParams
.
value
.
tabType
=
tab
.
paneName
queryParams
.
value
.
tabType
=
tab
.
paneName
getList
()
getList
()
}
}
...
@@ -253,7 +251,7 @@ const handleClick = (tab: TabsPaneContext) => {
...
@@ -253,7 +251,7 @@ const handleClick = (tab: TabsPaneContext) => {
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
const
data
=
await
managementApi
.
getSpuList
(
queryParams
.
value
)
const
data
=
await
ProductSpuApi
.
getSpuPage
(
queryParams
.
value
)
list
.
value
=
data
.
list
list
.
value
=
data
.
list
total
.
value
=
data
.
total
total
.
value
=
data
.
total
}
finally
{
}
finally
{
...
@@ -261,7 +259,7 @@ const getList = async () => {
...
@@ -261,7 +259,7 @@ const getList = async () => {
}
}
}
}
// TODO @puhui999:是不是 changeStatus 和 addToTrash 调用一个统一的方法,去更新状态。这样逻辑会更干净一些。
// TODO @puhui999:是不是 changeStatus 和 addToTrash 调用一个统一的方法,去更新状态。这样逻辑会更干净一些。
fix
/**
/**
* 更改 SPU 状态
* 更改 SPU 状态
*
*
...
@@ -269,10 +267,12 @@ const getList = async () => {
...
@@ -269,10 +267,12 @@ const getList = async () => {
* @param status 更改前的值
* @param status 更改前的值
*/
*/
const
changeStatus
=
async
(
row
,
status
?:
number
)
=>
{
const
changeStatus
=
async
(
row
,
status
?:
number
)
=>
{
// TODO 测试过程中似乎有点问题,下一版修复
// fix: 将加入回收站功能合并到changeStatus并优化
const
deepCopyValue
=
cloneDeep
(
unref
(
row
))
if
(
typeof
status
!==
'undefined'
)
deepCopyValue
.
status
=
status
try
{
try
{
let
text
=
''
let
text
=
''
switch
(
row
.
status
)
{
switch
(
deepCopyValue
.
status
)
{
case
ProductSpuStatusEnum
.
DISABLE
.
status
:
case
ProductSpuStatusEnum
.
DISABLE
.
status
:
text
=
ProductSpuStatusEnum
.
DISABLE
.
name
text
=
ProductSpuStatusEnum
.
DISABLE
.
name
break
break
...
@@ -283,21 +283,21 @@ const changeStatus = async (row, status?: number) => {
...
@@ -283,21 +283,21 @@ const changeStatus = async (row, status?: number) => {
text
=
`加入
${
ProductSpuStatusEnum
.
RECYCLE
.
name
}
`
text
=
`加入
${
ProductSpuStatusEnum
.
RECYCLE
.
name
}
`
break
break
}
}
// fix: 修复恢复到仓库的信息提示
await
message
.
confirm
(
await
message
.
confirm
(
row
.
status
===
-
1
?
`确认要将[
${
row
.
name
}
]
${
text
}
吗?`
:
`确认要
${
text
}
[
${
row
.
name
}
]吗?`
deepCopyValue
.
status
===
-
1
?
`确认要将[
${
row
.
name
}
]
${
text
}
吗?`
:
row
.
status
===
-
1
// 再判断一次原对象是否等于-1,例: 把回收站中的商品恢复到仓库中,事件触发时原对象status为-1 深拷贝对象status被赋值为0
?
`确认要将[
${
row
.
name
}
]恢复到仓库吗?`
:
`确认要
${
text
}
[
${
row
.
name
}
]吗?`
)
)
await
managementApi
.
updateStatus
({
id
:
row
.
id
,
status
:
row
.
status
})
await
ProductSpuApi
.
updateStatus
({
id
:
deepCopyValue
.
id
,
status
:
deepCopyValue
.
status
})
message
.
success
(
'更新状态成功'
)
message
.
success
(
'更新状态成功'
)
// 刷新 tabs 数据
// 刷新 tabs 数据
await
getTabsCount
()
await
getTabsCount
()
// 刷新列表
// 刷新列表
await
getList
()
await
getList
()
}
catch
{
}
catch
{
// 取消加入回收站时回显数据
if
(
typeof
status
!==
'undefined'
)
{
row
.
status
=
status
return
}
// 取消更改状态时回显数据
// 取消更改状态时回显数据
row
.
status
=
row
.
status
=
row
.
status
===
ProductSpuStatusEnum
.
DISABLE
.
status
row
.
status
===
ProductSpuStatusEnum
.
DISABLE
.
status
...
@@ -306,26 +306,13 @@ const changeStatus = async (row, status?: number) => {
...
@@ -306,26 +306,13 @@ const changeStatus = async (row, status?: number) => {
}
}
}
}
/**
* 加入回收站
*
* @param row
* @param status
*/
const
addToTrash
=
(
row
,
status
)
=>
{
// 复制一份原值
const
num
=
Number
(
`
${
row
.
status
}
`
)
row
.
status
=
status
changeStatus
(
row
,
num
)
}
/** 删除按钮操作 */
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
try
{
// 删除的二次确认
// 删除的二次确认
await
message
.
delConfirm
()
await
message
.
delConfirm
()
// 发起删除
// 发起删除
await
management
Api
.
deleteSpu
(
id
)
await
ProductSpu
Api
.
deleteSpu
(
id
)
message
.
success
(
t
(
'common.delSuccess'
))
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新tabs数据
// 刷新tabs数据
await
getTabsCount
()
await
getTabsCount
()
...
@@ -339,8 +326,10 @@ const handleDelete = async (id: number) => {
...
@@ -339,8 +326,10 @@ const handleDelete = async (id: number) => {
* @param imgUrl
* @param imgUrl
*/
*/
const
imagePreview
=
(
imgUrl
:
string
)
=>
{
const
imagePreview
=
(
imgUrl
:
string
)
=>
{
imageViewerList
.
value
=
[
imgUrl
]
// fix: 改用https://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/image-viewer.html 预览图片
imgViewVisible
.
value
=
true
createImageViewer
({
urlList
:
[
imgUrl
]
})
}
}
/** 搜索按钮操作 */
/** 搜索按钮操作 */
...
@@ -369,20 +358,28 @@ const openForm = (id?: number) => {
...
@@ -369,20 +358,28 @@ const openForm = (id?: number) => {
push
(
'/product/productManagementAdd'
)
push
(
'/product/productManagementAdd'
)
}
}
// 监听路由变化更新列表 TODO @puhui999:这个是必须加的么?
// 监听路由变化更新列表 TODO @puhui999:这个是必须加的么?
fix: 因为编辑表单是以路由的方式打开,保存表单后列表不会刷新
watch
(
watch
(
()
=>
currentRoute
.
value
,
()
=>
currentRoute
.
value
,
()
=>
{
()
=>
{
getList
()
getList
()
},
{
immediate
:
true
}
}
)
)
const
categoryList
=
ref
()
// 分类树
/** 初始化 **/
/** 初始化 **/
onMounted
(()
=>
{
onMounted
(
async
()
=>
{
getTabsCount
()
await
getTabsCount
()
getList
()
await
getList
()
// 获得分类树
const
data
=
await
ProductCategoryApi
.
getCategoryList
({})
categoryList
.
value
=
handleTree
(
data
,
'id'
,
'parentId'
)
})
})
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
.demo-table-expand
{
:deep(.el-form-item__label)
{
width
:
82px
;
color
:
#99a9bf
;
}
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment