Skip to content

Commit e92361e

Browse files
committed
code review 商品管理的实现
1 parent 4a965b8 commit e92361e

File tree

13 files changed

+108
-48
lines changed

13 files changed

+108
-48
lines changed

src/api/mall/product/management/spu.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
import request from '@/config/axios'
2-
import type { SpuType } from './type/spuType'
2+
import type { SpuType } from './type/spuType' // TODO @puhui999: type 和 api 一起放,简单一点哈~
33

4-
// 获得spu列表
5-
export const getSpuList = (params: any) => {
4+
// TODO @puhui999:中英文之间有空格
5+
6+
// 获得spu列表 TODO @puhui999:这个是 getSpuPage 哈
7+
export const getSpuList = (params: PageParam) => {
68
return request.get({ url: '/product/spu/page', params })
79
}
10+
811
// 获得spu列表tabsCount
912
export const getTabsCount = () => {
1013
return request.get({ url: '/product/spu/tabsCount' })
1114
}
15+
1216
// 创建商品spu
1317
export const createSpu = (data: SpuType) => {
1418
return request.post({ url: '/product/spu/create', data })
1519
}
20+
1621
// 更新商品spu
1722
export const updateSpu = (data: SpuType) => {
1823
return request.put({ url: '/product/spu/update', data })
1924
}
25+
2026
// 更新商品spu status
2127
export const updateStatus = (data: { id: number; status: number }) => {
2228
return request.put({ url: '/product/spu/updateStatus', data })
2329
}
24-
// 获得商品spu
30+
31+
// 获得商品 spu
2532
export const getSpu = (id: number) => {
2633
return request.get({ url: `/product/spu/get-detail?id=${id}` })
2734
}
35+
2836
// 删除商品Spu
2937
export const deleteSpu = (id: number) => {
3038
return request.delete({ url: `/product/spu/delete?id=${id}` })

src/router/modules/remaining.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
355355
},
356356
children: [
357357
{
358-
path: 'productManagementAdd',
359-
component: () => import('@/views/mall/product/management/addForm.vue'),
358+
path: 'productManagementAdd', // TODO @puhui999:最好拆成 add 和 edit 两个路由;添加商品;修改商品
359+
component: () => import('@/views/mall/product/spu/addForm.vue'),
360360
name: 'ProductManagementAdd',
361361
meta: {
362362
noCache: true,

src/utils/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ export const PayRefundStatusEnum = {
220220
name: '退款关闭'
221221
}
222222
}
223+
223224
/**
224225
* 商品SPU枚举类
225226
*/

src/utils/object.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// TODO @puhui999:这个方法,可以考虑放到 index.js
12
/**
23
* 将值复制到目标对象,且以目标对象属性为准,例:target: {a:1} source:{a:2,b:3} 结果为:{a:2}
34
* @param target 目标对象

src/views/mall/product/management/addForm.vue renamed to src/views/mall/product/spu/addForm.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
3737
import type { SpuType } from '@/api/mall/product/management/type/spuType' // 业务api
3838
import * as managementApi from '@/api/mall/product/management/spu'
3939
import * as PropertyApi from '@/api/mall/product/property'
40-
4140
const { t } = useI18n() // 国际化
4241
const message = useMessage() // 消息弹窗
4342
const { push, currentRoute } = useRouter() // 路由
@@ -69,7 +68,7 @@ const formData = ref<SpuType>({
6968
skus: [
7069
{
7170
/**
72-
* 商品价格,单位:分
71+
* 商品价格,单位:分 TODO @puhui999:注释放在尾巴哈,简洁一点~
7372
*/
7473
price: 0,
7574
/**
@@ -120,6 +119,7 @@ const formData = ref<SpuType>({
120119
recommendNew: false, // 是否新品
121120
recommendGood: false // 是否优品
122121
})
122+
123123
/** 获得详情 */
124124
const getDetail = async () => {
125125
const id = query.id as unknown as number
@@ -129,6 +129,7 @@ const getDetail = async () => {
129129
const res = (await managementApi.getSpu(id)) as SpuType
130130
formData.value = res
131131
// 直接取第一个值就能得到所有属性的id
132+
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
132133
const propertyIds = res.skus[0]?.properties.map((item) => item.propertyId)
133134
const PropertyS = await PropertyApi.getPropertyListAndValue({ propertyIds })
134135
await nextTick()
@@ -151,6 +152,7 @@ const submitForm = async () => {
151152
await unref(BasicInfoRef)?.validate()
152153
await unref(DescriptionRef)?.validate()
153154
await unref(OtherSettingsRef)?.validate()
155+
// TODO @puhui:直接做深拷贝?这样最终 server 端不满足,不需要恢复
154156
// 处理掉一些无关数据
155157
formData.value.skus.forEach((item) => {
156158
// 给sku name赋值
@@ -166,6 +168,7 @@ const submitForm = async () => {
166168
const newSliderPicUrls = []
167169
formData.value.sliderPicUrls.forEach((item) => {
168170
// 如果是前端选的图
171+
// TODO @puhui999:疑问哈,为啥会是 object 呀?
169172
if (typeof item === 'object') {
170173
newSliderPicUrls.push(item.url)
171174
} else {
@@ -224,6 +227,7 @@ const resetForm = async () => {
224227
}
225228
/** 关闭按钮 */
226229
const close = () => {
230+
// TODO @puhui999:是不是不用 reset 呀?close 默认销毁
227231
resetForm()
228232
delView(unref(currentRoute))
229233
push('/product/product-management')

src/views/mall/product/management/components/BasicInfoForm.vue renamed to src/views/mall/product/spu/components/BasicInfoForm.vue

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</el-form-item>
88
</el-col>
99
<el-col :span="12">
10+
<!-- TODO @puhui999:只能选根节点 -->
1011
<el-form-item label="商品分类" prop="categoryId">
1112
<el-tree-select
1213
v-model="formData.categoryId"
@@ -15,6 +16,7 @@
1516
check-strictly
1617
node-key="id"
1718
placeholder="请选择商品分类"
19+
class="w-1/1"
1820
/>
1921
</el-form-item>
2022
</el-col>
@@ -25,7 +27,7 @@
2527
</el-col>
2628
<el-col :span="12">
2729
<el-form-item label="单位" prop="unit">
28-
<el-select v-model="formData.unit" placeholder="请选择单位">
30+
<el-select v-model="formData.unit" placeholder="请选择单位" class="w-1/1">
2931
<el-option
3032
v-for="dict in getIntDictOptions(DICT_TYPE.PRODUCT_UNIT)"
3133
:key="dict.value"
@@ -57,7 +59,7 @@
5759
</el-col>
5860
<el-col :span="12">
5961
<el-form-item label="运费模板" prop="deliveryTemplateId">
60-
<el-select v-model="formData.deliveryTemplateId" placeholder="请选择" style="width: 100%">
62+
<el-select v-model="formData.deliveryTemplateId" placeholder="请选择" class="w-1/1">
6163
<el-option v-for="item in []" :key="item.id" :label="item.name" :value="item.id" />
6264
</el-select>
6365
</el-form-item>
@@ -84,9 +86,8 @@
8486
<!-- 多规格添加-->
8587
<el-col :span="24">
8688
<el-form-item v-if="formData.specType" label="商品属性">
87-
<el-button class="mr-15px mb-10px" @click="AttributesAddFormRef.open()"
88-
>添加规格
89-
</el-button>
89+
<!-- TODO @puhui999:参考 https://admin.java.crmeb.net/store/list/creatProduct 添加规格好做么?添加的时候,不用输入备注哈 -->
90+
<el-button class="mr-15px mb-10px" @click="AttributesAddFormRef.open">添加规格</el-button>
9091
<ProductAttributes :attribute-data="attributeList" />
9192
</el-form-item>
9293
<template v-if="formData.specType && attributeList.length > 0">
@@ -108,28 +109,27 @@
108109
<script lang="ts" name="ProductManagementBasicInfoForm" setup>
109110
import { PropType } from 'vue'
110111
import { defaultProps, handleTree } from '@/utils/tree'
111-
import { ElInput } from 'element-plus'
112112
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
113113
import type { SpuType } from '@/api/mall/product/management/type/spuType'
114114
import { UploadImg, UploadImgs } from '@/components/UploadFile'
115115
import { copyValueToTarget } from '@/utils/object'
116116
import { ProductAttributes, ProductAttributesAddForm, SkuList } from './index'
117-
// 业务Api
118117
import * as ProductCategoryApi from '@/api/mall/product/category'
119118
import { propTypes } from '@/utils/propTypes'
120-
121119
const message = useMessage() // 消息弹窗
120+
122121
const props = defineProps({
123122
propFormData: {
124123
type: Object as PropType<SpuType>,
125124
default: () => {}
126125
},
127126
activeName: propTypes.string.def('')
128127
})
129-
const AttributesAddFormRef = ref() // 添加商品属性表单
130-
const ProductManagementBasicInfoRef = ref() // 表单Ref
128+
const AttributesAddFormRef = ref() // 添加商品属性表单 TODO @puhui999:小写开头哈
129+
const ProductManagementBasicInfoRef = ref() // 表单Ref TODO @puhui999:小写开头哈
130+
// TODO @puhui999:attributeList 改成 propertyList,会更统一一点
131131
const attributeList = ref([]) // 商品属性列表
132-
/** 添加商品属性 */
132+
/** 添加商品属性 */ // TODO @puhui999:propFormData 算出来
133133
const addAttribute = (property: any) => {
134134
if (Array.isArray(property)) {
135135
attributeList.value = property
@@ -162,8 +162,9 @@ const rules = reactive({
162162
specType: [required],
163163
subCommissionType: [required]
164164
})
165+
165166
/**
166-
* 将传进来的值赋值给formData
167+
* 将传进来的值赋值给 formData
167168
*/
168169
watch(
169170
() => props.propFormData,
@@ -176,10 +177,11 @@ watch(
176177
immediate: true
177178
}
178179
)
179-
const emit = defineEmits(['update:activeName'])
180+
180181
/**
181182
* 表单校验
182183
*/
184+
const emit = defineEmits(['update:activeName'])
183185
const validate = async () => {
184186
// 校验表单
185187
if (!ProductManagementBasicInfoRef) return
@@ -197,15 +199,16 @@ const validate = async () => {
197199
}
198200
defineExpose({ validate, addAttribute })
199201
200-
// 分销类型
202+
/** 分销类型 */
201203
const changeSubCommissionType = () => {
202204
// 默认为零,类型切换后也要重置为零
203205
for (const item of formData.skus) {
204206
item.subCommissionFirstPrice = 0
205207
item.subCommissionSecondPrice = 0
206208
}
207209
}
208-
// 选择规格
210+
211+
/** 选择规格 */
209212
const onChangeSpec = () => {
210213
// 重置商品属性列表
211214
attributeList.value = []

src/views/mall/product/management/components/DescriptionForm.vue renamed to src/views/mall/product/spu/components/DescriptionForm.vue

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ const DescriptionFormRef = ref() // 表单Ref
2525
const formData = ref<SpuType>({
2626
description: '' // 商品详情
2727
})
28+
// 表单规则
29+
const rules = reactive({
30+
description: [required]
31+
})
32+
2833
/**
2934
* 富文本编辑器如果输入过再清空会有残留,需再重置一次
3035
*/
@@ -40,10 +45,7 @@ watch(
4045
immediate: true
4146
}
4247
)
43-
// 表单规则
44-
const rules = reactive({
45-
description: [required]
46-
})
48+
4749
/**
4850
* 将传进来的值赋值给formData
4951
*/
@@ -58,10 +60,11 @@ watch(
5860
immediate: true
5961
}
6062
)
61-
const emit = defineEmits(['update:activeName'])
63+
6264
/**
6365
* 表单校验
6466
*/
67+
const emit = defineEmits(['update:activeName'])
6568
const validate = async () => {
6669
// 校验表单
6770
if (!DescriptionFormRef) return

src/views/mall/product/management/components/OtherSettingsForm.vue renamed to src/views/mall/product/spu/components/OtherSettingsForm.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<el-form ref="OtherSettingsFormRef" :model="formData" :rules="rules" label-width="120px">
33
<el-row>
4+
<!-- TODO @puhui999:横着三个哈 -->
45
<el-col :span="24">
56
<el-col :span="8">
67
<el-form-item label="商品排序" prop="sort">
@@ -40,6 +41,7 @@
4041
<el-tag class="ml-2" type="warning">拼团</el-tag>
4142
</el-form-item>
4243
</el-col>
44+
<!-- TODO @puhui999:等优惠劵 ok 在搞 -->
4345
<el-col :span="24">
4446
<el-form-item label="赠送优惠劵">
4547
<el-button>选择优惠券</el-button>
@@ -49,32 +51,31 @@
4951
</el-form>
5052
</template>
5153
<script lang="ts" name="OtherSettingsForm" setup>
52-
// 商品推荐
5354
import type { SpuType } from '@/api/mall/product/management/type/spuType'
5455
import { PropType } from 'vue'
5556
import { copyValueToTarget } from '@/utils/object'
5657
import { propTypes } from '@/utils/propTypes'
57-
5858
const message = useMessage() // 消息弹窗
59+
5960
const props = defineProps({
6061
propFormData: {
6162
type: Object as PropType<SpuType>,
6263
default: () => {}
6364
},
6465
activeName: propTypes.string.def('')
6566
})
66-
// 商品推荐选项
67+
// 商品推荐选项 TODO @puhui999:这种叫 recommendOptions 会更合适哈
6768
const recommend = [
6869
{ name: '是否热卖', value: 'recommendHot' },
6970
{ name: '是否优惠', value: 'recommendBenefit' },
7071
{ name: '是否精品', value: 'recommendBest' },
7172
{ name: '是否新品', value: 'recommendNew' },
7273
{ name: '是否优品', value: 'recommendGood' }
7374
]
74-
// 选中推荐选项
75-
const checkboxGroup = ref<string[]>(['recommendHot'])
76-
// 选择商品后赋值
75+
const checkboxGroup = ref<string[]>(['recommendHot']) // 选中推荐选项
76+
/** 选择商品后赋值 */
7777
const onChangeGroup = () => {
78+
// TODO @puhui999:是不是可以遍历 recommend,然后进行是否选中;
7879
checkboxGroup.value.includes('recommendHot')
7980
? (formData.value.recommendHot = true)
8081
: (formData.value.recommendHot = false)
@@ -109,6 +110,7 @@ const rules = reactive({
109110
giveIntegral: [required],
110111
virtualSalesCount: [required]
111112
})
113+
112114
/**
113115
* 将传进来的值赋值给formData
114116
*/
@@ -130,10 +132,11 @@ watch(
130132
immediate: true
131133
}
132134
)
133-
const emit = defineEmits(['update:activeName'])
135+
134136
/**
135137
* 表单校验
136138
*/
139+
const emit = defineEmits(['update:activeName'])
137140
const validate = async () => {
138141
// 校验表单
139142
if (!OtherSettingsFormRef) return
@@ -149,6 +152,5 @@ const validate = async () => {
149152
}
150153
})
151154
}
152-
153155
defineExpose({ validate })
154156
</script>

src/views/mall/product/management/components/ProductAttributes.vue renamed to src/views/mall/product/spu/components/ProductAttributes.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,19 @@ watch(
7171
immediate: true
7272
}
7373
)
74+
7475
/** 删除标签 tagValue 标签值*/
7576
const handleClose = (index, valueIndex) => {
7677
attributeList.value[index].values?.splice(valueIndex, 1)
7778
}
79+
7880
/** 显示输入框并获取焦点 */
7981
const showInput = async (index) => {
8082
attributeIndex.value = index
8183
// 因为组件在ref中所以需要用索引获取对应的Ref
8284
InputRef.value[index]!.input!.focus()
8385
}
86+
8487
/** 输入框失去焦点或点击回车时触发 */
8588
const handleInputConfirm = async (index, propertyId) => {
8689
if (inputValue.value) {

0 commit comments

Comments
 (0)