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
4ddba9d4
authored
May 17, 2023
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 解决商品上一版遗留的各种小bug关键部分已添加fix注释。完成的TODO也已添加fix标记
parent
3c4a39df
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
135 additions
and
86 deletions
+135
-86
src/api/mall/product/spu.ts
+5
-0
src/components/UploadFile/src/UploadImgs.vue
+44
-14
src/router/modules/remaining.ts
+17
-4
src/views/mall/product/spu/addForm.vue
+0
-0
src/views/mall/product/spu/components/BasicInfoForm.vue
+29
-27
src/views/mall/product/spu/components/DescriptionForm.vue
+8
-9
src/views/mall/product/spu/components/OtherSettingsForm.vue
+14
-18
src/views/mall/product/spu/components/ProductAttributes.vue
+3
-2
src/views/mall/product/spu/components/SkuList.vue
+9
-9
src/views/mall/product/spu/index.vue
+6
-3
No files found.
src/api/mall/product/spu.ts
View file @
4ddba9d4
...
...
@@ -82,3 +82,8 @@ export const getSpu = (id: number) => {
export
const
deleteSpu
=
(
id
:
number
)
=>
{
return
request
.
delete
({
url
:
`/product/spu/delete?id=
${
id
}
`
})
}
// 导出商品 Spu
export
const
exportUser
=
(
params
)
=>
{
return
request
.
download
({
url
:
'/product/spu/export'
,
params
})
}
src/components/UploadFile/src/UploadImgs.vue
View file @
4ddba9d4
<
template
>
<div
class=
"upload-box"
>
<el-upload
v-model:file-list=
"fileList"
:accept=
"fileType.join(',')"
:action=
"updateUrl"
list-type=
"picture-car
d"
:before-upload=
"beforeUploa
d"
:class=
"['upload', drag ? 'no-border' : '']"
v-model:file-list=
"fileList"
:multiple=
"true"
:limit=
"limit"
:drag=
"drag"
:headers=
"uploadHeaders"
:before-upload=
"beforeUpload"
:limit=
"limit"
:multiple=
"true"
:on-error=
"uploadError"
:on-exceed=
"handleExceed"
:on-success=
"uploadSuccess"
:on-error=
"uploadError"
:drag=
"drag"
:accept=
"fileType.join(',')"
list-type=
"picture-card"
>
<div
class=
"upload-empty"
>
<slot
name=
"empty"
>
...
...
@@ -40,15 +40,15 @@
</div>
<el-image-viewer
v-if=
"imgViewVisible"
@
close=
"imgViewVisible = false"
:url-list=
"[viewImageUrl]"
@
close=
"imgViewVisible = false"
/>
</div>
</template>
<
script
setup
lang=
"ts"
name=
"UploadImgs"
>
<
script
lang=
"ts"
name=
"UploadImgs"
setup
>
import
{
PropType
}
from
'vue'
import
type
{
UploadFile
,
UploadProps
,
UploadUserFile
}
from
'element-plus'
import
{
ElNotification
}
from
'element-plus'
import
type
{
UploadProps
,
UploadFile
,
UploadUserFile
}
from
'element-plus'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
getAccessToken
,
getTenantId
}
from
'@/utils/auth'
...
...
@@ -88,8 +88,19 @@ const uploadHeaders = ref({
'tenant-id'
:
getTenantId
()
})
const
fileList
=
ref
<
UploadUserFile
[]
>
(
props
.
modelValue
)
const
fileList
=
ref
<
UploadUserFile
[]
>
()
// fix: 改为动态监听赋值解决图片回显问题
watch
(
()
=>
props
.
modelValue
,
(
data
)
=>
{
if
(
!
data
)
return
fileList
.
value
=
data
},
{
deep
:
true
,
immediate
:
true
}
)
/**
* @description 文件上传之前判断
* @param rawFile 上传的文件
...
...
@@ -116,9 +127,11 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
interface
UploadEmits
{
(
e
:
'update:modelValue'
,
value
:
UploadUserFile
[]):
void
}
const
emit
=
defineEmits
<
UploadEmits
>
()
const
uploadSuccess
=
(
response
,
uploadFile
:
UploadFile
)
=>
{
if
(
!
response
)
return
// TODO 多图上传组件成功后只是把保存成功后的url替换掉组件选图时的文件路径,所以返回的fileList包含的是一个包含文件信息的对象列表
uploadFile
.
url
=
response
.
data
emit
(
'update:modelValue'
,
fileList
.
value
)
message
.
success
(
'上传成功'
)
...
...
@@ -159,35 +172,40 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
}
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
lang=
"scss"
scoped
>
.is-error
{
.upload
{
:deep(.el-upload--picture-card),
:deep(.el-upload-dragger)
{
border
:
1px
dashed
var
(
--el-color-danger
)
!important
;
&:hover
{
border-color
:
var
(
--el-color-primary
)
!important
;
}
}
}
}
:deep
(
.disabled
)
{
.el-upload--picture-card,
.el-upload-dragger
{
cursor
:
not-allowed
;
background
:
var
(
--el-disabled-bg-color
)
!important
;
border
:
1px
dashed
var
(
--el-border-color-darker
);
&:hover
{
border-color
:
var
(
--el-border-color-darker
)
!important
;
}
}
}
.upload-box
{
.no-border
{
:deep(.el-upload--picture-card)
{
border
:
none
!important
;
}
}
:deep
(
.upload
)
{
.el-upload-dragger
{
display
:
flex
;
...
...
@@ -199,14 +217,17 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
overflow
:
hidden
;
border
:
1px
dashed
var
(
--el-border-color-darker
);
border-radius
:
v-bind
(
borderRadius
);
&:hover
{
border
:
1px
dashed
var
(
--el-color-primary
);
}
}
.el-upload-dragger.is-dragover
{
background-color
:
var
(
--el-color-primary-light-9
);
border
:
2px
dashed
var
(
--el-color-primary
)
!important
;
}
.el-upload-list__item
,
.el-upload--picture-card
{
width
:
v-bind
(
width
);
...
...
@@ -214,11 +235,13 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
background-color
:
transparent
;
border-radius
:
v-bind
(
borderRadius
);
}
.upload-image
{
width
:
100%
;
height
:
100%
;
object-fit
:
contain
;
}
.upload-handle
{
position
:
absolute
;
top
:
0
;
...
...
@@ -233,6 +256,7 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
background
:
rgb
(
0
0
0
/
60%
);
opacity
:
0
;
transition
:
var
(
--el-transition-duration-fast
);
.handle-icon
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -240,15 +264,18 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
justify-content
:
center
;
padding
:
0
6%
;
color
:
aliceblue
;
.el-icon
{
margin-bottom
:
15%
;
font-size
:
140%
;
}
span
{
font-size
:
100%
;
}
}
}
.el-upload-list__item
{
&:hover
{
.upload-handle
{
...
...
@@ -256,6 +283,7 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
}
}
}
.upload-empty
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -263,12 +291,14 @@ const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
font-size
:
12px
;
line-height
:
30px
;
color
:
var
(
--el-color-info
);
.el-icon
{
font-size
:
28px
;
color
:
var
(
--el-text-color-secondary
);
}
}
}
.el-upload__tip
{
line-height
:
15px
;
text-align
:
center
;
...
...
src/router/modules/remaining.ts
View file @
4ddba9d4
...
...
@@ -349,22 +349,35 @@ const remainingRouter: AppRouteRecordRaw[] = [
{
path
:
'/product'
,
component
:
Layout
,
name
:
'Product
ManagementEdit
'
,
name
:
'Product'
,
meta
:
{
hidden
:
true
},
children
:
[
{
path
:
'product
ManagementAdd'
,
// TODO @puhui999:最好拆成 add 和 edit 两个路由;添加商品;修改商品
path
:
'product
SpuAdd'
,
// TODO @puhui999:最好拆成 add 和 edit 两个路由;添加商品;修改商品 fix
component
:
()
=>
import
(
'@/views/mall/product/spu/addForm.vue'
),
name
:
'Product
Management
Add'
,
name
:
'Product
Spu
Add'
,
meta
:
{
noCache
:
true
,
hidden
:
true
,
canTo
:
true
,
icon
:
'ep:edit'
,
title
:
'添加商品'
,
activeMenu
:
'/product/product-management'
activeMenu
:
'/product/product-spu'
}
},
{
path
:
'productSpuEdit/:spuId(\\d+)'
,
component
:
()
=>
import
(
'@/views/mall/product/spu/addForm.vue'
),
name
:
'productSpuEdit'
,
meta
:
{
noCache
:
true
,
hidden
:
true
,
canTo
:
true
,
icon
:
'ep:edit'
,
title
:
'编辑商品'
,
activeMenu
:
'/product/product-spu'
}
}
]
...
...
src/views/mall/product/spu/addForm.vue
View file @
4ddba9d4
This diff is collapsed.
Click to expand it.
src/views/mall/product/spu/components/BasicInfoForm.vue
View file @
4ddba9d4
<
template
>
<el-form
ref=
"
ProductManagement
BasicInfoRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
ref=
"
productSpu
BasicInfoRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-row>
<el-col
:span=
"12"
>
<el-form-item
label=
"商品名称"
prop=
"name"
>
...
...
@@ -54,7 +54,7 @@
</el-col>
<el-col
:span=
"24"
>
<el-form-item
label=
"商品轮播图"
prop=
"sliderPicUrls"
>
<UploadImgs
v-model=
"formData.sliderPicUrls"
/>
<UploadImgs
v-model
:modelValue
=
"formData.sliderPicUrls"
/>
</el-form-item>
</el-col>
<el-col
:span=
"12"
>
...
...
@@ -86,36 +86,36 @@
<!-- 多规格添加-->
<el-col
:span=
"24"
>
<el-form-item
v-if=
"formData.specType"
label=
"商品属性"
>
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈 -->
<el-button
class=
"mr-15px mb-10px"
@
click=
"
A
ttributesAddFormRef.open"
>
添加规格
</el-button>
<ProductAttributes
:
attribute-data=
"attribute
List"
/>
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈
fix
-->
<el-button
class=
"mr-15px mb-10px"
@
click=
"
a
ttributesAddFormRef.open"
>
添加规格
</el-button>
<ProductAttributes
:
propertyList=
"property
List"
/>
</el-form-item>
<template
v-if=
"formData.specType &&
attribute
List.length > 0"
>
<template
v-if=
"formData.specType &&
property
List.length > 0"
>
<el-form-item
label=
"批量设置"
>
<SkuList
:
attributeList=
"attributeList"
:is-batch=
"true"
:prop-form-data=
"formData
"
/>
<SkuList
:
is-batch=
"true"
:prop-form-data=
"formData"
:propertyList=
"propertyList
"
/>
</el-form-item>
<el-form-item
label=
"属性列表"
>
<SkuList
:
attributeList=
"attributeList"
:prop-form-data=
"formData
"
/>
<SkuList
:
prop-form-data=
"formData"
:propertyList=
"propertyList
"
/>
</el-form-item>
</
template
>
<el-form-item
v-if=
"!formData.specType"
>
<SkuList
:
attributeList=
"attributeList"
:prop-form-data=
"formData
"
/>
<SkuList
:
prop-form-data=
"formData"
:propertyList=
"propertyList
"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<ProductAttributesAddForm
ref=
"
A
ttributesAddFormRef"
@
success=
"addAttribute"
/>
<ProductAttributesAddForm
ref=
"
a
ttributesAddFormRef"
@
success=
"addAttribute"
/>
</template>
<
script
lang=
"ts"
name=
"Product
Management
BasicInfoForm"
setup
>
<
script
lang=
"ts"
name=
"Product
Spu
BasicInfoForm"
setup
>
import
{
PropType
}
from
'vue'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
type
{
SpuType
}
from
'@/api/mall/product/
management/type/spuType
'
import
type
{
SpuType
}
from
'@/api/mall/product/
spu
'
import
{
UploadImg
,
UploadImgs
}
from
'@/components/UploadFile'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
ProductAttributes
,
ProductAttributesAddForm
,
SkuList
}
from
'./index'
import
*
as
ProductCategoryApi
from
'@/api/mall/product/category'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
copyValueToTarget
}
from
'@/utils'
const
message
=
useMessage
()
// 消息弹窗
...
...
@@ -126,17 +126,14 @@ const props = defineProps({
},
activeName
:
propTypes
.
string
.
def
(
''
)
})
const
AttributesAddFormRef
=
ref
()
// 添加商品属性表单 TODO @puhui999:小写开头哈
const
ProductManagementBasicInfoRef
=
ref
()
// 表单Ref TODO @puhui999:小写开头哈
// TODO @puhui999:attributeList 改成 propertyList,会更统一一点
const
attributeList
=
ref
([])
// 商品属性列表
/** 添加商品属性 */
// TODO @puhui999:propFormData 算出来
const
attributesAddFormRef
=
ref
()
// 添加商品属性表单 TODO @puhui999:小写开头哈 fix
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
)
=>
{
if
(
Array
.
isArray
(
property
))
{
attributeList
.
value
=
property
return
}
attributeList
.
value
.
push
(
property
)
Array
.
isArray
(
property
)
?
(
propertyList
.
value
=
property
)
:
propertyList
.
value
.
push
(
property
)
}
const
formData
=
reactive
<
SpuType
>
({
name
:
''
,
// 商品名称
...
...
@@ -171,10 +168,15 @@ watch(
()
=>
props
.
propFormData
,
(
data
)
=>
{
if
(
!
data
)
return
// fix:三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
copyValueToTarget
(
formData
,
data
)
// fix: 多图上传组件需要一个包含url属性的对象才能正常回显
formData
.
sliderPicUrls
=
data
[
'sliderPicUrls'
].
map
((
item
)
=>
({
url
:
item
}))
},
{
deep
:
true
,
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
immediate
:
true
}
)
...
...
@@ -185,8 +187,8 @@ watch(
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
ProductManagement
BasicInfoRef
)
return
return
await
unref
(
ProductManagement
BasicInfoRef
).
validate
((
valid
)
=>
{
if
(
!
productSpu
BasicInfoRef
)
return
return
await
unref
(
productSpu
BasicInfoRef
).
validate
((
valid
)
=>
{
if
(
!
valid
)
{
message
.
warning
(
'商品信息未完善!!'
)
emit
(
'update:activeName'
,
'basicInfo'
)
...
...
@@ -212,7 +214,7 @@ const changeSubCommissionType = () => {
/** 选择规格 */
const
onChangeSpec
=
()
=>
{
// 重置商品属性列表
attribute
List
.
value
=
[]
property
List
.
value
=
[]
// 重置sku列表
formData
.
skus
=
[
{
...
...
src/views/mall/product/spu/components/DescriptionForm.vue
View file @
4ddba9d4
<
template
>
<el-form
ref=
"
D
escriptionFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
ref=
"
d
escriptionFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<!--富文本编辑器组件-->
<el-form-item
label=
"商品详情"
prop=
"description"
>
<Editor
v-model:modelValue=
"formData.description"
/>
...
...
@@ -7,11 +7,11 @@
</el-form>
</
template
>
<
script
lang=
"ts"
name=
"DescriptionForm"
setup
>
import
type
{
SpuType
}
from
'@/api/mall/product/
management/type/spuType
'
import
type
{
SpuType
}
from
'@/api/mall/product/
spu
'
import
{
Editor
}
from
'@/components/Editor'
import
{
PropType
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
copyValueToTarget
}
from
'@/utils'
const
message
=
useMessage
()
// 消息弹窗
const
props
=
defineProps
({
...
...
@@ -21,7 +21,7 @@ const props = defineProps({
},
activeName
:
propTypes
.
string
.
def
(
''
)
})
const
D
escriptionFormRef
=
ref
()
// 表单Ref
const
d
escriptionFormRef
=
ref
()
// 表单Ref
const
formData
=
ref
<
SpuType
>
({
description
:
''
// 商品详情
})
...
...
@@ -29,7 +29,6 @@ const formData = ref<SpuType>({
const
rules
=
reactive
({
description
:
[
required
]
})
/**
* 富文本编辑器如果输入过再清空会有残留,需再重置一次
*/
...
...
@@ -45,7 +44,6 @@ watch(
immediate
:
true
}
)
/**
* 将传进来的值赋值给formData
*/
...
...
@@ -53,10 +51,11 @@ watch(
()
=>
props
.
propFormData
,
(
data
)
=>
{
if
(
!
data
)
return
// fix:三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
copyValueToTarget
(
formData
.
value
,
data
)
},
{
deep
:
true
,
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
immediate
:
true
}
)
...
...
@@ -67,8 +66,8 @@ watch(
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
D
escriptionFormRef
)
return
return
unref
(
D
escriptionFormRef
).
validate
((
valid
)
=>
{
if
(
!
d
escriptionFormRef
)
return
return
await
unref
(
d
escriptionFormRef
).
validate
((
valid
)
=>
{
if
(
!
valid
)
{
message
.
warning
(
'商品详情为完善!!'
)
emit
(
'update:activeName'
,
'description'
)
...
...
src/views/mall/product/spu/components/OtherSettingsForm.vue
View file @
4ddba9d4
<
template
>
<el-form
ref=
"
O
therSettingsFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
ref=
"
o
therSettingsFormRef"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-row>
<!-- TODO @puhui999:横着三个哈 fix-->
<el-col
:span=
"24"
>
...
...
@@ -55,8 +55,8 @@
<
script
lang=
"ts"
name=
"OtherSettingsForm"
setup
>
import
type
{
SpuType
}
from
'@/api/mall/product/spu'
import
{
PropType
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
copyValueToTarget
}
from
'@/utils'
const
message
=
useMessage
()
// 消息弹窗
...
...
@@ -68,7 +68,7 @@ const props = defineProps({
activeName
:
propTypes
.
string
.
def
(
''
)
})
const
O
therSettingsFormRef
=
ref
()
// 表单Ref
const
o
therSettingsFormRef
=
ref
()
// 表单Ref
// 表单数据
const
formData
=
ref
<
SpuType
>
({
sort
:
1
,
// 商品排序
...
...
@@ -100,7 +100,7 @@ const checkboxGroup = ref<string[]>([]) // 选中的推荐选项
const
onChangeGroup
=
()
=>
{
// TODO @puhui999:是不是可以遍历 recommend,然后进行是否选中;fix
recommendOptions
.
forEach
(({
value
})
=>
{
formData
.
value
[
value
]
=
checkboxGroup
.
value
.
includes
(
value
)
?
true
:
false
formData
.
value
[
value
]
=
checkboxGroup
.
value
.
includes
(
value
)
})
}
...
...
@@ -111,22 +111,28 @@ watch(
()
=>
props
.
propFormData
,
(
data
)
=>
{
if
(
!
data
)
return
// fix:三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
copyValueToTarget
(
formData
.
value
,
data
)
recommendOptions
.
forEach
(({
value
})
=>
{
// TODO 如果先修改其他设置的值,再改变商品详情或是商品信息会重置其他设置页面中的相关值 fix:已修复
if
(
formData
.
value
[
value
]
&&
!
checkboxGroup
.
value
.
includes
(
value
))
{
checkboxGroup
.
value
.
push
(
value
)
}
})
},
{
deep
:
true
,
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
immediate
:
true
}
)
/**
* 表单校验
*/
const
emit
=
defineEmits
([
'update:activeName'
])
const
validate
=
async
()
=>
{
// 校验表单
if
(
!
O
therSettingsFormRef
)
return
return
await
unref
(
O
therSettingsFormRef
).
validate
((
valid
)
=>
{
if
(
!
o
therSettingsFormRef
)
return
return
await
unref
(
o
therSettingsFormRef
).
validate
((
valid
)
=>
{
if
(
!
valid
)
{
message
.
warning
(
'商品其他设置未完善!!'
)
emit
(
'update:activeName'
,
'otherSettings'
)
...
...
@@ -139,14 +145,4 @@ const validate = async () => {
})
}
defineExpose
({
validate
})
onMounted
(
async
()
=>
{
await
nextTick
()
// TODO 如果先修改其他设置的值,再改变商品详情或是商品信息会重置其他设置页面中的相关值 fix:已修复,改为组件初始化时赋值
checkboxGroup
.
value
=
[]
recommendOptions
.
forEach
(({
value
})
=>
{
if
(
formData
.
value
[
value
])
{
checkboxGroup
.
value
.
push
(
value
)
}
})
})
</
script
>
src/views/mall/product/spu/components/ProductAttributes.vue
View file @
4ddba9d4
...
...
@@ -54,14 +54,14 @@ const inputVisible = computed(() => (index) => {
const
InputRef
=
ref
()
//标签输入框Ref
const
attributeList
=
ref
([])
// 商品属性列表
const
props
=
defineProps
({
attributeData
:
{
propertyList
:
{
type
:
Array
,
default
:
()
=>
{}
}
})
watch
(
()
=>
props
.
attributeData
,
()
=>
props
.
propertyList
,
(
data
)
=>
{
if
(
!
data
)
return
attributeList
.
value
=
data
...
...
@@ -80,6 +80,7 @@ const handleClose = (index, valueIndex) => {
/** 显示输入框并获取焦点 */
const
showInput
=
async
(
index
)
=>
{
attributeIndex
.
value
=
index
// TODO 嗯!!!自动获取焦点还是有点问题,后续继续改进
// 因为组件在ref中所以需要用索引获取对应的Ref
InputRef
.
value
[
index
]
!
.
input
!
.
focus
()
}
...
...
src/views/mall/product/spu/components/SkuList.vue
View file @
4ddba9d4
...
...
@@ -25,13 +25,13 @@
</
template
>
</el-table-column>
</template>
<!-- TODO @puhui999: controls-position=" " 可以去掉哈,不然太长了,手动输入更方便 -->
<!-- TODO @puhui999: controls-position=" " 可以去掉哈,不然太长了,手动输入更方便
fix
-->
<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:用户输入的时候,是按照元;分主要是我们自己用; -->
<!-- TODO @puhui999:用户输入的时候,是按照元;分主要是我们自己用;
fix
-->
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"168"
>
<
template
#
default=
"{ row }"
>
<el-input-number
v-model=
"row.price"
:min=
"0"
class=
"w-100%"
/>
...
...
@@ -96,7 +96,7 @@ const props = defineProps({
type
:
Object
as
PropType
<
SpuType
>
,
default
:
()
=>
{}
},
attribute
List
:
{
property
List
:
{
type
:
Array
,
default
:
()
=>
[]
},
...
...
@@ -142,7 +142,7 @@ watch(
}
)
// TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不
// TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不
fix
/** 生成表数据 */
const
generateTableData
=
(
data
:
any
[])
=>
{
// 构建数据结构 fix: 使用map替换多重for循环
...
...
@@ -207,8 +207,8 @@ const build = (propertyValuesList: Property[][]) => {
/** 监听属性列表生成相关参数和表头 */
watch
(
()
=>
props
.
attribute
List
,
(
attribute
List
)
=>
{
()
=>
props
.
property
List
,
(
property
List
)
=>
{
// 如果不是多规格则结束
if
(
!
formData
.
value
.
specType
)
return
// 如果当前组件作为批量添加数据使用则重置表数据
...
...
@@ -229,15 +229,15 @@ watch(
]
}
// 判断代理对象是否为空
if
(
JSON
.
stringify
(
attribute
List
)
===
'[]'
)
return
if
(
JSON
.
stringify
(
property
List
)
===
'[]'
)
return
// 重置表头
tableHeaders
.
value
=
[]
// 生成表头
attribute
List
.
forEach
((
item
,
index
)
=>
{
property
List
.
forEach
((
item
,
index
)
=>
{
// name加属性项index区分属性值
tableHeaders
.
value
.
push
({
prop
:
`name
${
index
}
`
,
label
:
item
.
name
})
})
generateTableData
(
attribute
List
)
generateTableData
(
property
List
)
},
{
deep
:
true
,
...
...
src/views/mall/product/spu/index.vue
View file @
4ddba9d4
...
...
@@ -8,7 +8,7 @@
class=
"-mb-15px"
label-width=
"68px"
>
<!-- TODO @puhui999:https://admin.java.crmeb.net/store/index,参考,使用分类 + 标题搜索 -->
<!-- TODO @puhui999:https://admin.java.crmeb.net/store/index,参考,使用分类 + 标题搜索
fix
-->
<el-form-item
label=
"品牌名称"
prop=
"name"
>
<el-input
v-model=
"queryParams.name"
...
...
@@ -351,11 +351,11 @@ const resetQuery = () => {
const
openForm
=
(
id
?:
number
)
=>
{
// 修改
if
(
typeof
id
===
'number'
)
{
push
(
'/product/product
ManagementAdd?id=
'
+
id
)
push
(
'/product/product
SpuEdit/
'
+
id
)
return
}
// 新增
push
(
'/product/product
Management
Add'
)
push
(
'/product/product
Spu
Add'
)
}
// 监听路由变化更新列表 TODO @puhui999:这个是必须加的么?fix: 因为编辑表单是以路由的方式打开,保存表单后列表不会刷新
...
...
@@ -377,8 +377,11 @@ onMounted(async () => {
</
script
>
<
style
lang=
"scss"
scoped
>
.demo-table-expand
{
padding-left
:
42px
;
:deep(.el-form-item__label)
{
width
:
82px
;
font-weight
:
bold
;
color
:
#99a9bf
;
}
}
...
...
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