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
38545e89
authored
May 20, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 优化相关逻辑,修复遗留bug
parent
0c42b76a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
76 additions
and
51 deletions
+76
-51
src/views/mall/product/spu/addForm.vue
+1
-21
src/views/mall/product/spu/components/BasicInfoForm.vue
+28
-12
src/views/mall/product/spu/components/ProductAttributes.vue
+25
-11
src/views/mall/product/spu/components/ProductAttributesAddForm.vue
+20
-3
src/views/mall/product/spu/components/SkuList.vue
+2
-4
No files found.
src/views/mall/product/spu/addForm.vue
View file @
38545e89
...
...
@@ -37,7 +37,6 @@ import { useTagsViewStore } from '@/store/modules/tagsView'
import
{
BasicInfoForm
,
DescriptionForm
,
OtherSettingsForm
}
from
'./components'
// 业务api
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
PropertyApi
from
'@/api/mall/product/property'
import
{
convertToInteger
,
formatToFraction
}
from
'@/utils'
const
{
t
}
=
useI18n
()
// 国际化
...
...
@@ -105,25 +104,6 @@ const getDetail = async () => {
item
.
subCommissionSecondPrice
=
formatToFraction
(
item
.
subCommissionSecondPrice
)
})
formData
.
value
=
res
// 只有是多规格才处理
if
(
res
.
specType
)
{
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
// fix: 考虑到 sku 数量和通过属性算出来的sku不一致的情况
const
propertyIds
=
[]
res
.
skus
.
forEach
((
sku
)
=>
sku
.
properties
?.
map
((
property
)
=>
property
.
propertyId
)
.
forEach
((
propertyId
)
=>
{
if
(
propertyIds
.
indexOf
(
propertyId
)
===
-
1
)
{
propertyIds
.
push
(
propertyId
)
}
})
)
const
properties
=
await
PropertyApi
.
getPropertyListAndValue
({
propertyIds
})
await
nextTick
()
// 回显商品属性
basicInfoRef
.
value
.
addAttribute
(
properties
)
}
}
finally
{
formLoading
.
value
=
false
}
...
...
@@ -141,7 +121,7 @@ const submitForm = async () => {
await
unref
(
descriptionRef
)?.
validate
()
await
unref
(
otherSettingsRef
)?.
validate
()
const
deepCopyFormData
=
cloneDeep
(
unref
(
formData
.
value
))
// 深拷贝一份 fix:这样最终 server 端不满足,不需要恢复,
// TODO 兜底处理 sku 空数据
详见 SkuList TODO
// TODO 兜底处理 sku 空数据
formData
.
value
.
skus
.
forEach
((
sku
)
=>
{
// 因为是空数据这里判断一下商品条码是否为空就行
if
(
sku
.
barCode
===
''
)
{
...
...
src/views/mall/product/spu/components/BasicInfoForm.vue
View file @
38545e89
...
...
@@ -98,14 +98,14 @@
<el-form-item
v-if=
"formData.specType"
label=
"商品属性"
>
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈 fix-->
<el-button
class=
"mr-15px mb-10px"
@
click=
"attributesAddFormRef.open"
>
添加规格
</el-button>
<ProductAttributes
:propertyList=
"propertyList"
/>
<ProductAttributes
:propertyList=
"propertyList"
@
success=
"generateSkus"
/>
</el-form-item>
<template
v-if=
"formData.specType && propertyList.length > 0"
>
<el-form-item
label=
"批量设置"
>
<SkuList
:is-batch=
"true"
:prop-form-data=
"formData"
:propertyList=
"propertyList"
/>
</el-form-item>
<el-form-item
label=
"属性列表"
>
<SkuList
:prop-form-data=
"formData"
:propertyList=
"propertyList"
/>
<SkuList
ref=
"skuListRef"
:prop-form-data=
"formData"
:propertyList=
"propertyList"
/>
</el-form-item>
</
template
>
<el-form-item
v-if=
"!formData.specType"
>
...
...
@@ -114,7 +114,7 @@
</el-col>
</el-row>
</el-form>
<ProductAttributesAddForm
ref=
"attributesAddFormRef"
@
success=
"addAttribute
"
/>
<ProductAttributesAddForm
ref=
"attributesAddFormRef"
:propertyList=
"propertyList
"
/>
</template>
<
script
lang=
"ts"
name=
"ProductSpuBasicInfoForm"
setup
>
import
{
PropType
}
from
'vue'
...
...
@@ -141,15 +141,11 @@ const attributesAddFormRef = ref() // 添加商品属性表单 TODO @puhui999:
const
productSpuBasicInfoRef
=
ref
()
// 表单Ref TODO @puhui999:小写开头哈 fix
// TODO @puhui999:attributeList 改成 propertyList,会更统一一点 fix
const
propertyList
=
ref
([])
// 商品属性列表
/** 添加商品属性 */
// TODO @puhui999:propFormData 算出来 fix: 因为ProductAttributesAddForm添加属性成功回调得使用不能完全依赖于propFormData
const
addAttribute
=
(
property
:
any
)
=>
{
Array
.
isArray
(
property
)
?
(
propertyList
.
value
=
property
)
:
propertyList
.
value
.
push
(
property
)
}
const
skuListRef
=
ref
()
// 商品属性列表Ref
/** 调用 SkuList generateTableData 方法*/
// const generateSkus(propertyList)
{
// skuList.value.generateTableData(
)
//
}
const
generateSkus
=
(
propertyList
)
=>
{
skuListRef
.
value
.
generateTableData
(
propertyList
)
}
const
formData
=
reactive
<
SpuType
>
({
name
:
''
,
// 商品名称
categoryId
:
null
,
// 商品分类
...
...
@@ -191,6 +187,26 @@ watch(
formData
.
sliderPicUrls
=
data
[
'sliderPicUrls'
].
map
((
item
)
=>
({
url
:
item
}))
// 只有是多规格才处理
if
(
formData
.
specType
)
{
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
// fix: 直接拿返回的 skus 属性逆向生成出 propertyList
const
properties
=
[]
formData
.
skus
.
forEach
((
sku
)
=>
{
sku
.
properties
.
forEach
(({
propertyId
,
propertyName
,
valueId
,
valueName
})
=>
{
// 添加属性
if
(
!
properties
.
some
((
item
)
=>
item
.
id
===
propertyId
))
{
properties
.
push
({
id
:
propertyId
,
name
:
propertyName
,
values
:
[]
})
}
// 添加属性值
const
index
=
properties
.
findIndex
((
item
)
=>
item
.
id
===
propertyId
)
if
(
!
properties
[
index
].
values
.
some
((
value
)
=>
value
.
id
===
valueId
))
{
properties
[
index
].
values
.
push
({
id
:
valueId
,
name
:
valueName
})
}
})
})
propertyList
.
value
=
properties
}
},
{
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
...
...
@@ -217,7 +233,7 @@ const validate = async () => {
}
})
}
defineExpose
({
validate
,
addAttribute
})
defineExpose
({
validate
})
/** 分销类型 */
const
changeSubCommissionType
=
()
=>
{
...
...
src/views/mall/product/spu/components/ProductAttributes.vue
View file @
38545e89
...
...
@@ -2,23 +2,25 @@
<el-col
v-for=
"(item, index) in attributeList"
:key=
"index"
>
<div>
<el-text
class=
"mx-1"
>
属性名:
</el-text>
<el-text
class=
"mx-1"
>
{{
item
.
name
}}
</el-text>
<el-tag
class=
"mx-1"
closable
type=
"success"
@
close=
"handleCloseProperty(index)"
>
{{
item
.
name
}}
</el-tag>
</div>
<div>
<el-text
class=
"mx-1"
>
属性值:
</el-text>
<el-tag
v-for=
"(value, valueIndex) in item.values"
:key=
"value.id"
:disable-transitions=
"false"
class=
"mx-1"
closable
@
close=
"handleClose(index, valueIndex)"
@
close=
"handleClose
Value
(index, valueIndex)"
>
{{
value
.
name
}}
</el-tag>
<el-input
v-show=
"inputVisible(index)"
ref=
"InputRef"
:id=
"`input$
{index}`"
:ref="setInputRef"
v-model="inputValue"
class="!w-20"
size="small"
...
...
@@ -51,7 +53,15 @@ const inputVisible = computed(() => (index) => {
if
(
attributeIndex
.
value
===
null
)
return
false
if
(
attributeIndex
.
value
===
index
)
return
true
})
const
InputRef
=
ref
()
//标签输入框Ref
const
inputRef
=
ref
([])
//标签输入框Ref
/** 解决 ref 在 v-for 中的获取问题*/
const
setInputRef
=
(
el
)
=>
{
if
(
el
===
null
||
typeof
el
===
'undefined'
)
return
// 如果不存在id相同的元素才添加
if
(
!
inputRef
.
value
.
some
((
item
)
=>
item
.
input
?.
attributes
.
id
===
el
.
input
?.
attributes
.
id
))
{
inputRef
.
value
.
push
(
el
)
}
}
const
attributeList
=
ref
([])
// 商品属性列表
const
props
=
defineProps
({
propertyList
:
{
...
...
@@ -72,19 +82,22 @@ watch(
}
)
/** 删除
标签 tagValue 标签
值*/
const
handleClose
=
(
index
,
valueIndex
)
=>
{
/** 删除
属性
值*/
const
handleClose
Value
=
(
index
,
valueIndex
)
=>
{
attributeList
.
value
[
index
].
values
?.
splice
(
valueIndex
,
1
)
}
/** 删除属性*/
const
handleCloseProperty
=
(
index
)
=>
{
attributeList
.
value
?.
splice
(
index
,
1
)
}
/** 显示输入框并获取焦点 */
const
showInput
=
async
(
index
)
=>
{
attributeIndex
.
value
=
index
// TODO 嗯!!!自动获取焦点还是有点问题,后续继续改进
// 因为组件在ref中所以需要用索引获取对应的Ref
InputRef
.
value
[
index
]
!
.
input
!
.
focus
()
inputRef
.
value
[
index
].
focus
()
}
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
/** 输入框失去焦点或点击回车时触发 */
const
handleInputConfirm
=
async
(
index
,
propertyId
)
=>
{
if
(
inputValue
.
value
)
{
...
...
@@ -93,6 +106,7 @@ const handleInputConfirm = async (index, propertyId) => {
const
id
=
await
PropertyApi
.
createPropertyValue
({
propertyId
,
name
:
inputValue
.
value
})
attributeList
.
value
[
index
].
values
.
push
({
id
,
name
:
inputValue
.
value
})
message
.
success
(
t
(
'common.createSuccess'
))
emit
(
'success'
,
attributeList
.
value
)
}
catch
{
message
.
error
(
'添加失败,请重试'
)
// TODO 缺少国际化
}
...
...
src/views/mall/product/spu/components/ProductAttributesAddForm.vue
View file @
38545e89
...
...
@@ -33,7 +33,25 @@ const formRules = reactive({
name
:
[{
required
:
true
,
message
:
'名称不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
const
attributeList
=
ref
([])
// 商品属性列表
const
props
=
defineProps
({
propertyList
:
{
type
:
Array
,
default
:
()
=>
{}
}
})
watch
(
()
=>
props
.
propertyList
,
(
data
)
=>
{
if
(
!
data
)
return
attributeList
.
value
=
data
},
{
deep
:
true
,
immediate
:
true
}
)
/** 打开弹窗 */
const
open
=
async
()
=>
{
dialogVisible
.
value
=
true
...
...
@@ -42,7 +60,6 @@ const open = async () => {
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
if
(
!
formRef
)
return
...
...
@@ -56,12 +73,12 @@ const submitForm = async () => {
const
res
=
await
PropertyApi
.
getPropertyListAndValue
({
name
:
data
.
name
})
if
(
res
.
length
===
0
)
{
const
propertyId
=
await
PropertyApi
.
createProperty
(
data
)
emit
(
'success'
,
{
id
:
propertyId
,
...
formData
.
value
,
values
:
[]
})
attributeList
.
value
.
push
(
{
id
:
propertyId
,
...
formData
.
value
,
values
:
[]
})
}
else
{
if
(
res
[
0
].
values
===
null
)
{
res
[
0
].
values
=
[]
}
emit
(
'success'
,
res
[
0
])
// 因为只用一个
attributeList
.
value
.
push
(
res
[
0
])
// 因为只用一个
}
message
.
success
(
t
(
'common.createSuccess'
))
dialogVisible
.
value
=
false
...
...
src/views/mall/product/spu/components/SkuList.vue
View file @
38545e89
...
...
@@ -212,10 +212,6 @@ const generateTableData = (propertyList: any[]) => {
if
(
index
!==
-
1
)
{
continue
}
/**
* TODO 嗯。。有一个问题回显数据时已删除的 sku 会被重新添加暂时没想到好办法,保存时先手动重新删除一下因为是一条空数据很好辨别 不手动删也没是提交表单时会检测删除空sku来兜底
*
*/
formData
.
value
.
skus
.
push
(
row
)
}
}
...
...
@@ -302,4 +298,6 @@ watch(
immediate
:
true
}
)
// 暴露出生成 sku 方法给添加属性成功时调用 fix: 为了在只有一个属性下 spu 回显 skus 属性和和商品属性个数一致的情况下 添加属性值时添加 sku
defineExpose
({
generateTableData
})
</
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