【优化】spu:新增商品属性属性值为空校验
parent
96a499a815
commit
e9bb9403b4
|
@ -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) => {
|
||||||
|
|
||||||
/** 批量添加 */
|
/** 批量添加 */
|
||||||
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 }[]>([]) // 多属性表
|
||||||
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 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(
|
||||||
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[]) => {
|
||||||
*/
|
*/
|
||||||
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(
|
||||||
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 列表
|
||||||
|
|
|
@ -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 @@
|
||||||
<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 @@
|
||||||
<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) => {
|
||||||
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(
|
||||||
() => 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) => {
|
||||||
/** 删除属性*/
|
/** 删除属性*/
|
||||||
const handleCloseProperty = (index: number) => {
|
const handleCloseProperty = (index: number) => {
|
||||||
attributeList.value?.splice(index, 1)
|
attributeList.value?.splice(index, 1)
|
||||||
|
emit('success', attributeList.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 显示输入框并获取焦点 */
|
/** 显示输入框并获取焦点 */
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<!-- 商品发布 - 库存价格 -->
|
<!-- 商品发布 - 库存价格 -->
|
||||||
<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 @@
|
||||||
<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 = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 调用 SkuList generateTableData 方法*/
|
/** 调用 SkuList generateTableData 方法*/
|
||||||
const generateSkus = (propertyList) => {
|
const generateSkus = (propertyList: any[]) => {
|
||||||
skuListRef.value.generateTableData(propertyList)
|
skuListRef.value.generateTableData(propertyList)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue