Skip to content

Commit 0c42b76

Browse files
author
puhui999
committed
fix:解决商品上一版遗留的各种小bug关键部分已添加fix注释。完成的TODO也已添加fix标记
1 parent 4ddba9d commit 0c42b76

File tree

7 files changed

+205
-75
lines changed

7 files changed

+205
-75
lines changed

src/api/mall/product/brand.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@ export const getBrand = (id: number) => {
5454
export const getBrandParam = (params: PageParam) => {
5555
return request.get({ url: '/product/brand/page', params })
5656
}
57+
58+
// 获得商品品牌精简信息列表
59+
export const getSimpleBrandList = () => {
60+
return request.get({ url: '/product/brand/list-all-simple' })
61+
}

src/api/mall/product/spu.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface SpuType {
3434
sliderPicUrls?: string[] // 商品轮播图
3535
introduction?: string // 商品简介
3636
deliveryTemplateId?: number | null // 运费模版
37+
brandId?: number | null // 商品品牌编号
3738
specType?: boolean // 商品规格
3839
subCommissionType?: boolean // 分销类型
3940
skus: SkuType[] // sku数组

src/utils/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,24 @@ export const copyValueToTarget = (target, source) => {
173173
// 更新目标对象值
174174
Object.assign(target, newObj)
175175
}
176+
177+
/**
178+
* 将一个整数转换为分数保留两位小数
179+
* @param num
180+
*/
181+
export const formatToFraction = (num: number | string | undefined): number => {
182+
if (typeof num === 'undefined') return 0
183+
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
184+
return parseFloat((parsedNumber / 100).toFixed(2))
185+
}
186+
187+
/**
188+
* 将一个分数转换为整数
189+
* @param num
190+
*/
191+
export const convertToInteger = (num: number | string | undefined): number => {
192+
if (typeof num === 'undefined') return 0
193+
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
194+
// TODO 分转元后还有小数则四舍五入
195+
return Math.round(parsedNumber * 100)
196+
}

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

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
3838
// 业务api
3939
import * as ProductSpuApi from '@/api/mall/product/spu'
4040
import * as PropertyApi from '@/api/mall/product/property'
41+
import { convertToInteger, formatToFraction } from '@/utils'
4142
4243
const { t } = useI18n() // 国际化
4344
const message = useMessage() // 消息弹窗
@@ -60,6 +61,7 @@ const formData = ref<ProductSpuApi.SpuType>({
6061
sliderPicUrls: [], // 商品轮播图
6162
introduction: '', // 商品简介
6263
deliveryTemplateId: 1, // 运费模版
64+
brandId: null, // 商品品牌
6365
specType: false, // 商品规格
6466
subCommissionType: false, // 分销类型
6567
skus: [
@@ -94,14 +96,34 @@ const getDetail = async () => {
9496
formLoading.value = true
9597
try {
9698
const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.SpuType
99+
res.skus.forEach((item) => {
100+
// 回显价格分转元
101+
item.price = formatToFraction(item.price)
102+
item.marketPrice = formatToFraction(item.marketPrice)
103+
item.costPrice = formatToFraction(item.costPrice)
104+
item.subCommissionFirstPrice = formatToFraction(item.subCommissionFirstPrice)
105+
item.subCommissionSecondPrice = formatToFraction(item.subCommissionSecondPrice)
106+
})
97107
formData.value = res
98-
// 直接取第一个值就能得到所有属性的id
99-
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
100-
const propertyIds = res.skus[0]?.properties.map((item) => item.propertyId)
101-
const PropertyS = await PropertyApi.getPropertyListAndValue({ propertyIds })
102-
await nextTick()
103-
// 回显商品属性
104-
basicInfoRef.value.addAttribute(PropertyS)
108+
// 只有是多规格才处理
109+
if (res.specType) {
110+
// TODO @puhui999:可以直接拿 propertyName 拼接处规格 id + 属性,可以看下商品 uniapp 详情的做法
111+
// fix: 考虑到 sku 数量和通过属性算出来的sku不一致的情况
112+
const propertyIds = []
113+
res.skus.forEach((sku) =>
114+
sku.properties
115+
?.map((property) => property.propertyId)
116+
.forEach((propertyId) => {
117+
if (propertyIds.indexOf(propertyId) === -1) {
118+
propertyIds.push(propertyId)
119+
}
120+
})
121+
)
122+
const properties = await PropertyApi.getPropertyListAndValue({ propertyIds })
123+
await nextTick()
124+
// 回显商品属性
125+
basicInfoRef.value.addAttribute(properties)
126+
}
105127
} finally {
106128
formLoading.value = false
107129
}
@@ -119,10 +141,26 @@ const submitForm = async () => {
119141
await unref(descriptionRef)?.validate()
120142
await unref(otherSettingsRef)?.validate()
121143
const deepCopyFormData = cloneDeep(unref(formData.value)) // 深拷贝一份 fix:这样最终 server 端不满足,不需要恢复,
122-
// 处理掉一些无关数据
144+
// TODO 兜底处理 sku 空数据详见 SkuList TODO
145+
formData.value.skus.forEach((sku) => {
146+
// 因为是空数据这里判断一下商品条码是否为空就行
147+
if (sku.barCode === '') {
148+
const index = deepCopyFormData.skus.findIndex(
149+
(item) => JSON.stringify(item.properties) === JSON.stringify(sku.properties)
150+
)
151+
// 删除这条 sku
152+
deepCopyFormData.skus.splice(index, 1)
153+
}
154+
})
123155
deepCopyFormData.skus.forEach((item) => {
124156
// 给sku name赋值
125157
item.name = deepCopyFormData.name
158+
// sku相关价格元转分
159+
item.price = convertToInteger(item.price)
160+
item.marketPrice = convertToInteger(item.marketPrice)
161+
item.costPrice = convertToInteger(item.costPrice)
162+
item.subCommissionFirstPrice = convertToInteger(item.subCommissionFirstPrice)
163+
item.subCommissionSecondPrice = convertToInteger(item.subCommissionSecondPrice)
126164
})
127165
// 处理轮播图列表
128166
const newSliderPicUrls = []
@@ -148,34 +186,6 @@ const submitForm = async () => {
148186
}
149187
}
150188
151-
/**
152-
* 重置表单
153-
* fix:先注释保留,如果后期没有使用到则移除
154-
*/
155-
// const resetForm = async () => {
156-
// formData.value = {
157-
// name: '', // 商品名称
158-
// categoryId: 0, // 商品分类
159-
// keyword: '', // 关键字
160-
// unit: '', // 单位
161-
// picUrl: '', // 商品封面图
162-
// sliderPicUrls: [], // 商品轮播图
163-
// introduction: '', // 商品简介
164-
// deliveryTemplateId: 0, // 运费模版
165-
// selectRule: '',
166-
// specType: false, // 商品规格
167-
// subCommissionType: false, // 分销类型
168-
// description: '', // 商品详情
169-
// sort: 1, // 商品排序
170-
// giveIntegral: 1, // 赠送积分
171-
// virtualSalesCount: 1, // 虚拟销量
172-
// recommendHot: false, // 是否热卖
173-
// recommendBenefit: false, // 是否优惠
174-
// recommendBest: false, // 是否精品
175-
// recommendNew: false, // 是否新品
176-
// recommendGood: false // 是否优品
177-
// }
178-
// }
179189
/** 关闭按钮 */
180190
const close = () => {
181191
delView(unref(currentRoute))

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,23 @@
5959
</el-col>
6060
<el-col :span="12">
6161
<el-form-item label="运费模板" prop="deliveryTemplateId">
62-
<el-select v-model="formData.deliveryTemplateId" class="w-1/1" placeholder="请选择">
62+
<el-select v-model="formData.deliveryTemplateId" placeholder="请选择">
6363
<el-option v-for="item in []" :key="item.id" :label="item.name" :value="item.id" />
6464
</el-select>
65+
<el-button class="ml-20px">运费模板</el-button>
6566
</el-form-item>
6667
</el-col>
6768
<el-col :span="12">
68-
<el-button class="ml-20px">运费模板</el-button>
69+
<el-form-item label="品牌" prop="brandId">
70+
<el-select v-model="formData.brandId" placeholder="请选择">
71+
<el-option
72+
v-for="item in brandList"
73+
:key="item.id"
74+
:label="item.name"
75+
:value="item.id"
76+
/>
77+
</el-select>
78+
</el-form-item>
6979
</el-col>
7080
<el-col :span="12">
7181
<el-form-item label="商品规格" props="specType">
@@ -108,14 +118,15 @@
108118
</template>
109119
<script lang="ts" name="ProductSpuBasicInfoForm" setup>
110120
import { PropType } from 'vue'
121+
import { copyValueToTarget } from '@/utils'
122+
import { propTypes } from '@/utils/propTypes'
111123
import { defaultProps, handleTree } from '@/utils/tree'
112124
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
113125
import type { SpuType } from '@/api/mall/product/spu'
114126
import { UploadImg, UploadImgs } from '@/components/UploadFile'
115127
import { ProductAttributes, ProductAttributesAddForm, SkuList } from './index'
116128
import * as ProductCategoryApi from '@/api/mall/product/category'
117-
import { propTypes } from '@/utils/propTypes'
118-
import { copyValueToTarget } from '@/utils'
129+
import { getSimpleBrandList } from '@/api/mall/product/brand'
119130
120131
const message = useMessage() // 消息弹窗
121132
@@ -135,15 +146,20 @@ const propertyList = ref([]) // 商品属性列表
135146
const addAttribute = (property: any) => {
136147
Array.isArray(property) ? (propertyList.value = property) : propertyList.value.push(property)
137148
}
149+
/** 调用 SkuList generateTableData 方法*/
150+
// const generateSkus(propertyList){
151+
// skuList.value.generateTableData()
152+
// }
138153
const formData = reactive<SpuType>({
139154
name: '', // 商品名称
140-
categoryId: undefined, // 商品分类
155+
categoryId: null, // 商品分类
141156
keyword: '', // 关键字
142157
unit: '', // 单位
143158
picUrl: '', // 商品封面图
144159
sliderPicUrls: [], // 商品轮播图
145160
introduction: '', // 商品简介
146161
deliveryTemplateId: 1, // 运费模版
162+
brandId: null, // 商品品牌
147163
specType: false, // 商品规格
148164
subCommissionType: false, // 分销类型
149165
skus: []
@@ -157,6 +173,7 @@ const rules = reactive({
157173
picUrl: [required],
158174
sliderPicUrls: [required],
159175
// deliveryTemplateId: [required],
176+
brandId: [required],
160177
specType: [required],
161178
subCommissionType: [required]
162179
})
@@ -232,10 +249,13 @@ const onChangeSpec = () => {
232249
]
233250
}
234251
235-
const categoryList = ref() // 分类树
252+
const categoryList = ref([]) // 分类树
253+
const brandList = ref([]) // 精简商品品牌列表
236254
onMounted(async () => {
237255
// 获得分类树
238256
const data = await ProductCategoryApi.getCategoryList({})
239257
categoryList.value = handleTree(data, 'id', 'parentId')
258+
// 获取商品品牌列表
259+
brandList.value = await getSimpleBrandList()
240260
})
241261
</script>

0 commit comments

Comments
 (0)