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
39c92cb9
authored
May 31, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 完善 SPU 查看详情
parent
e5559777
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
387 additions
and
37 deletions
+387
-37
src/api/mall/product/spu.ts
+1
-1
src/router/modules/remaining.ts
+13
-0
src/utils/tree.ts
+16
-5
src/views/mall/product/spu/addForm.vue
+8
-4
src/views/mall/product/spu/components/BasicInfoForm.vue
+74
-6
src/views/mall/product/spu/components/DescriptionForm.vue
+23
-2
src/views/mall/product/spu/components/OtherSettingsForm.vue
+35
-2
src/views/mall/product/spu/components/SkuList.vue
+97
-9
src/views/mall/product/spu/components/spu.data.ts
+105
-0
src/views/mall/product/spu/index.vue
+15
-8
No files found.
src/api/mall/product/spu.ts
View file @
39c92cb9
...
...
@@ -37,7 +37,7 @@ export interface Spu {
brandId
?:
number
|
null
// 商品品牌编号
specType
?:
boolean
// 商品规格
subCommissionType
?:
boolean
// 分销类型
skus
:
Sku
[]
// sku数组
skus
?
:
Sku
[]
// sku数组
description
?:
string
// 商品详情
sort
?:
number
// 商品排序
giveIntegral
?:
number
// 赠送积分
...
...
src/router/modules/remaining.ts
View file @
39c92cb9
...
...
@@ -379,6 +379,19 @@ const remainingRouter: AppRouteRecordRaw[] = [
title
:
'编辑商品'
,
activeMenu
:
'/product/product-spu'
}
},
{
path
:
'productSpuDetail/:spuId(\\d+)'
,
component
:
()
=>
import
(
'@/views/mall/product/spu/addForm.vue'
),
name
:
'productSpuDetail'
,
meta
:
{
noCache
:
true
,
hidden
:
true
,
canTo
:
true
,
icon
:
'ep:view'
,
title
:
'商品详情'
,
activeMenu
:
'/product/product-spu'
}
}
]
}
...
...
src/utils/tree.ts
View file @
39c92cb9
...
...
@@ -312,26 +312,30 @@ export const handleTree2 = (data, id, parentId, children, rootId) => {
* @param nodeId 需要判断在什么层级的数据
* @param level 检查的级别, 默认检查到二级
*/
export
const
checkSelectedNode
=
(
tree
:
any
[],
nodeId
,
level
=
2
)
=>
{
export
const
checkSelectedNode
=
(
tree
:
any
[],
nodeId
:
any
,
level
=
2
):
boolean
=>
{
if
(
typeof
tree
===
'undefined'
||
!
Array
.
isArray
(
tree
)
||
tree
.
length
===
0
)
{
console
.
warn
(
'tree must be an array'
)
return
false
}
// 校验是否是一级节点
if
(
tree
.
some
((
item
)
=>
item
.
id
===
nodeId
))
{
return
false
}
// 递归计数
let
count
=
1
// 深层次校验
function
performAThoroughValidation
(
arr
)
{
function
performAThoroughValidation
(
arr
:
any
[]):
boolean
{
count
+=
1
for
(
const
item
of
arr
)
{
if
(
item
.
id
===
nodeId
)
{
return
true
}
else
if
(
typeof
item
.
children
!==
'undefined'
&&
item
.
children
.
length
!==
0
)
{
performAThoroughValidation
(
item
.
children
)
if
(
performAThoroughValidation
(
item
.
children
))
{
return
true
}
}
}
return
false
...
...
@@ -341,11 +345,15 @@ export const checkSelectedNode = (tree: any[], nodeId, level = 2) => {
count
=
1
if
(
performAThoroughValidation
(
item
.
children
))
{
// 找到后对比是否是期望的层级
if
(
count
>=
level
)
return
true
if
(
count
>=
level
)
{
return
true
}
}
}
return
false
}
/**
* 获取节点的完整结构
* @param tree 树数据
...
...
@@ -369,7 +377,10 @@ export const treeToString = (tree: any[], nodeId) => {
str
+=
`/
${
item
.
name
}
`
return
true
}
else
if
(
typeof
item
.
children
!==
'undefined'
&&
item
.
children
.
length
!==
0
)
{
performAThoroughValidation
(
item
.
children
)
str
+=
`/
${
item
.
name
}
`
if
(
performAThoroughValidation
(
item
.
children
))
{
return
true
}
}
}
return
false
...
...
src/views/mall/product/spu/addForm.vue
View file @
39c92cb9
...
...
@@ -5,6 +5,7 @@
<BasicInfoForm
ref=
"basicInfoRef"
v-model:activeName=
"activeName"
:is-detail=
"isDetail"
:propFormData=
"formData"
/>
</el-tab-pane>
...
...
@@ -12,6 +13,7 @@
<DescriptionForm
ref=
"descriptionRef"
v-model:activeName=
"activeName"
:is-detail=
"isDetail"
:propFormData=
"formData"
/>
</el-tab-pane>
...
...
@@ -19,6 +21,7 @@
<OtherSettingsForm
ref=
"otherSettingsRef"
v-model:activeName=
"activeName"
:is-detail=
"isDetail"
:propFormData=
"formData"
/>
</el-tab-pane>
...
...
@@ -42,11 +45,12 @@ import { convertToInteger, formatToFraction } from '@/utils'
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
{
push
,
currentRoute
}
=
useRouter
()
// 路由
const
{
params
}
=
useRoute
()
// 查询参数
const
{
params
,
name
}
=
useRoute
()
// 查询参数
const
{
delView
}
=
useTagsViewStore
()
// 视图操作
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
activeName
=
ref
(
'basicInfo'
)
// Tag 激活的窗口
const
isDetail
=
ref
(
false
)
// 是否查看详情
const
basicInfoRef
=
ref
<
ComponentRef
<
typeof
BasicInfoForm
>>
()
// 商品信息Ref
const
descriptionRef
=
ref
<
ComponentRef
<
typeof
DescriptionForm
>>
()
// 商品详情Ref
const
otherSettingsRef
=
ref
<
ComponentRef
<
typeof
OtherSettingsForm
>>
()
// 其他设置Ref
...
...
@@ -90,12 +94,13 @@ const formData = ref<ProductSpuApi.Spu>({
/** 获得详情 */
const
getDetail
=
async
()
=>
{
console
.
log
(
name
)
const
id
=
params
.
spuId
as
number
if
(
id
)
{
formLoading
.
value
=
true
try
{
const
res
=
(
await
ProductSpuApi
.
getSpu
(
id
))
as
ProductSpuApi
.
Spu
res
.
skus
.
forEach
((
item
)
=>
{
res
.
skus
!
.
forEach
((
item
)
=>
{
// 回显价格分转元
item
.
price
=
formatToFraction
(
item
.
price
)
item
.
marketPrice
=
formatToFraction
(
item
.
marketPrice
)
...
...
@@ -123,7 +128,7 @@ const submitForm = async () => {
// 深拷贝一份, 这样最终 server 端不满足,不需要恢复,
const
deepCopyFormData
=
cloneDeep
(
unref
(
formData
.
value
))
// 兜底处理 sku 空数据
formData
.
value
.
skus
.
forEach
((
sku
)
=>
{
formData
.
value
.
skus
!
.
forEach
((
sku
)
=>
{
// 因为是空数据这里判断一下商品条码是否为空就行
if
(
sku
.
barCode
===
''
)
{
const
index
=
deepCopyFormData
.
skus
.
findIndex
(
...
...
@@ -171,7 +176,6 @@ const close = () => {
delView
(
unref
(
currentRoute
))
push
(
'/product/product-spu'
)
}
/** 初始化 */
onMounted
(
async
()
=>
{
await
getDetail
()
...
...
src/views/mall/product/spu/components/BasicInfoForm.vue
View file @
39c92cb9
<
template
>
<el-form
ref=
"productSpuBasicInfoRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
v-if=
"!isDetail"
ref=
"productSpuBasicInfoRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"商品名称"
prop=
"name"
>
...
...
@@ -115,18 +121,72 @@
</el-row>
</el-form>
<ProductAttributesAddForm
ref=
"attributesAddFormRef"
:propertyList=
"propertyList"
/>
<!-- 详情跟表单放在一块可以共用已有功能,再抽离成组件有点过度封装的感觉 -->
<Descriptions
v-if=
"isDetail"
:data=
"formData"
:schema=
"allSchemas.detailSchema"
>
<
template
#
categoryId=
"{ row }"
>
{{
categoryString
(
row
.
categoryId
)
}}
</
template
>
<
template
#
brandId=
"{ row }"
>
{{
brandList
.
find
((
item
)
=>
item
.
id
===
row
.
brandId
)?.
name
}}
</
template
>
<
template
#
specType=
"{ row }"
>
{{
row
.
specType
?
'多规格'
:
'单规格'
}}
</
template
>
<
template
#
subCommissionType=
"{ row }"
>
{{
row
.
subCommissionType
?
'自行设置'
:
'默认设置'
}}
</
template
>
<
template
#
picUrl=
"{ row }"
>
<el-image
:src=
"row.picUrl"
class=
"w-60px h-60px"
@
click=
"imagePreview(row.picUrl)"
/>
</
template
>
<
template
#
sliderPicUrls=
"{ row }"
>
<el-image
v-for=
"(item, index) in row.sliderPicUrls"
:key=
"index"
:src=
"item.url"
class=
"w-60px h-60px mr-10px"
@
click=
"imagePreview(row.sliderPicUrls)"
/>
</
template
>
<
template
#
skus
>
<SkuList
ref=
"skuDetailListRef"
:is-detail=
"isDetail"
:prop-form-data=
"formData"
:propertyList=
"propertyList"
/>
</
template
>
</Descriptions>
</template>
<
script
lang=
"ts"
name=
"ProductSpuBasicInfoForm"
setup
>
import
{
PropType
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
checkSelectedNode
,
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
{
checkSelectedNode
,
defaultProps
,
handleTree
,
treeToString
}
from
'@/utils/tree'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
type
{
Spu
}
from
'@/api/mall/product/spu'
import
{
UploadImg
,
UploadImgs
}
from
'@/components/UploadFile'
import
{
ProductAttributes
,
ProductAttributesAddForm
,
SkuList
}
from
'./index'
import
{
basicInfoSchema
}
from
'./spu.data'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
import
*
as
ProductCategoryApi
from
'@/api/mall/product/category'
import
{
getSimpleBrandList
}
from
'@/api/mall/product/brand'
import
{
isArray
}
from
'@/utils/is'
// ====== 商品详情相关操作 ======
const
{
allSchemas
}
=
useCrudSchemas
(
basicInfoSchema
)
/** 商品图预览 */
const
imagePreview
=
(
args
)
=>
{
const
urlList
=
[]
if
(
isArray
(
args
))
{
args
.
forEach
((
item
)
=>
{
urlList
.
push
(
item
.
url
)
})
}
else
{
urlList
.
push
(
args
)
}
createImageViewer
({
urlList
})
}
// ====== end ======
const
message
=
useMessage
()
// 消息弹窗
...
...
@@ -135,7 +195,8 @@ const props = defineProps({
type
:
Object
as
PropType
<
Spu
>
,
default
:
()
=>
{}
},
activeName
:
propTypes
.
string
.
def
(
''
)
activeName
:
propTypes
.
string
.
def
(
''
),
isDetail
:
propTypes
.
bool
.
def
(
false
)
// 是否作为详情组件
})
const
attributesAddFormRef
=
ref
()
// 添加商品属性表单
const
productSpuBasicInfoRef
=
ref
()
// 表单 Ref
...
...
@@ -149,11 +210,11 @@ const formData = reactive<Spu>({
name
:
''
,
// 商品名称
categoryId
:
null
,
// 商品分类
keyword
:
''
,
// 关键字
unit
:
''
,
// 单位
unit
:
null
,
// 单位
picUrl
:
''
,
// 商品封面图
sliderPicUrls
:
[],
// 商品轮播图
introduction
:
''
,
// 商品简介
deliveryTemplateId
:
1
,
// 运费模版
deliveryTemplateId
:
null
,
// 运费模版
brandId
:
null
,
// 商品品牌
specType
:
false
,
// 商品规格
subCommissionType
:
false
,
// 分销类型
...
...
@@ -273,9 +334,16 @@ const categoryList = ref([]) // 分类树
const
nodeClick
=
()
=>
{
if
(
!
checkSelectedNode
(
categoryList
.
value
,
formData
.
categoryId
))
{
formData
.
categoryId
=
null
message
.
warning
(
'必须选择二级节点!!'
)
message
.
warning
(
'必须选择二级
及以下
节点!!'
)
}
}
/**
* 获取分类的节点的完整结构
* @param categoryId 分类id
*/
const
categoryString
=
(
categoryId
)
=>
{
return
treeToString
(
categoryList
.
value
,
categoryId
)
}
const
brandList
=
ref
([])
// 精简商品品牌列表
onMounted
(
async
()
=>
{
// 获得分类树
...
...
src/views/mall/product/spu/components/DescriptionForm.vue
View file @
39c92cb9
<
template
>
<el-form
ref=
"descriptionFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
v-if=
"!isDetail"
ref=
"descriptionFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<!--富文本编辑器组件-->
<el-form-item
label=
"商品详情"
prop=
"description"
>
<Editor
v-model:modelValue=
"formData.description"
/>
</el-form-item>
</el-form>
<Descriptions
v-if=
"isDetail"
:data=
"formData"
:schema=
"allSchemas.detailSchema"
class=
"descriptionFormDescriptions"
>
<!-- 展示 HTML 内容 -->
<template
#
description=
"
{ row }">
<div
style=
"width: 600px"
v-html=
"row.description"
></div>
</
template
>
</Descriptions>
</template>
<
script
lang=
"ts"
name=
"DescriptionForm"
setup
>
import
type
{
Spu
}
from
'@/api/mall/product/spu'
...
...
@@ -12,6 +29,9 @@ import { Editor } from '@/components/Editor'
import
{
PropType
}
from
'vue'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
descriptionSchema
}
from
'./spu.data'
const
{
allSchemas
}
=
useCrudSchemas
(
descriptionSchema
)
const
message
=
useMessage
()
// 消息弹窗
const
props
=
defineProps
({
...
...
@@ -19,7 +39,8 @@ const props = defineProps({
type
:
Object
as
PropType
<
Spu
>
,
default
:
()
=>
{}
},
activeName
:
propTypes
.
string
.
def
(
''
)
activeName
:
propTypes
.
string
.
def
(
''
),
isDetail
:
propTypes
.
bool
.
def
(
false
)
// 是否作为详情组件
})
const
descriptionFormRef
=
ref
()
// 表单Ref
const
formData
=
ref
<
Spu
>
({
...
...
src/views/mall/product/spu/components/OtherSettingsForm.vue
View file @
39c92cb9
<
template
>
<el-form
ref=
"otherSettingsFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
v-if=
"!isDetail"
ref=
"otherSettingsFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-row>
<el-col
:span=
"24"
>
<el-row
:gutter=
"20"
>
...
...
@@ -50,12 +56,38 @@
</el-col>
</el-row>
</el-form>
<Descriptions
v-if=
"isDetail"
:data=
"formData"
:schema=
"allSchemas.detailSchema"
>
<template
#
recommendHot=
"
{ row }">
{{
row
.
recommendHot
?
'是'
:
'否'
}}
</
template
>
<
template
#
recommendBenefit=
"{ row }"
>
{{
row
.
recommendBenefit
?
'是'
:
'否'
}}
</
template
>
<
template
#
recommendBest=
"{ row }"
>
{{
row
.
recommendBest
?
'是'
:
'否'
}}
</
template
>
<
template
#
recommendNew=
"{ row }"
>
{{
row
.
recommendNew
?
'是'
:
'否'
}}
</
template
>
<
template
#
recommendGood=
"{ row }"
>
{{
row
.
recommendGood
?
'是'
:
'否'
}}
</
template
>
<
template
#
activityOrders
>
<el-tag>
默认
</el-tag>
<el-tag
class=
"ml-2"
type=
"success"
>
秒杀
</el-tag>
<el-tag
class=
"ml-2"
type=
"info"
>
砍价
</el-tag>
<el-tag
class=
"ml-2"
type=
"warning"
>
拼团
</el-tag>
</
template
>
</Descriptions>
</template>
<
script
lang=
"ts"
name=
"OtherSettingsForm"
setup
>
import
type
{
Spu
}
from
'@/api/mall/product/spu'
import
{
PropType
}
from
'vue'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
otherSettingsSchema
}
from
'./spu.data'
const
{
allSchemas
}
=
useCrudSchemas
(
otherSettingsSchema
)
const
message
=
useMessage
()
// 消息弹窗
...
...
@@ -64,7 +96,8 @@ const props = defineProps({
type
:
Object
as
PropType
<
Spu
>
,
default
:
()
=>
{}
},
activeName
:
propTypes
.
string
.
def
(
''
)
activeName
:
propTypes
.
string
.
def
(
''
),
isDetail
:
propTypes
.
bool
.
def
(
false
)
// 是否作为详情组件
})
const
otherSettingsFormRef
=
ref
()
// 表单Ref
...
...
src/views/mall/product/spu/components/SkuList.vue
View file @
39c92cb9
<
template
>
<el-table
v-if=
"!isDetail"
:data=
"isBatch ? skuList : formData!.skus"
border
class=
"tabNumWidth"
...
...
@@ -21,8 +22,8 @@
min-width=
"120"
>
<template
#
default=
"
{ row }">
<!-- TODO puhui999:展示成蓝色,有点区分度哈 fix
: 字体加粗,颜色使用 #99a9bf 蓝色有点不好看哈哈
-->
<span
style=
"font-weight: bold; color: #
99a9b
f"
>
<!-- TODO puhui999:展示成蓝色,有点区分度哈 fix-->
<span
style=
"font-weight: bold; color: #
40aaf
f"
>
{{
row
.
properties
[
index
]?.
valueName
}}
</span>
</
template
>
...
...
@@ -108,6 +109,84 @@
</
template
>
</el-table-column>
</el-table>
<el-table
v-if=
"isDetail"
:data=
"formData!.skus"
border
max-height=
"500"
size=
"small"
style=
"width: 99%"
>
<el-table-column
align=
"center"
label=
"图片"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
<el-image
:src=
"row.picUrl"
class=
"w-60px h-60px"
@
click=
"imagePreview(row.picUrl)"
/>
</
template
>
</el-table-column>
<
template
v-if=
"formData!.specType && !isBatch"
>
<!-- 根据商品属性动态添加 -->
<el-table-column
v-for=
"(item, index) in tableHeaders"
:key=
"index"
:label=
"item.label"
align=
"center"
min-width=
"80"
>
<template
#
default=
"
{ row }">
<!-- TODO puhui999:展示成蓝色,有点区分度哈 fix-->
<span
style=
"font-weight: bold; color: #40aaff"
>
{{
row
.
properties
[
index
]?.
valueName
}}
</span>
</
template
>
</el-table-column>
</template>
<el-table-column
align=
"center"
label=
"商品条码"
min-width=
"100"
>
<
template
#
default=
"{ row }"
>
{{
row
.
barCode
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
price
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"市场价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
marketPrice
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"成本价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
costPrice
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
stock
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"重量(kg)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
weight
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"体积(m^3)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
volume
}}
</
template
>
</el-table-column>
<
template
v-if=
"formData!.subCommissionType"
>
<el-table-column
align=
"center"
label=
"一级返佣(元)"
min-width=
"80"
>
<template
#
default=
"
{ row }">
{{
row
.
subCommissionFirstPrice
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"二级返佣(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
subCommissionSecondPrice
}}
</
template
>
</el-table-column>
</template>
</el-table>
</template>
<
script
lang=
"ts"
name=
"SkuList"
setup
>
import
{
PropType
,
Ref
}
from
'vue'
...
...
@@ -115,6 +194,7 @@ import { copyValueToTarget } from '@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
UploadImg
}
from
'@/components/UploadFile'
import
type
{
Property
,
Sku
,
Spu
}
from
'@/api/mall/product/spu'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
const
props
=
defineProps
({
propFormData
:
{
...
...
@@ -125,7 +205,8 @@ const props = defineProps({
type
:
Array
,
default
:
()
=>
[]
},
isBatch
:
propTypes
.
bool
.
def
(
false
)
// 是否作为批量操作组件
isBatch
:
propTypes
.
bool
.
def
(
false
),
// 是否作为批量操作组件
isDetail
:
propTypes
.
bool
.
def
(
false
)
// 是否作为 sku 详情组件
})
const
formData
:
Ref
<
Spu
|
undefined
>
=
ref
<
Spu
>
()
// 表单数据
const
skuList
=
ref
<
Sku
[]
>
([
...
...
@@ -143,20 +224,27 @@ const skuList = ref<Sku[]>([
}
])
// 批量添加时的临时数据
/** 商品图预览 */
const
imagePreview
=
(
imgUrl
:
string
)
=>
{
createImageViewer
({
urlList
:
[
imgUrl
]
})
}
/** 批量添加 */
const
batchAdd
=
()
=>
{
formData
.
value
!
.
skus
.
forEach
((
item
)
=>
{
formData
.
value
!
.
skus
!
.
forEach
((
item
)
=>
{
copyValueToTarget
(
item
,
skuList
.
value
[
0
])
})
}
/** 删除 sku */
const
deleteSku
=
(
row
)
=>
{
const
index
=
formData
.
value
!
.
skus
.
findIndex
(
const
index
=
formData
.
value
!
.
skus
!
.
findIndex
(
// 直接把列表转成字符串比较
(
sku
)
=>
JSON
.
stringify
(
sku
.
properties
)
===
JSON
.
stringify
(
row
.
properties
)
)
formData
.
value
!
.
skus
.
splice
(
index
,
1
)
formData
.
value
!
.
skus
!
.
splice
(
index
,
1
)
}
const
tableHeaders
=
ref
<
{
prop
:
string
;
label
:
string
}[]
>
([])
// 多属性表头
/**
...
...
@@ -221,13 +309,13 @@ const generateTableData = (propertyList: any[]) => {
subCommissionSecondPrice
:
0
}
// 如果存在属性相同的 sku 则不做处理
const
index
=
formData
.
value
!
.
skus
.
findIndex
(
const
index
=
formData
.
value
!
.
skus
!
.
findIndex
(
(
sku
)
=>
JSON
.
stringify
(
sku
.
properties
)
===
JSON
.
stringify
(
row
.
properties
)
)
if
(
index
!==
-
1
)
{
continue
}
formData
.
value
!
.
skus
.
push
(
row
)
formData
.
value
!
.
skus
!
.
push
(
row
)
}
}
...
...
@@ -236,7 +324,7 @@ const generateTableData = (propertyList: any[]) => {
*/
const
validateData
=
(
propertyList
:
any
[])
=>
{
const
skuPropertyIds
=
[]
formData
.
value
!
.
skus
.
forEach
((
sku
)
=>
formData
.
value
!
.
skus
!
.
forEach
((
sku
)
=>
sku
.
properties
?.
map
((
property
)
=>
property
.
propertyId
)
.
forEach
((
propertyId
)
=>
{
...
...
src/views/mall/product/spu/components/spu.data.ts
0 → 100644
View file @
39c92cb9
import
{
CrudSchema
}
from
'@/hooks/web/useCrudSchemas'
export
const
basicInfoSchema
=
reactive
<
CrudSchema
[]
>
([
{
label
:
'商品名称'
,
field
:
'name'
},
{
label
:
'关键字'
,
field
:
'keyword'
},
{
label
:
'商品简介'
,
field
:
'introduction'
},
{
label
:
'商品分类'
,
field
:
'categoryId'
},
{
label
:
'商品品牌'
,
field
:
'brandId'
},
{
label
:
'商品封面图'
,
field
:
'picUrl'
},
{
label
:
'商品轮播图'
,
field
:
'sliderPicUrls'
},
{
label
:
'商品视频'
,
field
:
'videoUrl'
},
{
label
:
'单位'
,
field
:
'unit'
,
dictType
:
DICT_TYPE
.
PRODUCT_UNIT
},
{
label
:
'规格类型'
,
field
:
'specType'
},
{
label
:
'分销类型'
,
field
:
'subCommissionType'
},
{
label
:
'物流模版'
,
field
:
'deliveryTemplateId'
},
{
label
:
'商品属性列表'
,
field
:
'skus'
}
])
export
const
descriptionSchema
=
reactive
<
CrudSchema
[]
>
([
{
label
:
'商品详情'
,
field
:
'description'
}
])
export
const
otherSettingsSchema
=
reactive
<
CrudSchema
[]
>
([
{
label
:
'商品排序'
,
field
:
'sort'
},
{
label
:
'赠送积分'
,
field
:
'giveIntegral'
},
{
label
:
'虚拟销量'
,
field
:
'virtualSalesCount'
},
{
label
:
'是否热卖推荐'
,
field
:
'recommendHot'
},
{
label
:
'是否优惠推荐'
,
field
:
'recommendBenefit'
},
{
label
:
'是否精品推荐'
,
field
:
'recommendBest'
},
{
label
:
'是否新品推荐'
,
field
:
'recommendNew'
},
{
label
:
'是否优品推荐'
,
field
:
'recommendGood'
},
{
label
:
'赠送的优惠劵'
,
field
:
'giveCouponTemplateIds'
},
{
label
:
'活动显示排序'
,
field
:
'activityOrders'
}
])
src/views/mall/product/spu/index.vue
View file @
39c92cb9
...
...
@@ -171,8 +171,13 @@
</el-table-column>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<!-- TODO @puhui999:【详情】,可以后面点做哈 -->
<el-button
v-hasPermi=
"['product:spu:update']"
link
type=
"primary"
@
click=
"openDetail"
>
<!-- TODO @puhui999:【详情】,可以后面点做哈 fix-->
<el-button
v-hasPermi=
"['product:spu:update']"
link
type=
"primary"
@
click=
"openDetail(row.id)"
>
详情
</el-button>
<template
v-if=
"queryParams.tabType === 4"
>
...
...
@@ -284,12 +289,14 @@ const getTabsCount = async () => {
const
queryParams
=
ref
({
pageNo
:
1
,
pageSize
:
10
,
tabType
:
0
tabType
:
0
,
name
:
''
,
categoryId
:
null
})
// 查询参数
const
queryFormRef
=
ref
()
// 搜索的表单Ref
const
handleTabClick
=
(
tab
:
TabsPaneContext
)
=>
{
queryParams
.
value
.
tabType
=
tab
.
paneName
queryParams
.
value
.
tabType
=
tab
.
paneName
as
number
getList
()
}
...
...
@@ -400,8 +407,8 @@ const openForm = (id?: number) => {
/**
* 查看商品详情
*/
const
openDetail
=
()
=>
{
message
.
alert
(
'查看详情未完善!!!'
)
const
openDetail
=
(
id
?:
number
)
=>
{
push
(
'/product/productSpuDetail'
+
id
)
}
/** 导出按钮操作 */
...
...
@@ -436,12 +443,12 @@ const categoryString = (categoryId) => {
return
treeToString
(
categoryList
.
value
,
categoryId
)
}
/**
* 校验所选是否为二级节点
* 校验所选是否为二级
及以下
节点
*/
const
nodeClick
=
()
=>
{
if
(
!
checkSelectedNode
(
categoryList
.
value
,
queryParams
.
value
.
categoryId
))
{
queryParams
.
value
.
categoryId
=
null
message
.
warning
(
'必须选择二级节点!!'
)
message
.
warning
(
'必须选择二级
及以下
节点!!'
)
}
}
/** 初始化 **/
...
...
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