商品管理: 调整相关组件优化逻辑,完成表单保存和数据回显
This commit is contained in:
parent
1116fb278b
commit
9ee35fc165
@ -13,3 +13,7 @@ export const createSpu = (data: SpuType) => {
|
|||||||
export const updateSpu = (data: SpuType) => {
|
export const updateSpu = (data: SpuType) => {
|
||||||
return request.put({ url: '/product/spu/update', data })
|
return request.put({ url: '/product/spu/update', data })
|
||||||
}
|
}
|
||||||
|
// 获得商品spu
|
||||||
|
export const getSpu = (id: number) => {
|
||||||
|
return request.get({ url: `/product/spu/get-detail?id=${id}` })
|
||||||
|
}
|
||||||
|
@ -11,6 +11,10 @@ export interface Property {
|
|||||||
* 关联 {@link ProductPropertyValueDO#getId()}
|
* 关联 {@link ProductPropertyValueDO#getId()}
|
||||||
*/
|
*/
|
||||||
valueId?: number
|
valueId?: number
|
||||||
|
/**
|
||||||
|
* 属性值名称
|
||||||
|
*/
|
||||||
|
valueName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SkuType {
|
export interface SkuType {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { SkuType } from './skuType'
|
import { SkuType } from './skuType'
|
||||||
|
|
||||||
export interface SpuType {
|
export interface SpuType {
|
||||||
|
id?: number
|
||||||
name?: string // 商品名称
|
name?: string // 商品名称
|
||||||
categoryId?: number | null // 商品分类
|
categoryId?: number | null // 商品分类
|
||||||
keyword?: string // 关键字
|
keyword?: string // 关键字
|
||||||
@ -11,7 +12,7 @@ export interface SpuType {
|
|||||||
deliveryTemplateId?: number // 运费模版
|
deliveryTemplateId?: number // 运费模版
|
||||||
specType?: boolean // 商品规格
|
specType?: boolean // 商品规格
|
||||||
subCommissionType?: boolean // 分销类型
|
subCommissionType?: boolean // 分销类型
|
||||||
skus?: SkuType[] // sku数组
|
skus: SkuType[] // sku数组
|
||||||
description?: string // 商品详情
|
description?: string // 商品详情
|
||||||
sort?: string // 商品排序
|
sort?: string // 商品排序
|
||||||
giveIntegral?: number // 赠送积分
|
giveIntegral?: number // 赠送积分
|
||||||
|
@ -71,8 +71,8 @@ export const getPropertyList = (params: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获得属性项列表
|
// 获得属性项列表
|
||||||
export const getPropertyListAndValue = (params: any) => {
|
export const getPropertyListAndValue = (data: any) => {
|
||||||
return request.get({ url: '/product/property/get-value-list', params })
|
return request.post({ url: '/product/property/get-value-list', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------ 属性值 -------------------
|
// ------------------------ 属性值 -------------------
|
||||||
|
@ -36,6 +36,7 @@ import { useTagsViewStore } from '@/store/modules/tagsView'
|
|||||||
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
|
import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
|
||||||
import type { SpuType } from '@/api/mall/product/management/type/spuType' // 业务api
|
import type { SpuType } from '@/api/mall/product/management/type/spuType' // 业务api
|
||||||
import * as managementApi from '@/api/mall/product/management/spu'
|
import * as managementApi from '@/api/mall/product/management/spu'
|
||||||
|
import * as PropertyApi from '@/api/mall/product/property'
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
@ -122,8 +123,20 @@ const formData = ref<SpuType>({
|
|||||||
/** 获得详情 */
|
/** 获得详情 */
|
||||||
const getDetail = async () => {
|
const getDetail = async () => {
|
||||||
const id = query.id as unknown as number
|
const id = query.id as unknown as number
|
||||||
if (!id) {
|
if (id) {
|
||||||
return
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = (await managementApi.getSpu(id)) as SpuType
|
||||||
|
formData.value = res
|
||||||
|
// 直接取第一个值就能得到所有属性的id
|
||||||
|
const propertyIds = res.skus[0]?.properties.map((item) => item.propertyId)
|
||||||
|
const PropertyS = await PropertyApi.getPropertyListAndValue({ propertyIds })
|
||||||
|
await nextTick()
|
||||||
|
// 回显商品属性
|
||||||
|
BasicInfoRef.value.addAttribute(PropertyS)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +158,7 @@ const submitForm = async () => {
|
|||||||
// 多规格情况移除skus相关属性值value
|
// 多规格情况移除skus相关属性值value
|
||||||
if (formData.value.specType) {
|
if (formData.value.specType) {
|
||||||
item.properties.forEach((item2) => {
|
item.properties.forEach((item2) => {
|
||||||
delete item2.value
|
delete item2.valueName
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -131,6 +131,10 @@ const ProductManagementBasicInfoRef = ref() // 表单Ref
|
|||||||
const attributeList = ref([]) // 商品属性列表
|
const attributeList = ref([]) // 商品属性列表
|
||||||
/** 添加商品属性 */
|
/** 添加商品属性 */
|
||||||
const addAttribute = (property: any) => {
|
const addAttribute = (property: any) => {
|
||||||
|
if (Array.isArray(property)) {
|
||||||
|
attributeList.value = property
|
||||||
|
return
|
||||||
|
}
|
||||||
attributeList.value.push(property)
|
attributeList.value.push(property)
|
||||||
}
|
}
|
||||||
const formData = reactive<SpuType>({
|
const formData = reactive<SpuType>({
|
||||||
@ -191,7 +195,7 @@ const validate = async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
defineExpose({ validate })
|
defineExpose({ validate, addAttribute })
|
||||||
|
|
||||||
// 分销类型
|
// 分销类型
|
||||||
const changeSubCommissionType = () => {
|
const changeSubCommissionType = () => {
|
||||||
@ -203,7 +207,6 @@ const changeSubCommissionType = () => {
|
|||||||
}
|
}
|
||||||
// 选择规格
|
// 选择规格
|
||||||
const onChangeSpec = () => {
|
const onChangeSpec = () => {
|
||||||
console.log(111)
|
|
||||||
// 重置商品属性列表
|
// 重置商品属性列表
|
||||||
attributeList.value = []
|
attributeList.value = []
|
||||||
// 重置sku列表
|
// 重置sku列表
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-table :data="isBatch ? SkuData : formData.skus" border class="tabNumWidth" size="small">
|
<el-table
|
||||||
|
:data="isBatch ? SkuData : formData.skus"
|
||||||
|
border
|
||||||
|
class="tabNumWidth"
|
||||||
|
max-height="500"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
<el-table-column align="center" fixed="left" label="图片" min-width="100">
|
<el-table-column align="center" fixed="left" label="图片" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<UploadImg v-model="row.picUrl" height="80px" width="100%" />
|
<UploadImg v-model="row.picUrl" height="80px" width="100%" />
|
||||||
@ -15,7 +21,7 @@
|
|||||||
min-width="120"
|
min-width="120"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ row.properties[index].value }}
|
{{ row.properties[index]?.valueName }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</template>
|
</template>
|
||||||
@ -190,15 +196,28 @@ const generateTableData = (data: any[]) => {
|
|||||||
for (const item of data) {
|
for (const item of data) {
|
||||||
const objList = []
|
const objList = []
|
||||||
for (const v of item.values) {
|
for (const v of item.values) {
|
||||||
const obj = { propertyId: 0, valueId: 0, value: '' }
|
const obj = { propertyId: 0, valueId: 0, valueName: '' }
|
||||||
obj.propertyId = item.id
|
obj.propertyId = item.id
|
||||||
obj.valueId = v.id
|
obj.valueId = v.id
|
||||||
obj.value = v.name
|
obj.valueName = v.name
|
||||||
objList.push(obj)
|
objList.push(obj)
|
||||||
}
|
}
|
||||||
propertiesItemList.push(objList)
|
propertiesItemList.push(objList)
|
||||||
}
|
}
|
||||||
build(propertiesItemList).forEach((item) => {
|
const buildList = build(propertiesItemList)
|
||||||
|
// 如果构建后的组合数跟sku数量一样的话则不用处理,添加新属性没有属性值也不做处理 (解决编辑表单时或查看详情时数据回显问题)
|
||||||
|
console.log(
|
||||||
|
buildList.length === formData.value.skus.length || data.some((item) => item.values.length === 0)
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
buildList.length === formData.value.skus.length ||
|
||||||
|
data.some((item) => item.values.length === 0)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 重置表数据
|
||||||
|
formData.value!.skus = []
|
||||||
|
buildList.forEach((item) => {
|
||||||
const row = {
|
const row = {
|
||||||
properties: [],
|
properties: [],
|
||||||
price: 0,
|
price: 0,
|
||||||
@ -212,6 +231,7 @@ const generateTableData = (data: any[]) => {
|
|||||||
subCommissionFirstPrice: 0,
|
subCommissionFirstPrice: 0,
|
||||||
subCommissionSecondPrice: 0
|
subCommissionSecondPrice: 0
|
||||||
}
|
}
|
||||||
|
// 判断是否是单一属性的情况
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item)) {
|
||||||
row.properties = item
|
row.properties = item
|
||||||
} else {
|
} else {
|
||||||
@ -269,8 +289,6 @@ watch(
|
|||||||
if (JSON.stringify(data) === '[]') return
|
if (JSON.stringify(data) === '[]') return
|
||||||
// 重置表头
|
// 重置表头
|
||||||
tableHeaderList.value = []
|
tableHeaderList.value = []
|
||||||
// 重置表数据
|
|
||||||
formData.value!.skus = []
|
|
||||||
// 生成表头
|
// 生成表头
|
||||||
data.forEach((item, index) => {
|
data.forEach((item, index) => {
|
||||||
// name加属性项index区分属性值
|
// name加属性项index区分属性值
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
<el-image
|
<el-image
|
||||||
:src="row.picUrl"
|
:src="row.picUrl"
|
||||||
style="width: 36px; height: 36px"
|
style="width: 36px; height: 36px"
|
||||||
@click="imgViewVisible = true"
|
@click="imagePreview(row.picUrl)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -106,11 +106,38 @@
|
|||||||
/>
|
/>
|
||||||
<el-table-column fixed="right" label="状态" min-width="80">
|
<el-table-column fixed="right" label="状态" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<!--TODO 暂时用COMMON_STATUS占位一下使其不报错 -->
|
<el-switch
|
||||||
<dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="row.status" />
|
v-model="row.status"
|
||||||
|
:active-value="0"
|
||||||
|
:disabled="Number(row.status) < 0"
|
||||||
|
:inactive-value="1"
|
||||||
|
active-text="上架"
|
||||||
|
inactive-text="下架"
|
||||||
|
inline-prompt
|
||||||
|
@change="changeStatus(row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" fixed="right" label="操作" min-width="150">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['product:spu:query']"
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm(row.id)"
|
||||||
|
>
|
||||||
|
修改
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-hasPermi="['product:spu:update']"
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="changeStatus(row)"
|
||||||
|
>
|
||||||
|
加入回收站
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" fixed="right" label="操作" min-width="150" />
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
@ -123,9 +150,7 @@
|
|||||||
<!-- 必须在表格外面展示。不然单元格会遮挡图层 -->
|
<!-- 必须在表格外面展示。不然单元格会遮挡图层 -->
|
||||||
<el-image-viewer
|
<el-image-viewer
|
||||||
v-if="imgViewVisible"
|
v-if="imgViewVisible"
|
||||||
:url-list="[
|
:url-list="imageViewerList"
|
||||||
'http://127.0.0.1:48080/admin-api/infra/file/4/get/6ffdf8f5dfc03f7ceec1ff1ebc138adb8b721a057d505ccfb0e61a8783af1371.png'
|
|
||||||
]"
|
|
||||||
@close="imgViewVisible = false"
|
@close="imgViewVisible = false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@ -166,7 +191,8 @@ const headerNum = ref([
|
|||||||
type: 5
|
type: 5
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const imgViewVisible = ref(false)
|
const imgViewVisible = ref(false) // 商品图预览
|
||||||
|
const imageViewerList = ref<string[]>([]) // 商品图预览列表
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10
|
pageSize: 10
|
||||||
@ -184,7 +210,21 @@ const getList = async () => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 更改SPU状态
|
||||||
|
* @param row
|
||||||
|
*/
|
||||||
|
const changeStatus = (row) => {
|
||||||
|
console.log(row)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 商品图预览
|
||||||
|
* @param imgUrl
|
||||||
|
*/
|
||||||
|
const imagePreview = (imgUrl: string) => {
|
||||||
|
imageViewerList.value = [imgUrl]
|
||||||
|
imgViewVisible.value = true
|
||||||
|
}
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
getList()
|
getList()
|
||||||
@ -196,26 +236,18 @@ const resetQuery = () => {
|
|||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或修改
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
const openForm = (id?: number) => {
|
const openForm = (id?: number) => {
|
||||||
if (typeof id === 'number') {
|
if (typeof id === 'number') {
|
||||||
push('/product/productManagementAdd?id=' + id)
|
push('/product/productManagementAdd?id=' + id)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
push('/product/productManagementAdd')
|
push('/product/productManagementAdd')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
|
||||||
// const handleDelete = async (id: number) => {
|
|
||||||
// try {
|
|
||||||
// // 删除的二次确认
|
|
||||||
// await message.delConfirm()
|
|
||||||
// // 发起删除
|
|
||||||
// await ProductBrandApi.deleteBrand(id)
|
|
||||||
// message.success(t('common.delSuccess'))
|
|
||||||
// // 刷新列表
|
|
||||||
// await getList()
|
|
||||||
// } catch {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList()
|
||||||
|
Loading…
Reference in New Issue
Block a user