Skip to content

Commit 61218ae

Browse files
author
puhui999
committed
商品管理: 初步完成相关组件
1 parent ab1685a commit 61218ae

File tree

13 files changed

+491
-75
lines changed

13 files changed

+491
-75
lines changed

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

Whitespace-only changes.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import request from '@/config/axios'
2+
import type { SpuType } from './type/spuType'
3+
4+
// 获得sku列表
5+
export const getSkuList = (params: any) => {
6+
return request.get({ url: '/product/sku/list', params })
7+
}
8+
// 创建商品spu
9+
export const createSpu = (data: SpuType) => {
10+
return request.post({ url: '/product/spu/create', data })
11+
}
12+
// 更新商品spu
13+
export const updateSpu = (data: SpuType) => {
14+
return request.put({ url: '/product/spu/update', data })
15+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
export interface Property {
2+
/**
3+
* 属性编号
4+
*
5+
* 关联 {@link ProductPropertyDO#getId()}
6+
*/
7+
propertyId?: number
8+
/**
9+
* 属性值编号
10+
*
11+
* 关联 {@link ProductPropertyValueDO#getId()}
12+
*/
13+
valueId?: number
14+
}
15+
16+
export interface SkuType {
17+
/**
18+
* 商品 SKU 编号,自增
19+
*/
20+
id?: number
21+
/**
22+
* SPU 编号
23+
*/
24+
spuId?: number
25+
/**
26+
* 属性数组,JSON 格式
27+
*/
28+
properties?: Property[]
29+
/**
30+
* 商品价格,单位:分
31+
*/
32+
price?: number
33+
/**
34+
* 市场价,单位:分
35+
*/
36+
marketPrice?: number
37+
/**
38+
* 成本价,单位:分
39+
*/
40+
costPrice?: number
41+
/**
42+
* 商品条码
43+
*/
44+
barCode?: string
45+
/**
46+
* 图片地址
47+
*/
48+
picUrl?: string
49+
/**
50+
* 库存
51+
*/
52+
stock?: number
53+
/**
54+
* 商品重量,单位:kg 千克
55+
*/
56+
weight?: number
57+
/**
58+
* 商品体积,单位:m^3 平米
59+
*/
60+
volume?: number
61+
62+
/**
63+
* 一级分销的佣金,单位:分
64+
*/
65+
subCommissionFirstPrice?: number
66+
/**
67+
* 二级分销的佣金,单位:分
68+
*/
69+
subCommissionSecondPrice?: number
70+
71+
/**
72+
* 商品销量
73+
*/
74+
salesCount?: number
75+
}

src/api/mall/product/management/type/index.ts renamed to src/api/mall/product/management/type/spuType.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { SkuType } from './skuType'
2+
13
export interface SpuType {
24
name?: string // 商品名称
35
categoryId?: number | undefined // 商品分类
@@ -10,6 +12,7 @@ export interface SpuType {
1012
selectRule?: string // 选择规格 TODO 暂时定义
1113
specType?: boolean // 商品规格
1214
subCommissionType?: boolean // 分销类型
15+
skus?: SkuType[] // sku数组
1316
description?: string // 商品详情
1417
sort?: string // 商品排序
1518
giveIntegral?: number // 赠送积分

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@
3434
<script lang="ts" name="ProductManagementForm" setup>
3535
import { useTagsViewStore } from '@/store/modules/tagsView'
3636
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
37-
import { SpuType } from '@/api/mall/product/management/type' // const { t } = useI18n() // 国际化
37+
import type { SpuType } from '@/api/mall/product/management/type/spuType'
38+
// 业务api
39+
import * as managementApi from '@/api/mall/product/management/spu'
3840
39-
// const { t } = useI18n() // 国际化
40-
// const message = useMessage() // 消息弹窗
41+
const { t } = useI18n() // 国际化
42+
const message = useMessage() // 消息弹窗
4143
const { push, currentRoute } = useRouter() // 路由
42-
// const { query } = useRoute() // 查询参数
44+
const { query } = useRoute() // 查询参数
4345
const { delView } = useTagsViewStore() // 视图操作
4446
4547
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
@@ -70,20 +72,38 @@ const formData = ref<SpuType>({
7072
recommendGood: false // 是否优品
7173
})
7274
/** 获得详情 */
73-
const getDetail = async () => {}
75+
const getDetail = async () => {
76+
const id = query.id as unknown as number
77+
if (!id) {
78+
return
79+
}
80+
}
7481
7582
/** 提交按钮 */
7683
const submitForm = async () => {
84+
// 提交请求
85+
formLoading.value = true
7786
// TODO 三个表单逐一校验,如果有一个表单校验不通过则切换到对应表单,如果有两个及以上的情况则切换到最前面的一个并弹出提示消息
7887
// 校验各表单
7988
try {
8089
await unref(BasicInfoRef)?.validate()
8190
await unref(DescriptionRef)?.validate()
8291
await unref(OtherSettingsRef)?.validate()
8392
// 校验都通过后提交表单
84-
console.log(formData.value)
85-
} catch {}
93+
const data = formData.value as SpuType
94+
const id = query.id as unknown as number
95+
if (!id) {
96+
await managementApi.createSpu(data)
97+
message.success(t('common.createSuccess'))
98+
} else {
99+
await managementApi.updateSpu(data)
100+
message.success(t('common.updateSuccess'))
101+
}
102+
} finally {
103+
formLoading.value = false
104+
}
86105
}
106+
87107
/**
88108
* 重置表单
89109
*/

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

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
<el-col :span="12">
5959
<el-button class="ml-20px">运费模板</el-button>
6060
</el-col>
61-
<!-- TODO 商品规格和分销类型切换待定 -->
6261
<el-col :span="12">
6362
<el-form-item label="商品规格" props="specType">
6463
<el-radio-group v-model="formData.specType" @change="changeSpecType(formData.specType)">
@@ -67,45 +66,41 @@
6766
</el-radio-group>
6867
</el-form-item>
6968
</el-col>
70-
<!-- TODO 商品规格和分销类型切换待定 -->
7169
<el-col :span="12">
7270
<el-form-item label="分销类型" props="subCommissionType">
73-
<el-radio-group
74-
v-model="formData.subCommissionType"
75-
@change="changeSubCommissionType(formData.subCommissionType)"
76-
>
71+
<el-radio-group v-model="formData.subCommissionType" @change="changeSubCommissionType">
7772
<el-radio :label="false">默认设置</el-radio>
7873
<el-radio :label="true" class="radio">自行设置</el-radio>
7974
</el-radio-group>
8075
</el-form-item>
8176
</el-col>
8277
<!-- 多规格添加-->
83-
<el-col v-if="formData.specType" :span="24">
84-
<el-form-item label="选择规格" prop="">
85-
<div class="acea-row">
86-
<el-select v-model="formData.selectRule">
87-
<el-option
88-
v-for="item in []"
89-
:key="item.id"
90-
:label="item.ruleName"
91-
:value="item.id"
92-
/>
93-
</el-select>
94-
<el-button class="mr-20px" type="primary" @click="confirm">确认</el-button>
95-
<el-button class="mr-15px" @click="addRule">添加规格</el-button>
96-
</div>
78+
<el-col :span="24">
79+
<el-form-item v-if="formData.specType" label="商品属性" prop="">
80+
<el-button class="mr-15px" @click="AttributesAddFormRef.open()">添加规格</el-button>
81+
<ProductAttributes :attribute-data="attributeList" />
82+
</el-form-item>
83+
<el-form-item>
84+
<SkuList :sku-data="formData.skus" :subCommissionType="formData.subCommissionType" />
9785
</el-form-item>
9886
</el-col>
9987
</el-row>
10088
</el-form>
89+
<ProductAttributesAddForm ref="AttributesAddFormRef" @success="addAttribute" />
10190
</template>
10291
<script lang="ts" name="ProductManagementBasicInfoForm" setup>
10392
import { PropType } from 'vue'
104-
import type { SpuType } from '@/api/mall/product/management/type'
93+
import type { SpuType } from '@/api/mall/product/management/type/spuType'
10594
import { UploadImg, UploadImgs } from '@/components/UploadFile'
95+
import SkuList from './SkuList/index.vue'
96+
import ProductAttributesAddForm from './ProductAttributesAddForm.vue'
97+
import ProductAttributes from './ProductAttributes.vue'
10698
import { copyValueToTarget } from '@/utils/object'
99+
// 业务Api
107100
import * as ProductCategoryApi from '@/api/mall/product/category'
101+
import * as PropertyApi from '@/api/mall/product/property'
108102
import { defaultProps, handleTree } from '@/utils/tree'
103+
import { ElInput } from 'element-plus'
109104
110105
const message = useMessage() // 消息弹窗
111106
const props = defineProps({
@@ -114,20 +109,68 @@ const props = defineProps({
114109
default: () => {}
115110
}
116111
})
117-
112+
const AttributesAddFormRef = ref() // 添加商品属性表单
118113
const ProductManagementBasicInfoRef = ref() // 表单Ref
119-
const formData = ref<SpuType>({
114+
// 属性列表
115+
const attributeList = ref([
116+
{
117+
id: 1,
118+
name: '颜色',
119+
attributeValues: [{ id: 1, name: '白色' }]
120+
}
121+
])
122+
const addAttribute = async (propertyId: number) => {
123+
const data = await PropertyApi.getPropertyValuePage({ id: propertyId })
124+
console.log(data)
125+
}
126+
const formData = reactive<SpuType>({
120127
name: '', // 商品名称
121128
categoryId: undefined, // 商品分类
122129
keyword: '', // 关键字
123130
unit: '', // 单位
124131
picUrl: '', // 商品封面图
125132
sliderPicUrls: [], // 商品轮播图
126133
introduction: '', // 商品简介
127-
deliveryTemplateId: '', // 运费模版
134+
deliveryTemplateId: 1, // 运费模版
128135
selectRule: '', // 选择规则 TODO 暂定
129136
specType: false, // 商品规格
130-
subCommissionType: false // 分销类型
137+
subCommissionType: false, // 分销类型
138+
skus: [
139+
{
140+
/**
141+
* 商品价格,单位:分
142+
*/
143+
price: 0,
144+
/**
145+
* 市场价,单位:分
146+
*/
147+
marketPrice: 0,
148+
/**
149+
* 成本价,单位:分
150+
*/
151+
costPrice: 0,
152+
/**
153+
* 商品条码
154+
*/
155+
barCode: '',
156+
/**
157+
* 图片地址
158+
*/
159+
picUrl: '',
160+
/**
161+
* 库存
162+
*/
163+
stock: 0,
164+
/**
165+
* 商品重量,单位:kg 千克
166+
*/
167+
weight: 0,
168+
/**
169+
* 商品体积,单位:m^3 平米
170+
*/
171+
volume: 0
172+
}
173+
]
131174
})
132175
const rules = reactive({
133176
name: [required],
@@ -148,7 +191,7 @@ watch(
148191
() => props.propFormData,
149192
(data) => {
150193
if (!data) return
151-
copyValueToTarget(formData.value, data)
194+
copyValueToTarget(formData, data)
152195
},
153196
{
154197
deep: true,
@@ -170,7 +213,7 @@ const validate = async () => {
170213
throw new Error('商品信息未完善!!')
171214
} else {
172215
// 校验通过更新数据
173-
Object.assign(props.propFormData, formData.value)
216+
Object.assign(props.propFormData, formData)
174217
}
175218
})
176219
}
@@ -180,13 +223,17 @@ const changeSpecType = (specType) => {
180223
console.log(specType)
181224
}
182225
// 分销类型
183-
const changeSubCommissionType = (subCommissionType) => {
184-
console.log(subCommissionType)
226+
const changeSubCommissionType = () => {
227+
// 默认为零,类型切换后也要重置为零
228+
for (const item of formData.skus) {
229+
item.subCommissionFirstPrice = 0
230+
item.subCommissionSecondPrice = 0
231+
}
185232
}
186233
// 选择属性确认
187-
const confirm = () => {}
234+
// const confirm = () => {}
188235
// 添加规格
189-
const addRule = () => {}
236+
// const addRule = () => {}
190237
const categoryList = ref() // 分类树
191238
onMounted(async () => {
192239
// 获得分类树

src/views/mall/product/management/components/DescriptionForm.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</el-form>
88
</template>
99
<script lang="ts" name="DescriptionForm" setup>
10-
import type { SpuType } from '@/api/mall/product/management/type'
10+
import type { SpuType } from '@/api/mall/product/management/type/spuType'
1111
import { Editor } from '@/components/Editor'
1212
import { PropType } from 'vue'
1313
import { copyValueToTarget } from '@/utils/object'

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
</template>
5151
<script lang="ts" name="OtherSettingsForm" setup>
5252
// 商品推荐
53-
import type { SpuType } from '@/api/mall/product/management/type'
53+
import type { SpuType } from '@/api/mall/product/management/type/spuType'
5454
import { PropType } from 'vue'
5555
import { copyValueToTarget } from '@/utils/object'
5656

0 commit comments

Comments
 (0)