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
e92361ed
authored
May 06, 2023
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code review 商品管理的实现
parent
4a965b8c
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
108 additions
and
48 deletions
+108
-48
src/api/mall/product/management/spu.ts
+12
-4
src/router/modules/remaining.ts
+2
-2
src/utils/constants.ts
+1
-0
src/utils/object.ts
+1
-0
src/views/mall/product/spu/addForm.vue
+6
-2
src/views/mall/product/spu/components/BasicInfoForm.vue
+18
-15
src/views/mall/product/spu/components/DescriptionForm.vue
+8
-5
src/views/mall/product/spu/components/OtherSettingsForm.vue
+10
-8
src/views/mall/product/spu/components/ProductAttributes.vue
+3
-0
src/views/mall/product/spu/components/ProductAttributesAddForm.vue
+0
-0
src/views/mall/product/spu/components/SkuList.vue
+12
-4
src/views/mall/product/spu/components/index.ts
+0
-0
src/views/mall/product/spu/index.vue
+35
-8
No files found.
src/api/mall/product/management/spu.ts
View file @
e92361ed
import
request
from
'@/config/axios'
import
type
{
SpuType
}
from
'./type/spuType'
import
type
{
SpuType
}
from
'./type/spuType'
// TODO @puhui999: type 和 api 一起放,简单一点哈~
// 获得spu列表
export
const
getSpuList
=
(
params
:
any
)
=>
{
// TODO @puhui999:中英文之间有空格
// 获得spu列表 TODO @puhui999:这个是 getSpuPage 哈
export
const
getSpuList
=
(
params
:
PageParam
)
=>
{
return
request
.
get
({
url
:
'/product/spu/page'
,
params
})
}
// 获得spu列表tabsCount
export
const
getTabsCount
=
()
=>
{
return
request
.
get
({
url
:
'/product/spu/tabsCount'
})
}
// 创建商品spu
export
const
createSpu
=
(
data
:
SpuType
)
=>
{
return
request
.
post
({
url
:
'/product/spu/create'
,
data
})
}
// 更新商品spu
export
const
updateSpu
=
(
data
:
SpuType
)
=>
{
return
request
.
put
({
url
:
'/product/spu/update'
,
data
})
}
// 更新商品spu status
export
const
updateStatus
=
(
data
:
{
id
:
number
;
status
:
number
})
=>
{
return
request
.
put
({
url
:
'/product/spu/updateStatus'
,
data
})
}
// 获得商品spu
// 获得商品 spu
export
const
getSpu
=
(
id
:
number
)
=>
{
return
request
.
get
({
url
:
`/product/spu/get-detail?id=
${
id
}
`
})
}
// 删除商品Spu
export
const
deleteSpu
=
(
id
:
number
)
=>
{
return
request
.
delete
({
url
:
`/product/spu/delete?id=
${
id
}
`
})
...
...
src/router/modules/remaining.ts
View file @
e92361ed
...
...
@@ -355,8 +355,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
},
children
:
[
{
path
:
'productManagementAdd'
,
component
:
()
=>
import
(
'@/views/mall/product/
management
/addForm.vue'
),
path
:
'productManagementAdd'
,
// TODO @puhui999:最好拆成 add 和 edit 两个路由;添加商品;修改商品
component
:
()
=>
import
(
'@/views/mall/product/
spu
/addForm.vue'
),
name
:
'ProductManagementAdd'
,
meta
:
{
noCache
:
true
,
...
...
src/utils/constants.ts
View file @
e92361ed
...
...
@@ -220,6 +220,7 @@ export const PayRefundStatusEnum = {
name
:
'退款关闭'
}
}
/**
* 商品SPU枚举类
*/
...
...
src/utils/object.ts
View file @
e92361ed
// TODO @puhui999:这个方法,可以考虑放到 index.js
/**
* 将值复制到目标对象,且以目标对象属性为准,例:target: {a:1} source:{a:2,b:3} 结果为:{a:2}
* @param target 目标对象
...
...
src/views/mall/product/
management
/addForm.vue
→
src/views/mall/product/
spu
/addForm.vue
View file @
e92361ed
...
...
@@ -37,7 +37,6 @@ import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
import
type
{
SpuType
}
from
'@/api/mall/product/management/type/spuType'
// 业务api
import
*
as
managementApi
from
'@/api/mall/product/management/spu'
import
*
as
PropertyApi
from
'@/api/mall/product/property'
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
{
push
,
currentRoute
}
=
useRouter
()
// 路由
...
...
@@ -69,7 +68,7 @@ const formData = ref<SpuType>({
skus
:
[
{
/**
* 商品价格,单位:分
* 商品价格,单位:分
TODO @puhui999:注释放在尾巴哈,简洁一点~
*/
price
:
0
,
/**
...
...
@@ -120,6 +119,7 @@ const formData = ref<SpuType>({
recommendNew
:
false
,
// 是否新品
recommendGood
:
false
// 是否优品
})
/** 获得详情 */
const
getDetail
=
async
()
=>
{
const
id
=
query
.
id
as
unknown
as
number
...
...
@@ -129,6 +129,7 @@ const getDetail = async () => {
const
res
=
(
await
managementApi
.
getSpu
(
id
))
as
SpuType
formData
.
value
=
res
// 直接取第一个值就能得到所有属性的id
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
const
propertyIds
=
res
.
skus
[
0
]?.
properties
.
map
((
item
)
=>
item
.
propertyId
)
const
PropertyS
=
await
PropertyApi
.
getPropertyListAndValue
({
propertyIds
})
await
nextTick
()
...
...
@@ -151,6 +152,7 @@ const submitForm = async () => {
await
unref
(
BasicInfoRef
)?.
validate
()
await
unref
(
DescriptionRef
)?.
validate
()
await
unref
(
OtherSettingsRef
)?.
validate
()
// TODO @puhui:直接做深拷贝?这样最终 server 端不满足,不需要恢复
// 处理掉一些无关数据
formData
.
value
.
skus
.
forEach
((
item
)
=>
{
// 给sku name赋值
...
...
@@ -166,6 +168,7 @@ const submitForm = async () => {
const
newSliderPicUrls
=
[]
formData
.
value
.
sliderPicUrls
.
forEach
((
item
)
=>
{
// 如果是前端选的图
// TODO @puhui999:疑问哈,为啥会是 object 呀?
if
(
typeof
item
===
'object'
)
{
newSliderPicUrls
.
push
(
item
.
url
)
}
else
{
...
...
@@ -224,6 +227,7 @@ const resetForm = async () => {
}
/** 关闭按钮 */
const
close
=
()
=>
{
// TODO @puhui999:是不是不用 reset 呀?close 默认销毁
resetForm
()
delView
(
unref
(
currentRoute
))
push
(
'/product/product-management'
)
...
...
src/views/mall/product/
management
/components/BasicInfoForm.vue
→
src/views/mall/product/
spu
/components/BasicInfoForm.vue
View file @
e92361ed
...
...
@@ -7,6 +7,7 @@
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
<!-- TODO @puhui999:只能选根节点 -->
<el-form-item
label=
"商品分类"
prop=
"categoryId"
>
<el-tree-select
v-model=
"formData.categoryId"
...
...
@@ -15,6 +16,7 @@
check-strictly
node-key=
"id"
placeholder=
"请选择商品分类"
class=
"w-1/1"
/>
</el-form-item>
</el-col>
...
...
@@ -25,7 +27,7 @@
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"单位"
prop=
"unit"
>
<el-select
v-model=
"formData.unit"
placeholder=
"请选择单位"
>
<el-select
v-model=
"formData.unit"
placeholder=
"请选择单位"
class=
"w-1/1"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.PRODUCT_UNIT)"
:key=
"dict.value"
...
...
@@ -57,7 +59,7 @@
</el-col>
<el-col
:span=
"12"
>
<el-form-item
label=
"运费模板"
prop=
"deliveryTemplateId"
>
<el-select
v-model=
"formData.deliveryTemplateId"
placeholder=
"请选择"
style=
"width: 100%
"
>
<el-select
v-model=
"formData.deliveryTemplateId"
placeholder=
"请选择"
class=
"w-1/1
"
>
<el-option
v-for=
"item in []"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-form-item>
...
...
@@ -84,9 +86,8 @@
<!-- 多规格添加-->
<el-col
:span=
"24"
>
<el-form-item
v-if=
"formData.specType"
label=
"商品属性"
>
<el-button
class=
"mr-15px mb-10px"
@
click=
"AttributesAddFormRef.open()"
>
添加规格
</el-button>
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈 -->
<el-button
class=
"mr-15px mb-10px"
@
click=
"AttributesAddFormRef.open"
>
添加规格
</el-button>
<ProductAttributes
:attribute-data=
"attributeList"
/>
</el-form-item>
<template
v-if=
"formData.specType && attributeList.length > 0"
>
...
...
@@ -108,17 +109,15 @@
<
script
lang=
"ts"
name=
"ProductManagementBasicInfoForm"
setup
>
import
{
PropType
}
from
'vue'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
{
ElInput
}
from
'element-plus'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
type
{
SpuType
}
from
'@/api/mall/product/management/type/spuType'
import
{
UploadImg
,
UploadImgs
}
from
'@/components/UploadFile'
import
{
copyValueToTarget
}
from
'@/utils/object'
import
{
ProductAttributes
,
ProductAttributesAddForm
,
SkuList
}
from
'./index'
// 业务Api
import
*
as
ProductCategoryApi
from
'@/api/mall/product/category'
import
{
propTypes
}
from
'@/utils/propTypes'
const
message
=
useMessage
()
// 消息弹窗
const
props
=
defineProps
({
propFormData
:
{
type
:
Object
as
PropType
<
SpuType
>
,
...
...
@@ -126,10 +125,11 @@ const props = defineProps({
},
activeName
:
propTypes
.
string
.
def
(
''
)
})
const
AttributesAddFormRef
=
ref
()
// 添加商品属性表单
const
ProductManagementBasicInfoRef
=
ref
()
// 表单Ref
const
AttributesAddFormRef
=
ref
()
// 添加商品属性表单 TODO @puhui999:小写开头哈
const
ProductManagementBasicInfoRef
=
ref
()
// 表单Ref TODO @puhui999:小写开头哈
// TODO @puhui999:attributeList 改成 propertyList,会更统一一点
const
attributeList
=
ref
([])
// 商品属性列表
/** 添加商品属性 */
/** 添加商品属性 */
// TODO @puhui999:propFormData 算出来
const
addAttribute
=
(
property
:
any
)
=>
{
if
(
Array
.
isArray
(
property
))
{
attributeList
.
value
=
property
...
...
@@ -162,8 +162,9 @@ const rules = reactive({
specType
:
[
required
],
subCommissionType
:
[
required
]
})
/**
* 将传进来的值赋值给formData
* 将传进来的值赋值给
formData
*/
watch
(
()
=>
props
.
propFormData
,
...
...
@@ -176,10 +177,11 @@ watch(
immediate
:
true
}
)
const
emit
=
defineEmits
([
'update:activeName'
])
/**
* 表单校验
*/
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
ProductManagementBasicInfoRef
)
return
...
...
@@ -197,7 +199,7 @@ const validate = async () => {
}
defineExpose
({
validate
,
addAttribute
})
/
/ 分销类型
/
** 分销类型 */
const
changeSubCommissionType
=
()
=>
{
// 默认为零,类型切换后也要重置为零
for
(
const
item
of
formData
.
skus
)
{
...
...
@@ -205,7 +207,8 @@ const changeSubCommissionType = () => {
item
.
subCommissionSecondPrice
=
0
}
}
// 选择规格
/** 选择规格 */
const
onChangeSpec
=
()
=>
{
// 重置商品属性列表
attributeList
.
value
=
[]
...
...
src/views/mall/product/
management
/components/DescriptionForm.vue
→
src/views/mall/product/
spu
/components/DescriptionForm.vue
View file @
e92361ed
...
...
@@ -25,6 +25,11 @@ const DescriptionFormRef = ref() // 表单Ref
const
formData
=
ref
<
SpuType
>
({
description
:
''
// 商品详情
})
// 表单规则
const
rules
=
reactive
({
description
:
[
required
]
})
/**
* 富文本编辑器如果输入过再清空会有残留,需再重置一次
*/
...
...
@@ -40,10 +45,7 @@ watch(
immediate
:
true
}
)
// 表单规则
const
rules
=
reactive
({
description
:
[
required
]
})
/**
* 将传进来的值赋值给formData
*/
...
...
@@ -58,10 +60,11 @@ watch(
immediate
:
true
}
)
const
emit
=
defineEmits
([
'update:activeName'
])
/**
* 表单校验
*/
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
DescriptionFormRef
)
return
...
...
src/views/mall/product/
management
/components/OtherSettingsForm.vue
→
src/views/mall/product/
spu
/components/OtherSettingsForm.vue
View file @
e92361ed
<
template
>
<el-form
ref=
"OtherSettingsFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-row>
<!-- TODO @puhui999:横着三个哈 -->
<el-col
:span=
"24"
>
<el-col
:span=
"8"
>
<el-form-item
label=
"商品排序"
prop=
"sort"
>
...
...
@@ -40,6 +41,7 @@
<el-tag
class=
"ml-2"
type=
"warning"
>
拼团
</el-tag>
</el-form-item>
</el-col>
<!-- TODO @puhui999:等优惠劵 ok 在搞 -->
<el-col
:span=
"24"
>
<el-form-item
label=
"赠送优惠劵"
>
<el-button>
选择优惠券
</el-button>
...
...
@@ -49,13 +51,12 @@
</el-form>
</
template
>
<
script
lang=
"ts"
name=
"OtherSettingsForm"
setup
>
// 商品推荐
import
type
{
SpuType
}
from
'@/api/mall/product/management/type/spuType'
import
{
PropType
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils/object'
import
{
propTypes
}
from
'@/utils/propTypes'
const
message
=
useMessage
()
// 消息弹窗
const
props
=
defineProps
({
propFormData
:
{
type
:
Object
as
PropType
<
SpuType
>
,
...
...
@@ -63,7 +64,7 @@ const props = defineProps({
},
activeName
:
propTypes
.
string
.
def
(
''
)
})
// 商品推荐选项
// 商品推荐选项
TODO @puhui999:这种叫 recommendOptions 会更合适哈
const
recommend
=
[
{
name
:
'是否热卖'
,
value
:
'recommendHot'
},
{
name
:
'是否优惠'
,
value
:
'recommendBenefit'
},
...
...
@@ -71,10 +72,10 @@ const recommend = [
{
name
:
'是否新品'
,
value
:
'recommendNew'
},
{
name
:
'是否优品'
,
value
:
'recommendGood'
}
]
// 选中推荐选项
const
checkboxGroup
=
ref
<
string
[]
>
([
'recommendHot'
])
// 选择商品后赋值
const
checkboxGroup
=
ref
<
string
[]
>
([
'recommendHot'
])
// 选中推荐选项
/** 选择商品后赋值 */
const
onChangeGroup
=
()
=>
{
// TODO @puhui999:是不是可以遍历 recommend,然后进行是否选中;
checkboxGroup
.
value
.
includes
(
'recommendHot'
)
?
(
formData
.
value
.
recommendHot
=
true
)
:
(
formData
.
value
.
recommendHot
=
false
)
...
...
@@ -109,6 +110,7 @@ const rules = reactive({
giveIntegral
:
[
required
],
virtualSalesCount
:
[
required
]
})
/**
* 将传进来的值赋值给formData
*/
...
...
@@ -130,10 +132,11 @@ watch(
immediate
:
true
}
)
const
emit
=
defineEmits
([
'update:activeName'
])
/**
* 表单校验
*/
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
OtherSettingsFormRef
)
return
...
...
@@ -149,6 +152,5 @@ const validate = async () => {
}
})
}
defineExpose
({
validate
})
</
script
>
src/views/mall/product/
management
/components/ProductAttributes.vue
→
src/views/mall/product/
spu
/components/ProductAttributes.vue
View file @
e92361ed
...
...
@@ -71,16 +71,19 @@ watch(
immediate
:
true
}
)
/** 删除标签 tagValue 标签值*/
const
handleClose
=
(
index
,
valueIndex
)
=>
{
attributeList
.
value
[
index
].
values
?.
splice
(
valueIndex
,
1
)
}
/** 显示输入框并获取焦点 */
const
showInput
=
async
(
index
)
=>
{
attributeIndex
.
value
=
index
// 因为组件在ref中所以需要用索引获取对应的Ref
InputRef
.
value
[
index
]
!
.
input
!
.
focus
()
}
/** 输入框失去焦点或点击回车时触发 */
const
handleInputConfirm
=
async
(
index
,
propertyId
)
=>
{
if
(
inputValue
.
value
)
{
...
...
src/views/mall/product/
management
/components/ProductAttributesAddForm.vue
→
src/views/mall/product/
spu
/components/ProductAttributesAddForm.vue
View file @
e92361ed
File moved
src/views/mall/product/
management
/components/SkuList.vue
→
src/views/mall/product/
spu
/components/SkuList.vue
View file @
e92361ed
...
...
@@ -25,11 +25,13 @@
</
template
>
</el-table-column>
</template>
<!-- TODO @puhui999: controls-position="right" 可以去掉哈,不然太长了,手动输入更方便 -->
<el-table-column
align=
"center"
label=
"商品条码"
min-width=
"168"
>
<
template
#
default=
"{ row }"
>
<el-input
v-model=
"row.barCode"
class=
"w-100%"
/>
</
template
>
</el-table-column>
<!-- TODO @puhui999:用户输入的时候,是按照元;分主要是我们自己用; -->
<el-table-column
align=
"center"
label=
"销售价(分)"
min-width=
"168"
>
<
template
#
default=
"{ row }"
>
<el-input-number
v-model=
"row.price"
:min=
"0"
class=
"w-100%"
controls-position=
"right"
/>
...
...
@@ -94,15 +96,14 @@
</template>
<el-table-column
v-if=
"formData.specType"
align=
"center"
fixed=
"right"
label=
"操作"
width=
"80"
>
<
template
#
default
>
<el-button
v-if=
"isBatch"
link
size=
"small"
type=
"primary"
@
click=
"batchAdd"
>
批量添加
<el-button
v-if=
"isBatch"
link
size=
"small"
type=
"primary"
@
click=
"batchAdd"
>
批量添加
</el-button>
<el-button
v-else
link
size=
"small"
type=
"primary"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</template>
<
script
lang=
"ts"
name=
"SkuList"
setup
>
import
{
UploadImg
}
from
'@/components/UploadFile'
import
{
PropType
}
from
'vue'
...
...
@@ -123,7 +124,7 @@ const props = defineProps({
isBatch
:
propTypes
.
bool
.
def
(
false
)
// 是否批量操作
})
const
formData
=
ref
<
SpuType
>
()
// 表单数据
// 批量添加时的零时数据
// 批量添加时的零时数据
TODO @puhui999:小写开头哈;然后变量都尾注释
const
SkuData
=
ref
<
SkuType
[]
>
([
{
/**
...
...
@@ -168,13 +169,16 @@ const SkuData = ref<SkuType[]>([
subCommissionSecondPrice
:
0
}
])
/** 批量添加 */
const
batchAdd
=
()
=>
{
formData
.
value
.
skus
.
forEach
((
item
)
=>
{
copyValueToTarget
(
item
,
SkuData
.
value
[
0
])
})
}
const
tableHeaderList
=
ref
<
{
prop
:
string
;
label
:
string
}[]
>
([])
/**
* 将传进来的值赋值给SkuData
*/
...
...
@@ -189,6 +193,8 @@ watch(
immediate
:
true
}
)
// TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不
/** 生成表数据 */
const
generateTableData
=
(
data
:
any
[])
=>
{
// 构建数据结构
...
...
@@ -237,6 +243,7 @@ const generateTableData = (data: any[]) => {
formData
.
value
.
skus
.
push
(
row
)
})
}
/** 构建所有排列组合 */
const
build
=
(
list
:
any
[])
=>
{
if
(
list
.
length
===
0
)
{
...
...
@@ -259,6 +266,7 @@ const build = (list: any[]) => {
return
result
}
}
/** 监听属性列表生成相关参数和表头 */
watch
(
()
=>
props
.
attributeList
,
...
...
src/views/mall/product/
management
/components/index.ts
→
src/views/mall/product/
spu
/components/index.ts
View file @
e92361ed
File moved
src/views/mall/product/
management
/index.vue
→
src/views/mall/product/
spu
/index.vue
View file @
e92361ed
...
...
@@ -8,6 +8,7 @@
class=
"-mb-15px"
label-width=
"68px"
>
<!-- TODO @puhui999:https://admin.java.crmeb.net/store/index,参考,使用分类 + 标题搜索 -->
<el-form-item
label=
"品牌名称"
prop=
"name"
>
<el-input
v-model=
"queryParams.name"
...
...
@@ -51,6 +52,7 @@
<Icon
class=
"mr-5px"
icon=
"ep:plus"
/>
新增
</el-button>
<!-- TODO @puhui999:增加一个【导出】操作 -->
</el-form-item>
</el-form>
</ContentWrap>
...
...
@@ -66,6 +68,7 @@
/>
</el-tabs>
<el-table
v-loading=
"loading"
:data=
"list"
>
<!-- TODO puhui999: ID 编号的展示 -->
<!-- TODO 暂时不做折叠数据 -->
<!--
<el-table-column
type=
"expand"
>
-->
<!--
<template
#
default=
"
{ row }">-->
...
...
@@ -92,6 +95,7 @@
</
template
>
</el-table-column>
<el-table-column
:show-overflow-tooltip=
"true"
label=
"商品名称"
min-width=
"300"
prop=
"name"
/>
<!-- TODO 价格 / 100.0 -->
<el-table-column
align=
"center"
label=
"商品售价"
min-width=
"90"
prop=
"price"
/>
<el-table-column
align=
"center"
label=
"销量"
min-width=
"90"
prop=
"salesCount"
/>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"90"
prop=
"stock"
/>
...
...
@@ -105,6 +109,7 @@
/>
<el-table-column
fixed=
"right"
label=
"状态"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<!-- TODO @puhui:是不是不用 Number(row.status) 去比较哈,直接 row.status
<
0
--
>
<el-switch
v-model=
"row.status"
:active-value=
"1"
...
...
@@ -119,6 +124,7 @@
</el-table-column>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"150"
>
<
template
#
default=
"{ row }"
>
<!-- TODO @puhui999:【详情】,可以后面点做哈 -->
<template
v-if=
"queryParams.tabType === 4"
>
<el-button
v-hasPermi=
"['product:spu:delete']"
...
...
@@ -166,6 +172,7 @@
@
pagination=
"getList"
/>
</ContentWrap>
<!-- https://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/image-viewer.html,可以用这个么? -->
<!-- 必须在表格外面展示。不然单元格会遮挡图层 -->
<el-image-viewer
v-if=
"imgViewVisible"
...
...
@@ -173,20 +180,21 @@
@
close=
"imgViewVisible = false"
/>
</template>
<
script
lang=
"ts"
name=
"Product
Managemen
t"
setup
>
<
script
lang=
"ts"
name=
"Product
Lis
t"
setup
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
}
from
'@/utils/formatTime'
// 业务api
import
{
dateFormatter
}
from
'@/utils/formatTime'
// TODO @puhui999:managementApi=》ProductSpuApi
import
*
as
managementApi
from
'@/api/mall/product/management/spu'
import
{
ProductSpuStatusEnum
}
from
'@/utils/constants'
import
{
TabsPaneContext
}
from
'element-plus'
const
message
=
useMessage
()
// 消息弹窗
const
{
t
}
=
useI18n
()
// 国际化
const
{
currentRoute
,
push
}
=
useRouter
()
// 路由跳转
const
loading
=
ref
(
false
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
<
any
[]
>
([])
// 列表的数据
// tabs数据
// tabs
数据
const
tabsData
=
ref
([
{
count
:
0
,
...
...
@@ -214,7 +222,10 @@ const tabsData = ref([
type
:
4
}
])
/** 获得每个 Tab 的数量 */
const
getTabsCount
=
async
()
=>
{
// TODO @puhui999:这里是不是可以不要 try catch 哈
try
{
const
res
=
await
managementApi
.
getTabsCount
()
for
(
let
objName
in
res
)
{
...
...
@@ -222,6 +233,7 @@ const getTabsCount = async () => {
}
}
catch
{}
}
const
imgViewVisible
=
ref
(
false
)
// 商品图预览
const
imageViewerList
=
ref
<
string
[]
>
([])
// 商品图预览列表
const
queryParams
=
ref
({
...
...
@@ -230,10 +242,13 @@ const queryParams = ref({
tabType
:
0
})
const
queryFormRef
=
ref
()
// 搜索的表单
// TODO @puhui999:可以改成 handleTabClick:更准确一点;
const
handleClick
=
(
tab
:
TabsPaneContext
)
=>
{
queryParams
.
value
.
tabType
=
tab
.
paneName
getList
()
}
/** 查询列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
...
...
@@ -246,8 +261,10 @@ const getList = async () => {
}
}
// TODO @puhui999:是不是 changeStatus 和 addToTrash 调用一个统一的方法,去更新状态。这样逻辑会更干净一些。
/**
* 更改SPU状态
* 更改 SPU 状态
*
* @param row
* @param status 更改前的值
*/
...
...
@@ -271,7 +288,7 @@ const changeStatus = async (row, status?: number) => {
)
await
managementApi
.
updateStatus
({
id
:
row
.
id
,
status
:
row
.
status
})
message
.
success
(
'更新状态成功'
)
// 刷新
tabs
数据
// 刷新
tabs
数据
await
getTabsCount
()
// 刷新列表
await
getList
()
...
...
@@ -288,8 +305,10 @@ const changeStatus = async (row, status?: number) => {
:
ProductSpuStatusEnum
.
DISABLE
.
status
}
}
/**
* 加入回收站
*
* @param row
* @param status
*/
...
...
@@ -299,6 +318,7 @@ const addToTrash = (row, status) => {
row
.
status
=
status
changeStatus
(
row
,
num
)
}
/** 删除按钮操作 */
const
handleDelete
=
async
(
id
:
number
)
=>
{
try
{
...
...
@@ -313,6 +333,7 @@ const handleDelete = async (id: number) => {
await
getList
()
}
catch
{}
}
/**
* 商品图预览
* @param imgUrl
...
...
@@ -321,6 +342,7 @@ const imagePreview = (imgUrl: string) => {
imageViewerList
.
value
=
[
imgUrl
]
imgViewVisible
.
value
=
true
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
getList
()
...
...
@@ -334,16 +356,20 @@ const resetQuery = () => {
/**
* 新增或修改
* @param id
*
* @param id 商品 SPU 编号
*/
const
openForm
=
(
id
?:
number
)
=>
{
// 修改
if
(
typeof
id
===
'number'
)
{
push
(
'/product/productManagementAdd?id='
+
id
)
return
}
// 新增
push
(
'/product/productManagementAdd'
)
}
// 监听路由变化更新列表
// 监听路由变化更新列表 TODO @puhui999:这个是必须加的么?
watch
(
()
=>
currentRoute
.
value
,
()
=>
{
...
...
@@ -353,6 +379,7 @@ watch(
immediate
:
true
}
)
/** 初始化 **/
onMounted
(()
=>
{
getTabsCount
()
...
...
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