Skip to content

Commit 0fba3fd

Browse files
committed
review + mall:商品管理
1 parent c296c9e commit 0fba3fd

File tree

8 files changed

+63
-59
lines changed

8 files changed

+63
-59
lines changed

build/vite/optimize.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ const include = [
102102
'element-plus/es/components/timeline-item/style/css',
103103
'element-plus/es/components/collapse/style/css',
104104
'element-plus/es/components/collapse-item/style/css',
105-
'element-plus/es/components/button-group/style/css'
105+
'element-plus/es/components/button-group/style/css',
106+
'element-plus/es/components/text/style/css'
106107
]
107108

108109
const exclude = ['@iconify/json']

src/api/mall/product/spu.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface Property {
77
valueName?: string // 属性值名称
88
}
99

10+
// TODO puhui999:是不是直接叫 Sku 更简洁一点哈。type 待后面,总感觉有个类型?
1011
export interface SkuType {
1112
id?: number // 商品 SKU 编号
1213
spuId?: number // SPU 编号
@@ -24,6 +25,7 @@ export interface SkuType {
2425
salesCount?: number // 商品销量
2526
}
2627

28+
// TODO puhui999:是不是直接叫 Spu 更简洁一点哈。type 待后面,总感觉有个类型?
2729
export interface SpuType {
2830
id?: number
2931
name?: string // 商品名称

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export const copyValueToTarget = (target, source) => {
174174
Object.assign(target, newObj)
175175
}
176176

177+
// TODO @puhui999:返回要带上 .00 哈.例如说 1.00
177178
/**
178179
* 将一个整数转换为分数保留两位小数
179180
* @param num

src/views/mall/product/spu/addForm.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ const submitForm = async () => {
146146
const newSliderPicUrls = []
147147
deepCopyFormData.sliderPicUrls.forEach((item) => {
148148
// 如果是前端选的图
149-
// TODO @puhui999:疑问哈,为啥会是 object 呀?fix
150149
typeof item === 'object' ? newSliderPicUrls.push(item.url) : newSliderPicUrls.push(item)
151150
})
152151
deepCopyFormData.sliderPicUrls = newSliderPicUrls

src/views/mall/product/spu/components/BasicInfoForm.vue

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@
9696
<!-- 多规格添加-->
9797
<el-col :span="24">
9898
<el-form-item v-if="formData.specType" label="商品属性">
99-
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈 fix-->
10099
<el-button class="mr-15px mb-10px" @click="attributesAddFormRef.open">添加规格</el-button>
101100
<ProductAttributes :propertyList="propertyList" @success="generateSkus" />
102101
</el-form-item>
@@ -137,9 +136,8 @@ const props = defineProps({
137136
},
138137
activeName: propTypes.string.def('')
139138
})
140-
const attributesAddFormRef = ref() // 添加商品属性表单 TODO @puhui999:小写开头哈 fix
141-
const productSpuBasicInfoRef = ref() // 表单Ref TODO @puhui999:小写开头哈 fix
142-
// TODO @puhui999:attributeList 改成 propertyList,会更统一一点 fix
139+
const attributesAddFormRef = ref() // 添加商品属性表单
140+
const productSpuBasicInfoRef = ref() // 表单 Ref
143141
const propertyList = ref([]) // 商品属性列表
144142
const skuListRef = ref() // 商品属性列表Ref
145143
/** 调用 SkuList generateTableData 方法*/
@@ -180,17 +178,17 @@ const rules = reactive({
180178
watch(
181179
() => props.propFormData,
182180
(data) => {
183-
if (!data) return
184-
// fix:三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
181+
if (!data) {
182+
return
183+
}
185184
copyValueToTarget(formData, data)
186-
// fix: 多图上传组件需要一个包含url属性的对象才能正常回显
187185
formData.sliderPicUrls = data['sliderPicUrls'].map((item) => ({
188186
url: item
189187
}))
188+
// TODO @puhui999:if return,减少嵌套层级
190189
// 只有是多规格才处理
191190
if (formData.specType) {
192-
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
193-
// fix: 直接拿返回的 skus 属性逆向生成出 propertyList
191+
// 直接拿返回的 skus 属性逆向生成出 propertyList
194192
const properties = []
195193
formData.skus.forEach((sku) => {
196194
sku.properties.forEach(({ propertyId, propertyName, valueId, valueName }) => {
@@ -209,7 +207,6 @@ watch(
209207
}
210208
},
211209
{
212-
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
213210
immediate: true
214211
}
215212
)

src/views/mall/product/spu/components/OtherSettingsForm.vue

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<template>
22
<el-form ref="otherSettingsFormRef" :model="formData" :rules="rules" label-width="120px">
33
<el-row>
4-
<!-- TODO @puhui999:横着三个哈 fix-->
54
<el-col :span="24">
65
<el-row :gutter="20">
76
<el-col :span="8">
@@ -35,7 +34,7 @@
3534
</el-form-item>
3635
</el-col>
3736
<el-col :span="24">
38-
<!-- TODO tag展示暂时不考虑排序 -->
37+
<!-- TODO tag展示暂时不考虑排序 -->
3938
<el-form-item label="活动优先级">
4039
<el-tag>默认</el-tag>
4140
<el-tag class="ml-2" type="success">秒杀</el-tag>
@@ -86,7 +85,6 @@ const rules = reactive({
8685
giveIntegral: [required],
8786
virtualSalesCount: [required]
8887
})
89-
// TODO @puhui999:这种叫 recommendOptions 会更合适哈 fix
9088
const recommendOptions = [
9189
{ name: '是否热卖', value: 'recommendHot' },
9290
{ name: '是否优惠', value: 'recommendBenefit' },
@@ -98,7 +96,6 @@ const checkboxGroup = ref<string[]>([]) // 选中的推荐选项
9896
9997
/** 选择商品后赋值 */
10098
const onChangeGroup = () => {
101-
// TODO @puhui999:是不是可以遍历 recommend,然后进行是否选中;fix
10299
recommendOptions.forEach(({ value }) => {
103100
formData.value[value] = checkboxGroup.value.includes(value)
104101
})
@@ -110,21 +107,21 @@ const onChangeGroup = () => {
110107
watch(
111108
() => props.propFormData,
112109
(data) => {
113-
if (!data) return
114-
// fix:三个表单组件监听赋值必须使用 copyValueToTarget 使用 formData.value = data 会监听非常多次
110+
if (!data) {
111+
return
112+
}
115113
copyValueToTarget(formData.value, data)
116114
recommendOptions.forEach(({ value }) => {
117-
// TODO 如果先修改其他设置的值,再改变商品详情或是商品信息会重置其他设置页面中的相关值 fix:已修复
118115
if (formData.value[value] && !checkboxGroup.value.includes(value)) {
119116
checkboxGroup.value.push(value)
120117
}
121118
})
122119
},
123120
{
124-
// fix: 去掉深度监听只有对象引用发生改变的时候才执行,解决改一动多的问题
125121
immediate: true
126122
}
127123
)
124+
128125
/**
129126
* 表单校验
130127
*/

src/views/mall/product/spu/components/SkuList.vue

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</template>
1313
</el-table-column>
1414
<template v-if="formData.specType && !isBatch">
15-
<!-- 根据商品属性动态添加 -->
15+
<!-- 根据商品属性动态添加 -->
1616
<el-table-column
1717
v-for="(item, index) in tableHeaders"
1818
:key="index"
@@ -21,17 +21,16 @@
2121
min-width="120"
2222
>
2323
<template #default="{ row }">
24+
<!-- TODO puhui999:展示成蓝色,有点区分度哈 -->
2425
{{ row.properties[index]?.valueName }}
2526
</template>
2627
</el-table-column>
2728
</template>
28-
<!-- TODO @puhui999: controls-position=" " 可以去掉哈,不然太长了,手动输入更方便 fix -->
2929
<el-table-column align="center" label="商品条码" min-width="168">
3030
<template #default="{ row }">
3131
<el-input v-model="row.barCode" class="w-100%" />
3232
</template>
3333
</el-table-column>
34-
<!-- TODO @puhui999:用户输入的时候,是按照元;分主要是我们自己用;fix -->
3534
<el-table-column align="center" label="销售价(元)" min-width="168">
3635
<template #default="{ row }">
3736
<el-input-number v-model="row.price" :min="0" :precision="2" :step="0.1" class="w-100%" />
@@ -141,13 +140,15 @@ const skuList = ref<SkuType[]>([
141140
subCommissionSecondPrice: 0 // 二级分销的佣金
142141
}
143142
]) // 批量添加时的临时数据
143+
// TODO @puhui999:保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
144144
145145
/** 批量添加 */
146146
const batchAdd = () => {
147147
formData.value.skus.forEach((item) => {
148148
copyValueToTarget(item, skuList.value[0])
149149
})
150150
}
151+
151152
/** 删除 sku */
152153
const deleteSku = (row) => {
153154
const index = formData.value.skus.findIndex(
@@ -159,7 +160,7 @@ const deleteSku = (row) => {
159160
const tableHeaders = ref<{ prop: string; label: string }[]>([]) // 多属性表头
160161
161162
/**
162-
* 将传进来的值赋值给skuList
163+
* 将传进来的值赋值给 skuList
163164
*/
164165
watch(
165166
() => props.propFormData,
@@ -173,27 +174,27 @@ watch(
173174
}
174175
)
175176
176-
// TODO @芋艿:看看 chatgpt 可以进一步下面几个方法的实现不 fix: 添加相关处理逻辑解决编辑表单时或查看详情时数据回显问题
177177
/** 生成表数据 */
178178
const generateTableData = (propertyList: any[]) => {
179-
// 构建数据结构 fix: 使用map替换多重for循环
180-
const propertiesItemList = propertyList.map((item) =>
179+
// 构建数据结构
180+
const propertyValues = propertyList.map((item) =>
181181
item.values.map((v) => ({
182182
propertyId: item.id,
183183
propertyName: item.name,
184184
valueId: v.id,
185185
valueName: v.name
186186
}))
187187
)
188-
const buildList = build(propertiesItemList)
188+
// TODO @puhui:是不是 buildSkuList,这样容易理解一点哈。item 改成 sku
189+
const buildList = build(propertyValues)
189190
// 如果回显的 sku 属性和添加的属性不一致则重置 skus 列表
190191
if (!validateData(propertyList)) {
191-
// 如果不一致则重置表数据,默认添加新的属性重新生成sku列表
192+
// 如果不一致则重置表数据,默认添加新的属性重新生成 sku 列表
192193
formData.value!.skus = []
193194
}
194195
for (const item of buildList) {
195196
const row = {
196-
properties: Array.isArray(item) ? item : [item], // 如果只有一个属性的话返回的是一个property对象
197+
properties: Array.isArray(item) ? item : [item], // 如果只有一个属性的话返回的是一个 property 对象
197198
price: 0,
198199
marketPrice: 0,
199200
costPrice: 0,
@@ -205,16 +206,17 @@ const generateTableData = (propertyList: any[]) => {
205206
subCommissionFirstPrice: 0,
206207
subCommissionSecondPrice: 0
207208
}
209+
// 如果存在属性相同的 sku 则不做处理
208210
const index = formData.value!.skus.findIndex(
209211
(sku) => JSON.stringify(sku.properties) === JSON.stringify(row.properties)
210212
)
211-
// 如果存在属性相同的 sku 则不做处理
212213
if (index !== -1) {
213214
continue
214215
}
215216
formData.value.skus.push(row)
216217
}
217218
}
219+
218220
/**
219221
* 生成 skus 前置校验
220222
*/
@@ -232,6 +234,7 @@ const validateData = (propertyList: any[]) => {
232234
const propertyIds = propertyList.map((item) => item.id)
233235
return skuPropertyIds.length === propertyIds.length
234236
}
237+
235238
/** 构建所有排列组合 */
236239
const build = (propertyValuesList: Property[][]) => {
237240
if (propertyValuesList.length === 0) {
@@ -255,13 +258,15 @@ const build = (propertyValuesList: Property[][]) => {
255258
}
256259
}
257260
258-
/** 监听属性列表生成相关参数和表头 */
261+
/** 监听属性列表,生成相关参数和表头 */
259262
watch(
260263
() => props.propertyList,
261264
(propertyList) => {
262265
// 如果不是多规格则结束
263-
if (!formData.value.specType) return
264-
// 如果当前组件作为批量添加数据使用则重置表数据
266+
if (!formData.value.specType) {
267+
return
268+
}
269+
// 如果当前组件作为批量添加数据使用,则重置表数据
265270
if (props.isBatch) {
266271
skuList.value = [
267272
{
@@ -278,26 +283,35 @@ watch(
278283
}
279284
]
280285
}
286+
281287
// 判断代理对象是否为空
282-
if (JSON.stringify(propertyList) === '[]') return
288+
if (JSON.stringify(propertyList) === '[]') {
289+
return
290+
}
283291
// 重置表头
284292
tableHeaders.value = []
285293
// 生成表头
286294
propertyList.forEach((item, index) => {
287295
// name加属性项index区分属性值
288296
tableHeaders.value.push({ prop: `name${index}`, label: item.name })
289297
})
298+
290299
// 如果回显的 sku 属性和添加的属性一致则不处理
291-
if (validateData(propertyList)) return
300+
if (validateData(propertyList)) {
301+
return
302+
}
292303
// 添加新属性没有属性值也不做处理
293-
if (propertyList.some((item) => item.values.length === 0)) return
304+
if (propertyList.some((item) => item.values.length === 0)) {
305+
return
306+
}
307+
// 生成 table 数据,即 sku 列表
294308
generateTableData(propertyList)
295309
},
296310
{
297311
deep: true,
298312
immediate: true
299313
}
300314
)
301-
// 暴露出生成 sku 方法给添加属性成功时调用 fix: 为了在只有一个属性下 spu 回显 skus 属性和和商品属性个数一致的情况下 添加属性值时添加 sku
315+
// 暴露出生成 sku 方法,给添加属性成功时调用
302316
defineExpose({ generateTableData })
303317
</script>

0 commit comments

Comments
 (0)