review + mall:商品管理

This commit is contained in:
YunaiV
2023-05-24 20:27:45 +08:00
parent c296c9e53d
commit 0fba3fd503
8 changed files with 63 additions and 59 deletions

View File

@@ -96,7 +96,6 @@
<!-- 多规格添加-->
<el-col :span="24">
<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" @success="generateSkus" />
</el-form-item>
@@ -137,9 +136,8 @@ const props = defineProps({
},
activeName: propTypes.string.def('')
})
const attributesAddFormRef = ref() // 添加商品属性表单 TODO @puhui999小写开头哈 fix
const productSpuBasicInfoRef = ref() // 表单Ref TODO @puhui999小写开头哈 fix
// TODO @puhui999attributeList 改成 propertyList会更统一一点 fix
const attributesAddFormRef = ref() // 添加商品属性表单
const productSpuBasicInfoRef = ref() // 表单 Ref
const propertyList = ref([]) // 商品属性列表
const skuListRef = ref() // 商品属性列表Ref
/** 调用 SkuList generateTableData 方法*/
@@ -180,17 +178,17 @@ const rules = reactive({
watch(
() => props.propFormData,
(data) => {
if (!data) return
// fix三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
if (!data) {
return
}
copyValueToTarget(formData, data)
// fix: 多图上传组件需要一个包含url属性的对象才能正常回显
formData.sliderPicUrls = data['sliderPicUrls'].map((item) => ({
url: item
}))
// TODO @puhui999if return减少嵌套层级
// 只有是多规格才处理
if (formData.specType) {
// TODO @puhui999可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
// fix: 直接拿返回的 skus 属性逆向生成出 propertyList
// 直接拿返回的 skus 属性逆向生成出 propertyList
const properties = []
formData.skus.forEach((sku) => {
sku.properties.forEach(({ propertyId, propertyName, valueId, valueName }) => {
@@ -209,7 +207,6 @@ watch(
}
},
{
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
immediate: true
}
)

View File

@@ -1,7 +1,6 @@
<template>
<el-form ref="otherSettingsFormRef" :model="formData" :rules="rules" label-width="120px">
<el-row>
<!-- TODO @puhui999横着三个哈 fix-->
<el-col :span="24">
<el-row :gutter="20">
<el-col :span="8">
@@ -35,7 +34,7 @@
</el-form-item>
</el-col>
<el-col :span="24">
<!-- TODO tag展示暂时不考虑排序 -->
<!-- TODO tag展示暂时不考虑排序 -->
<el-form-item label="活动优先级">
<el-tag>默认</el-tag>
<el-tag class="ml-2" type="success">秒杀</el-tag>
@@ -86,7 +85,6 @@ const rules = reactive({
giveIntegral: [required],
virtualSalesCount: [required]
})
// TODO @puhui999这种叫 recommendOptions 会更合适哈 fix
const recommendOptions = [
{ name: '是否热卖', value: 'recommendHot' },
{ name: '是否优惠', value: 'recommendBenefit' },
@@ -98,7 +96,6 @@ const checkboxGroup = ref<string[]>([]) // 选中的推荐选项
/** 选择商品后赋值 */
const onChangeGroup = () => {
// TODO @puhui999是不是可以遍历 recommend然后进行是否选中fix
recommendOptions.forEach(({ value }) => {
formData.value[value] = checkboxGroup.value.includes(value)
})
@@ -110,21 +107,21 @@ const onChangeGroup = () => {
watch(
() => props.propFormData,
(data) => {
if (!data) return
// fix三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
if (!data) {
return
}
copyValueToTarget(formData.value, data)
recommendOptions.forEach(({ value }) => {
// TODO 如果先修改其他设置的值,再改变商品详情或是商品信息会重置其他设置页面中的相关值 fix:已修复
if (formData.value[value] && !checkboxGroup.value.includes(value)) {
checkboxGroup.value.push(value)
}
})
},
{
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
immediate: true
}
)
/**
* 表单校验
*/

View File

@@ -12,7 +12,7 @@
</template>
</el-table-column>
<template v-if="formData.specType && !isBatch">
<!-- 根据商品属性动态添加 -->
<!-- 根据商品属性动态添加 -->
<el-table-column
v-for="(item, index) in tableHeaders"
:key="index"
@@ -21,17 +21,16 @@
min-width="120"
>
<template #default="{ row }">
<!-- TODO puhui999展示成蓝色有点区分度哈 -->
{{ row.properties[index]?.valueName }}
</template>
</el-table-column>
</template>
<!-- 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用户输入的时候是按照元分主要是我们自己用fix -->
<el-table-column align="center" label="销售价(元)" min-width="168">
<template #default="{ row }">
<el-input-number v-model="row.price" :min="0" :precision="2" :step="0.1" class="w-100%" />
@@ -141,6 +140,7 @@ const skuList = ref<SkuType[]>([
subCommissionSecondPrice: 0 // 二级分销的佣金
}
]) // 批量添加时的临时数据
// TODO @puhui999保存时每个商品规格的表单要校验下。例如说销售金额最低是 0.01 这种。
/** 批量添加 */
const batchAdd = () => {
@@ -148,6 +148,7 @@ const batchAdd = () => {
copyValueToTarget(item, skuList.value[0])
})
}
/** 删除 sku */
const deleteSku = (row) => {
const index = formData.value.skus.findIndex(
@@ -159,7 +160,7 @@ const deleteSku = (row) => {
const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表头
/**
* 将传进来的值赋值给skuList
* 将传进来的值赋值给 skuList
*/
watch(
() => props.propFormData,
@@ -173,11 +174,10 @@ watch(
}
)
// TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不 fix: 添加相关处理逻辑解决编辑表单时或查看详情时数据回显问题
/** 生成表数据 */
const generateTableData = (propertyList: any[]) => {
// 构建数据结构 fix: 使用map替换多重for循环
const propertiesItemList = propertyList.map((item) =>
// 构建数据结构
const propertyValues = propertyList.map((item) =>
item.values.map((v) => ({
propertyId: item.id,
propertyName: item.name,
@@ -185,15 +185,16 @@ const generateTableData = (propertyList: any[]) => {
valueName: v.name
}))
)
const buildList = build(propertiesItemList)
// TODO @puhui是不是 buildSkuList这样容易理解一点哈。item 改成 sku
const buildList = build(propertyValues)
// 如果回显的 sku 属性和添加的属性不一致则重置 skus 列表
if (!validateData(propertyList)) {
// 如果不一致则重置表数据默认添加新的属性重新生成sku列表
// 如果不一致则重置表数据,默认添加新的属性重新生成 sku 列表
formData.value!.skus = []
}
for (const item of buildList) {
const row = {
properties: Array.isArray(item) ? item : [item], // 如果只有一个属性的话返回的是一个property对象
properties: Array.isArray(item) ? item : [item], // 如果只有一个属性的话返回的是一个 property 对象
price: 0,
marketPrice: 0,
costPrice: 0,
@@ -205,16 +206,17 @@ const generateTableData = (propertyList: any[]) => {
subCommissionFirstPrice: 0,
subCommissionSecondPrice: 0
}
// 如果存在属性相同的 sku 则不做处理
const index = formData.value!.skus.findIndex(
(sku) => JSON.stringify(sku.properties) === JSON.stringify(row.properties)
)
// 如果存在属性相同的 sku 则不做处理
if (index !== -1) {
continue
}
formData.value.skus.push(row)
}
}
/**
* 生成 skus 前置校验
*/
@@ -232,6 +234,7 @@ const validateData = (propertyList: any[]) => {
const propertyIds = propertyList.map((item) => item.id)
return skuPropertyIds.length === propertyIds.length
}
/** 构建所有排列组合 */
const build = (propertyValuesList: Property[][]) => {
if (propertyValuesList.length === 0) {
@@ -255,13 +258,15 @@ const build = (propertyValuesList: Property[][]) => {
}
}
/** 监听属性列表生成相关参数和表头 */
/** 监听属性列表生成相关参数和表头 */
watch(
() => props.propertyList,
(propertyList) => {
// 如果不是多规格则结束
if (!formData.value.specType) return
// 如果当前组件作为批量添加数据使用则重置表数据
if (!formData.value.specType) {
return
}
// 如果当前组件作为批量添加数据使用,则重置表数据
if (props.isBatch) {
skuList.value = [
{
@@ -278,8 +283,11 @@ watch(
}
]
}
// 判断代理对象是否为空
if (JSON.stringify(propertyList) === '[]') return
if (JSON.stringify(propertyList) === '[]') {
return
}
// 重置表头
tableHeaders.value = []
// 生成表头
@@ -287,10 +295,16 @@ watch(
// name加属性项index区分属性值
tableHeaders.value.push({ prop: `name${index}`, label: item.name })
})
// 如果回显的 sku 属性和添加的属性一致则不处理
if (validateData(propertyList)) return
if (validateData(propertyList)) {
return
}
// 添加新属性没有属性值也不做处理
if (propertyList.some((item) => item.values.length === 0)) return
if (propertyList.some((item) => item.values.length === 0)) {
return
}
// 生成 table 数据,即 sku 列表
generateTableData(propertyList)
},
{
@@ -298,6 +312,6 @@ watch(
immediate: true
}
)
// 暴露出生成 sku 方法给添加属性成功时调用 fix: 为了在只有一个属性下 spu 回显 skus 属性和和商品属性个数一致的情况下 添加属性值时添加 sku
// 暴露出生成 sku 方法给添加属性成功时调用
defineExpose({ generateTableData })
</script>