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
e9bb9403
authored
Jul 08, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【优化】spu:新增商品属性属性值为空校验
parent
96a499a8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
37 additions
and
25 deletions
+37
-25
src/views/mall/product/spu/components/SkuList.vue
+24
-12
src/views/mall/product/spu/form/ProductAttributes.vue
+6
-6
src/views/mall/product/spu/form/SkuForm.vue
+7
-7
No files found.
src/views/mall/product/spu/components/SkuList.vue
View file @
e9bb9403
...
@@ -292,6 +292,7 @@ import { createImageViewer } from '@/components/ImageViewer'
...
@@ -292,6 +292,7 @@ import { createImageViewer } from '@/components/ImageViewer'
import
{
RuleConfig
}
from
'@/views/mall/product/spu/components/index'
import
{
RuleConfig
}
from
'@/views/mall/product/spu/components/index'
import
{
PropertyAndValues
}
from
'./index'
import
{
PropertyAndValues
}
from
'./index'
import
{
ElTable
}
from
'element-plus'
import
{
ElTable
}
from
'element-plus'
import
{
isEmpty
}
from
'@/utils/is'
defineOptions
({
name
:
'SkuList'
})
defineOptions
({
name
:
'SkuList'
})
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
...
@@ -340,11 +341,22 @@ const imagePreview = (imgUrl: string) => {
...
@@ -340,11 +341,22 @@ const imagePreview = (imgUrl: string) => {
/** 批量添加 */
/** 批量添加 */
const
batchAdd
=
()
=>
{
const
batchAdd
=
()
=>
{
validateProperty
()
formData
.
value
!
.
skus
!
.
forEach
((
item
)
=>
{
formData
.
value
!
.
skus
!
.
forEach
((
item
)
=>
{
copyValueToTarget
(
item
,
skuList
.
value
[
0
])
copyValueToTarget
(
item
,
skuList
.
value
[
0
])
})
})
}
}
/** 校验商品属性属性值 */
const
validateProperty
=
()
=>
{
// 校验商品属性属性值是否为空,有一个为空都不给过
const
warningInfo
=
'存在属性属性值为空,请先检查完善属性值后重试!!!'
for
(
const
item
of
props
.
propertyList
)
{
if
(
!
item
.
values
||
isEmpty
(
item
.
values
))
{
message
.
warning
(
warningInfo
)
throw
new
Error
(
warningInfo
)
}
}
}
/** 删除 sku */
/** 删除 sku */
const
deleteSku
=
(
row
)
=>
{
const
deleteSku
=
(
row
)
=>
{
const
index
=
formData
.
value
!
.
skus
!
.
findIndex
(
const
index
=
formData
.
value
!
.
skus
!
.
findIndex
(
...
@@ -358,6 +370,7 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表
...
@@ -358,6 +370,7 @@ const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
*/
*/
const
validateSku
=
()
=>
{
const
validateSku
=
()
=>
{
validateProperty
()
let
warningInfo
=
'请检查商品各行相关属性配置,'
let
warningInfo
=
'请检查商品各行相关属性配置,'
let
validate
=
true
// 默认通过
let
validate
=
true
// 默认通过
for
(
const
sku
of
formData
.
value
!
.
skus
!
)
{
for
(
const
sku
of
formData
.
value
!
.
skus
!
)
{
...
@@ -421,7 +434,7 @@ watch(
...
@@ -421,7 +434,7 @@ watch(
const
generateTableData
=
(
propertyList
:
any
[])
=>
{
const
generateTableData
=
(
propertyList
:
any
[])
=>
{
// 构建数据结构
// 构建数据结构
const
propertyValues
=
propertyList
.
map
((
item
)
=>
const
propertyValues
=
propertyList
.
map
((
item
)
=>
item
.
values
.
map
((
v
)
=>
({
item
.
values
.
map
((
v
:
any
)
=>
({
propertyId
:
item
.
id
,
propertyId
:
item
.
id
,
propertyName
:
item
.
name
,
propertyName
:
item
.
name
,
valueId
:
v
.
id
,
valueId
:
v
.
id
,
...
@@ -464,15 +477,14 @@ const generateTableData = (propertyList: any[]) => {
...
@@ -464,15 +477,14 @@ const generateTableData = (propertyList: any[]) => {
*/
*/
const
validateData
=
(
propertyList
:
any
[])
=>
{
const
validateData
=
(
propertyList
:
any
[])
=>
{
const
skuPropertyIds
:
number
[]
=
[]
const
skuPropertyIds
:
number
[]
=
[]
formData
.
value
!
.
skus
!
.
forEach
(
formData
.
value
!
.
skus
!
.
forEach
((
sku
)
=>
(
sku
)
=>
sku
.
properties
sku
.
properties
?.
map
((
property
)
=>
property
.
propertyId
)
?.
map
((
property
)
=>
property
.
propertyId
)
?.
forEach
((
propertyId
)
=>
{
?.
forEach
((
propertyId
)
=>
{
if
(
skuPropertyIds
.
indexOf
(
propertyId
!
)
===
-
1
)
{
if
(
skuPropertyIds
.
indexOf
(
propertyId
!
)
===
-
1
)
{
skuPropertyIds
.
push
(
propertyId
!
)
skuPropertyIds
.
push
(
propertyId
!
)
}
}
})
})
)
)
const
propertyIds
=
propertyList
.
map
((
item
)
=>
item
.
id
)
const
propertyIds
=
propertyList
.
map
((
item
)
=>
item
.
id
)
return
skuPropertyIds
.
length
===
propertyIds
.
length
return
skuPropertyIds
.
length
===
propertyIds
.
length
...
@@ -543,7 +555,7 @@ watch(
...
@@ -543,7 +555,7 @@ watch(
return
return
}
}
// 添加新属性没有属性值也不做处理
// 添加新属性没有属性值也不做处理
if
(
propertyList
.
some
((
item
)
=>
item
.
values
!
.
length
===
0
))
{
if
(
propertyList
.
some
((
item
)
=>
!
item
.
values
||
isEmpty
(
item
.
values
)
))
{
return
return
}
}
// 生成 table 数据,即 sku 列表
// 生成 table 数据,即 sku 列表
...
...
src/views/mall/product/spu/form/ProductAttributes.vue
View file @
e9bb9403
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
<el-col
v-for=
"(item, index) in attributeList"
:key=
"index"
>
<el-col
v-for=
"(item, index) in attributeList"
:key=
"index"
>
<div>
<div>
<el-text
class=
"mx-1"
>
属性名:
</el-text>
<el-text
class=
"mx-1"
>
属性名:
</el-text>
<el-tag
class=
"mx-1"
:closable=
"!isDetail
"
type=
"success"
@
close=
"handleCloseProperty(index)"
>
<el-tag
:closable=
"!isDetail"
class=
"mx-1
"
type=
"success"
@
close=
"handleCloseProperty(index)"
>
{{
item
.
name
}}
{{
item
.
name
}}
</el-tag>
</el-tag>
</div>
</div>
...
@@ -12,8 +12,8 @@
...
@@ -12,8 +12,8 @@
<el-tag
<el-tag
v-for=
"(value, valueIndex) in item.values"
v-for=
"(value, valueIndex) in item.values"
:key=
"value.id"
:key=
"value.id"
class=
"mx-1"
:closable=
"!isDetail"
:closable=
"!isDetail"
class=
"mx-1"
@
close=
"handleCloseValue(index, valueIndex)"
@
close=
"handleCloseValue(index, valueIndex)"
>
>
{{
value
.
name
}}
{{
value
.
name
}}
...
@@ -44,7 +44,6 @@
...
@@ -44,7 +44,6 @@
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
ElInput
}
from
'element-plus'
import
{
ElInput
}
from
'element-plus'
import
*
as
PropertyApi
from
'@/api/mall/product/property'
import
*
as
PropertyApi
from
'@/api/mall/product/property'
import
{
PropertyVO
}
from
'@/api/mall/product/property'
import
{
PropertyAndValues
}
from
'@/views/mall/product/spu/components'
import
{
PropertyAndValues
}
from
'@/views/mall/product/spu/components'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
propTypes
}
from
'@/utils/propTypes'
...
@@ -59,9 +58,9 @@ const inputVisible = computed(() => (index: number) => {
...
@@ -59,9 +58,9 @@ const inputVisible = computed(() => (index: number) => {
if
(
attributeIndex
.
value
===
null
)
return
false
if
(
attributeIndex
.
value
===
null
)
return
false
if
(
attributeIndex
.
value
===
index
)
return
true
if
(
attributeIndex
.
value
===
index
)
return
true
})
})
const
inputRef
=
ref
([])
//标签输入框Ref
const
inputRef
=
ref
<
any
[]
>
([])
//标签输入框Ref
/** 解决 ref 在 v-for 中的获取问题*/
/** 解决 ref 在 v-for 中的获取问题*/
const
setInputRef
=
(
el
)
=>
{
const
setInputRef
=
(
el
:
any
)
=>
{
if
(
el
===
null
||
typeof
el
===
'undefined'
)
return
if
(
el
===
null
||
typeof
el
===
'undefined'
)
return
// 如果不存在 id 相同的元素才添加
// 如果不存在 id 相同的元素才添加
if
(
!
inputRef
.
value
.
some
((
item
)
=>
item
.
input
?.
attributes
.
id
===
el
.
input
?.
attributes
.
id
))
{
if
(
!
inputRef
.
value
.
some
((
item
)
=>
item
.
input
?.
attributes
.
id
===
el
.
input
?.
attributes
.
id
))
{
...
@@ -81,7 +80,7 @@ watch(
...
@@ -81,7 +80,7 @@ watch(
()
=>
props
.
propertyList
,
()
=>
props
.
propertyList
,
(
data
)
=>
{
(
data
)
=>
{
if
(
!
data
)
return
if
(
!
data
)
return
attributeList
.
value
=
data
attributeList
.
value
=
data
as
any
},
},
{
{
deep
:
true
,
deep
:
true
,
...
@@ -97,6 +96,7 @@ const handleCloseValue = (index: number, valueIndex: number) => {
...
@@ -97,6 +96,7 @@ const handleCloseValue = (index: number, valueIndex: number) => {
/** 删除属性*/
/** 删除属性*/
const
handleCloseProperty
=
(
index
:
number
)
=>
{
const
handleCloseProperty
=
(
index
:
number
)
=>
{
attributeList
.
value
?.
splice
(
index
,
1
)
attributeList
.
value
?.
splice
(
index
,
1
)
emit
(
'success'
,
attributeList
.
value
)
}
}
/** 显示输入框并获取焦点 */
/** 显示输入框并获取焦点 */
...
...
src/views/mall/product/spu/form/SkuForm.vue
View file @
e9bb9403
<!-- 商品发布 - 库存价格 -->
<!-- 商品发布 - 库存价格 -->
<
template
>
<
template
>
<el-form
ref=
"formRef"
:
model=
"formData"
:rules=
"rules"
label-width=
"120px"
:disabled=
"isDetail
"
>
<el-form
ref=
"formRef"
:
disabled=
"isDetail"
:model=
"formData"
:rules=
"rules"
label-width=
"120px
"
>
<el-form-item
label=
"分销类型"
props=
"subCommissionType"
>
<el-form-item
label=
"分销类型"
props=
"subCommissionType"
>
<el-radio-group
<el-radio-group
v-model=
"formData.subCommissionType"
v-model=
"formData.subCommissionType"
@
change=
"changeSubCommissionType"
class=
"w-80"
class=
"w-80"
@
change=
"changeSubCommissionType"
>
>
<el-radio
:label=
"false"
>
默认设置
</el-radio>
<el-radio
:label=
"false"
>
默认设置
</el-radio>
<el-radio
:label=
"true"
class=
"radio"
>
单独设置
</el-radio>
<el-radio
:label=
"true"
class=
"radio"
>
单独设置
</el-radio>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"商品规格"
props=
"specType"
>
<el-form-item
label=
"商品规格"
props=
"specType"
>
<el-radio-group
v-model=
"formData.specType"
@
change=
"onChangeSpec"
class=
"w-80
"
>
<el-radio-group
v-model=
"formData.specType"
class=
"w-80"
@
change=
"onChangeSpec
"
>
<el-radio
:label=
"false"
class=
"radio"
>
单规格
</el-radio>
<el-radio
:label=
"false"
class=
"radio"
>
单规格
</el-radio>
<el-radio
:label=
"true"
>
多规格
</el-radio>
<el-radio
:label=
"true"
>
多规格
</el-radio>
</el-radio-group>
</el-radio-group>
...
@@ -29,22 +29,22 @@
...
@@ -29,22 +29,22 @@
<el-form-item
v-if=
"formData.specType"
label=
"商品属性"
>
<el-form-item
v-if=
"formData.specType"
label=
"商品属性"
>
<el-button
class=
"mb-10px mr-15px"
@
click=
"attributesAddFormRef.open"
>
添加属性
</el-button>
<el-button
class=
"mb-10px mr-15px"
@
click=
"attributesAddFormRef.open"
>
添加属性
</el-button>
<ProductAttributes
<ProductAttributes
:is-detail=
"isDetail"
:property-list=
"propertyList"
:property-list=
"propertyList"
@
success=
"generateSkus"
@
success=
"generateSkus"
:is-detail=
"isDetail"
/>
/>
</el-form-item>
</el-form-item>
<template
v-if=
"formData.specType && propertyList.length > 0"
>
<template
v-if=
"formData.specType && propertyList.length > 0"
>
<el-form-item
label=
"批量设置"
v-if=
"!isDetail
"
>
<el-form-item
v-if=
"!isDetail"
label=
"批量设置
"
>
<SkuList
:is-batch=
"true"
:prop-form-data=
"formData"
:property-list=
"propertyList"
/>
<SkuList
:is-batch=
"true"
:prop-form-data=
"formData"
:property-list=
"propertyList"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"规格列表"
>
<el-form-item
label=
"规格列表"
>
<SkuList
<SkuList
ref=
"skuListRef"
ref=
"skuListRef"
:is-detail=
"isDetail"
:prop-form-data=
"formData"
:prop-form-data=
"formData"
:property-list=
"propertyList"
:property-list=
"propertyList"
:rule-config=
"ruleConfig"
:rule-config=
"ruleConfig"
:is-detail=
"isDetail"
/>
/>
</el-form-item>
</el-form-item>
</
template
>
</
template
>
...
@@ -181,7 +181,7 @@ const onChangeSpec = () => {
...
@@ -181,7 +181,7 @@ const onChangeSpec = () => {
}
}
/** 调用 SkuList generateTableData 方法*/
/** 调用 SkuList generateTableData 方法*/
const
generateSkus
=
(
propertyList
)
=>
{
const
generateSkus
=
(
propertyList
:
any
[]
)
=>
{
skuListRef
.
value
.
generateTableData
(
propertyList
)
skuListRef
.
value
.
generateTableData
(
propertyList
)
}
}
</
script
>
</
script
>
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