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
Unverified
Commit
e7c9ca0c
authored
Aug 13, 2024
by
芋道源码
Committed by
GitHub
Aug 13, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #71 from GoldenZqqq/GoldenZqqq/issue47
【功能优化】添加商品属性时允许选择已有的属性值
parents
aaa5e146
2937f3c1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
12 deletions
+97
-12
src/views/mall/product/spu/components/SkuList.vue
+3
-3
src/views/mall/product/spu/components/index.ts
+1
-0
src/views/mall/product/spu/form/ProductAttributes.vue
+26
-5
src/views/mall/product/spu/form/ProductPropertyAddForm.vue
+40
-1
src/views/mall/product/spu/form/SkuForm.vue
+27
-3
No files found.
src/views/mall/product/spu/components/SkuList.vue
View file @
e7c9ca0c
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
>
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
<span
style=
"font-weight: bold; color: #40aaff"
>
<span
style=
"font-weight: bold; color: #40aaff"
>
{{
row
.
properties
[
index
]?.
valueName
}}
{{
row
.
properties
?.
[
index
]?.
valueName
}}
</span>
</span>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
...
@@ -168,7 +168,7 @@
...
@@ -168,7 +168,7 @@
>
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
<span
style=
"font-weight: bold; color: #40aaff"
>
<span
style=
"font-weight: bold; color: #40aaff"
>
{{
row
.
properties
[
index
]?.
valueName
}}
{{
row
.
properties
?.
[
index
]?.
valueName
}}
</span>
</span>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
...
@@ -248,7 +248,7 @@
...
@@ -248,7 +248,7 @@
>
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
<span
style=
"font-weight: bold; color: #40aaff"
>
<span
style=
"font-weight: bold; color: #40aaff"
>
{{
row
.
properties
[
index
]?.
valueName
}}
{{
row
.
properties
?.
[
index
]?.
valueName
}}
</span>
</span>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
...
...
src/views/mall/product/spu/components/index.ts
View file @
e7c9ca0c
...
@@ -5,6 +5,7 @@ interface PropertyAndValues {
...
@@ -5,6 +5,7 @@ interface PropertyAndValues {
id
:
number
id
:
number
name
:
string
name
:
string
values
?:
PropertyAndValues
[]
values
?:
PropertyAndValues
[]
propertyOpts
?:
PropertyAndValues
[]
}
}
interface
RuleConfig
{
interface
RuleConfig
{
...
...
src/views/mall/product/spu/form/ProductAttributes.vue
View file @
e7c9ca0c
...
@@ -18,16 +18,28 @@
...
@@ -18,16 +18,28 @@
>
>
{{
value
.
name
}}
{{
value
.
name
}}
</el-tag>
</el-tag>
<el-input
<el-select
v-show=
"inputVisible(index)"
:id=
"`input$
{index}`"
:id=
"`input$
{index}`"
:ref="setInputRef"
:ref="setInputRef"
v-show="inputVisible(index)"
v-model="inputValue"
v-model="inputValue"
class="!w-20"
filterable
allow-create
default-first-option
:reserve-keyword="false"
size="small"
size="small"
class="!w-30"
@blur="handleInputConfirm(index, item.id)"
@blur="handleInputConfirm(index, item.id)"
@keyup.enter="handleInputConfirm(index, item.id)"
@keyup.enter="handleInputConfirm(index, item.id)"
/>
@change="handleInputConfirm(index, item.id)"
>
<el-option
v-for=
"item2 in item.propertyOpts"
:key=
"item2.id"
:label=
"item2.name"
:value=
"item2.id"
/>
</el-select>
<el-button
<el-button
v-show=
"!inputVisible(index)"
v-show=
"!inputVisible(index)"
class=
"button-new-tag ml-1"
class=
"button-new-tag ml-1"
...
@@ -42,10 +54,10 @@
...
@@ -42,10 +54,10 @@
</
template
>
</
template
>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
ElInput
}
from
'element-plus'
import
*
as
PropertyApi
from
'@/api/mall/product/property'
import
*
as
PropertyApi
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'
import
{
isNumber
}
from
'@/utils/is'
defineOptions
({
name
:
'ProductAttributes'
})
defineOptions
({
name
:
'ProductAttributes'
})
...
@@ -109,6 +121,15 @@ const showInput = async (index) => {
...
@@ -109,6 +121,15 @@ const showInput = async (index) => {
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
handleInputConfirm
=
async
(
index
:
number
,
propertyId
:
number
)
=>
{
const
handleInputConfirm
=
async
(
index
:
number
,
propertyId
:
number
)
=>
{
if
(
inputValue
.
value
)
{
if
(
inputValue
.
value
)
{
// 重复添加校验
if
(
isNumber
(
inputValue
.
value
))
{
if
(
attributeList
.
value
[
index
].
values
?.
some
((
item
)
=>
item
.
id
===
inputValue
.
value
))
{
message
.
warning
(
'已存在相同属性值,请重试'
)
attributeIndex
.
value
=
null
inputValue
.
value
=
''
return
}
}
// 保存属性值
// 保存属性值
try
{
try
{
const
id
=
await
PropertyApi
.
createPropertyValue
({
propertyId
,
name
:
inputValue
.
value
})
const
id
=
await
PropertyApi
.
createPropertyValue
({
propertyId
,
name
:
inputValue
.
value
})
...
...
src/views/mall/product/spu/form/ProductPropertyAddForm.vue
View file @
e7c9ca0c
...
@@ -10,7 +10,22 @@
...
@@ -10,7 +10,22 @@
@
keydown
.
enter
.
prevent=
"submitForm"
@
keydown
.
enter
.
prevent=
"submitForm"
>
>
<el-form-item
label=
"属性名称"
prop=
"name"
>
<el-form-item
label=
"属性名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入名称"
/>
<el-select
v-model=
"formData.name"
filterable
allow-create
default-first-option
:reserve-keyword=
"false"
placeholder=
"请选择属性名称"
style=
"width: 240px"
>
<el-option
v-for=
"item in attrOption"
:key=
"item.id"
:label=
"item.name"
:value=
"item.name"
/>
</el-select>
</el-form-item>
</el-form-item>
</el-form>
</el-form>
<template
#
footer
>
<template
#
footer
>
...
@@ -24,6 +39,7 @@ import * as PropertyApi from '@/api/mall/product/property'
...
@@ -24,6 +39,7 @@ import * as PropertyApi from '@/api/mall/product/property'
defineOptions
({
name
:
'ProductPropertyForm'
})
defineOptions
({
name
:
'ProductPropertyForm'
})
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
{
t
}
=
useI18n
()
// 国际化
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
...
@@ -37,6 +53,7 @@ const formRules = reactive({
...
@@ -37,6 +53,7 @@ const formRules = reactive({
})
})
const
formRef
=
ref
()
// 表单 Ref
const
formRef
=
ref
()
// 表单 Ref
const
attributeList
=
ref
([])
// 商品属性列表
const
attributeList
=
ref
([])
// 商品属性列表
const
attrOption
=
ref
([])
// 属性名称下拉框
const
props
=
defineProps
({
const
props
=
defineProps
({
propertyList
:
{
propertyList
:
{
type
:
Array
,
type
:
Array
,
...
@@ -59,6 +76,7 @@ watch(
...
@@ -59,6 +76,7 @@ watch(
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
()
=>
{
const
open
=
async
()
=>
{
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
getAttrOption
()
resetForm
()
resetForm
()
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
...
@@ -80,6 +98,15 @@ const submitForm = async () => {
...
@@ -80,6 +98,15 @@ const submitForm = async () => {
...
formData
.
value
,
...
formData
.
value
,
values
:
[]
values
:
[]
})
})
// 判断最终提交的属性名称是否是选择的 自己手动输入的属性名称不执行emit
for
(
const
element
of
attrOption
.
value
)
{
if
(
element
.
name
===
formData
.
value
.
name
)
{
emit
(
'success'
,
propertyId
,
element
.
id
)
message
.
success
(
t
(
'common.createSuccess'
))
dialogVisible
.
value
=
false
return
}
}
message
.
success
(
t
(
'common.createSuccess'
))
message
.
success
(
t
(
'common.createSuccess'
))
dialogVisible
.
value
=
false
dialogVisible
.
value
=
false
}
finally
{
}
finally
{
...
@@ -94,4 +121,16 @@ const resetForm = () => {
...
@@ -94,4 +121,16 @@ const resetForm = () => {
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
}
}
/** 获取商品属性下拉选项 */
const
getAttrOption
=
async
()
=>
{
formLoading
.
value
=
true
try
{
// TODO @芋艿:需要增加一个全列表接口
const
data
=
await
PropertyApi
.
getPropertyPage
({
pageNo
:
1
,
pageSize
:
100
})
attrOption
.
value
=
data
.
list
}
finally
{
formLoading
.
value
=
false
}
}
</
script
>
</
script
>
src/views/mall/product/spu/form/SkuForm.vue
View file @
e7c9ca0c
<!-- 商品发布 - 库存价格 -->
<!-- 商品发布 - 库存价格 -->
<
template
>
<
template
>
<el-form
ref=
"formRef"
:disabled=
"isDetail"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
>
<el-form
ref=
"formRef"
:disabled=
"isDetail"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
v-loading=
"formLoading"
>
<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"
...
@@ -51,9 +58,14 @@
...
@@ -51,9 +58,14 @@
</el-form>
</el-form>
<!-- 商品属性添加 Form 表单 -->
<!-- 商品属性添加 Form 表单 -->
<ProductPropertyAddForm
ref=
"attributesAddFormRef"
:propertyList=
"propertyList"
/>
<ProductPropertyAddForm
ref=
"attributesAddFormRef"
:propertyList=
"propertyList"
@
success=
"getPropertyValueList"
/>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
*
as
PropertyApi
from
'@/api/mall/product/property'
import
{
PropType
}
from
'vue'
import
{
PropType
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
propTypes
}
from
'@/utils/propTypes'
...
@@ -94,7 +106,7 @@ const ruleConfig: RuleConfig[] = [
...
@@ -94,7 +106,7 @@ const ruleConfig: RuleConfig[] = [
]
]
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
const
formLoading
=
ref
(
false
)
const
props
=
defineProps
({
const
props
=
defineProps
({
propFormData
:
{
propFormData
:
{
type
:
Object
as
PropType
<
Spu
>
,
type
:
Object
as
PropType
<
Spu
>
,
...
@@ -184,4 +196,16 @@ const onChangeSpec = () => {
...
@@ -184,4 +196,16 @@ const onChangeSpec = () => {
const
generateSkus
=
(
propertyList
:
any
[])
=>
{
const
generateSkus
=
(
propertyList
:
any
[])
=>
{
skuListRef
.
value
.
generateTableData
(
propertyList
)
skuListRef
.
value
.
generateTableData
(
propertyList
)
}
}
/* 获取属性值列表 */
const
getPropertyValueList
=
async
(
id
,
propertyId
)
=>
{
formLoading
.
value
=
true
try
{
// TODO @芋艿:需要增加一个全列表接口
const
data
=
await
PropertyApi
.
getPropertyValuePage
({
pageNo
:
1
,
pageSize
:
100
,
propertyId
})
propertyList
.
value
.
find
((
item
)
=>
item
.
id
===
id
).
propertyOpts
=
data
.
list
}
finally
{
formLoading
.
value
=
false
}
}
</
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