2024-06-03 01:09:01 +08:00
|
|
|
|
<template>
|
2024-06-06 02:20:25 +08:00
|
|
|
|
<pb-layout class="manage-goods" title="发布商品" leftIcon="leftIcon" navbar="normal" :bgStyle="bgStyle"
|
|
|
|
|
opacityBgUi="bg-white" color="black">
|
|
|
|
|
<view class="goods-form">
|
|
|
|
|
<uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160">
|
|
|
|
|
<uni-forms-item label="商品封面图" name="picUrl" required>
|
|
|
|
|
<p-uploader v-model:url="formData.picUrl" fileMediatype="image" limit="1" mode="grid"
|
|
|
|
|
:imageStyles="{ width: '168rpx', height: '168rpx' }" />
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品轮播图" name="sliderPicUrls" required>
|
|
|
|
|
<p-uploader v-model:url="formData.sliderPicUrls" fileMediatype="image" limit="6" mode="grid"
|
|
|
|
|
:imageStyles="{ width: '168rpx', height: '168rpx' }" />
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品名称" name="name" required>
|
|
|
|
|
<uni-easyinput type="text" trim="all" v-model="formData.name" placeholder="请输入商品名称" />
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品分类" @tap="openPicker('category', 'multiple')" name="categoryId" label-position="left"
|
|
|
|
|
required>
|
|
|
|
|
<uni-easyinput type="text" v-model="formData.categoryText" :styles="selfStyles"
|
|
|
|
|
placeholderStyle="color:#8a8a8a" :clearable="false" :inputBorder="false" placeholder="请选择商品分类" disabled>
|
|
|
|
|
<template v-slot:right>
|
|
|
|
|
<uni-icons type="right" />
|
|
|
|
|
</template>
|
|
|
|
|
</uni-easyinput>
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品品牌" name="brandId" label-position="left" required @tap="openPicker('brand', 'single')">
|
|
|
|
|
<uni-easyinput type="text" v-model="formData.brandText" :styles="selfStyles" placeholderStyle="color:#8a8a8a"
|
|
|
|
|
:clearable="false" :inputBorder="false" placeholder="请选择商品品牌" disabled>
|
|
|
|
|
<template v-slot:right>
|
|
|
|
|
<uni-icons type="right" />
|
|
|
|
|
</template>
|
|
|
|
|
</uni-easyinput>
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品规格" name="skus" required label-position="left">
|
|
|
|
|
<view class="btn-group">
|
|
|
|
|
<button class="ss-reset-button ss-set-property" @tap="clickSetProperty">规格设置</button>
|
|
|
|
|
</view>
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品关键词" name="keyword" required>
|
|
|
|
|
<uni-easyinput type="text" v-model="formData.keyword" placeholder="请输入商品关键词" />
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="商品简介" name="introduction" required>
|
|
|
|
|
<uni-easyinput type="textarea" trim="all" autoHeight v-model="formData.introduction" placeholder="请输入商品简介" />
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
<uni-forms-item label="物流设置" @tap="openPicker('delivery', 'single')" name="deliveryTypes" label-position="left"
|
|
|
|
|
required>
|
|
|
|
|
<uni-easyinput type="text" :clearable="false" :styles="selfStyles" placeholderStyle="color:#8a8a8a"
|
|
|
|
|
:inputBorder="false" v-model="formData.deliveryText" placeholder="请选择配送方式" disabled>
|
|
|
|
|
<template v-slot:right>
|
|
|
|
|
<uni-icons type="right" />
|
|
|
|
|
</template>
|
|
|
|
|
</uni-easyinput>
|
|
|
|
|
</uni-forms-item>
|
|
|
|
|
</uni-forms>
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
<p-picker ref="pickerRef" :mode="pickerMode" :options-cols="optionsCols" @confirm="onRDPickerConfirm"></p-picker>
|
|
|
|
|
</pb-layout>
|
2024-06-03 01:09:01 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2024-06-03 18:35:53 +08:00
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
|
|
import peach from '@/peach'
|
2024-06-04 18:43:13 +08:00
|
|
|
|
import { handleTree } from '@/peach/utils'
|
2024-06-03 18:35:53 +08:00
|
|
|
|
import GoodsApi from '@/peach/api/trade/goods'
|
|
|
|
|
import _ from 'lodash'
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
|
|
|
|
const bgStyle = {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
backgroundImage: '',
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
description: '',
|
2024-06-03 01:09:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-04 18:43:13 +08:00
|
|
|
|
const DELIVERY_TYPES = [
|
2024-06-06 02:20:25 +08:00
|
|
|
|
{
|
|
|
|
|
value: 3,
|
|
|
|
|
label: '到店核销',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: 4,
|
|
|
|
|
label: '商家配送',
|
|
|
|
|
},
|
2024-06-04 18:43:13 +08:00
|
|
|
|
]
|
2024-06-04 01:13:55 +08:00
|
|
|
|
|
2024-06-03 01:09:01 +08:00
|
|
|
|
const selfStyles = {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
backgroundColor: '#f9f9f9',
|
2024-06-03 01:09:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-04 18:43:13 +08:00
|
|
|
|
const pickerRef = ref()
|
2024-06-03 01:09:01 +08:00
|
|
|
|
const formData = ref({
|
2024-06-06 02:20:25 +08:00
|
|
|
|
picUrl: 'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
|
|
|
|
sliderPicUrls: [
|
|
|
|
|
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
|
|
|
|
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
|
|
|
|
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
|
|
|
|
],
|
|
|
|
|
name: '测试商品',
|
|
|
|
|
categoryId: [],
|
|
|
|
|
categoryText: '',
|
|
|
|
|
brandId: '',
|
|
|
|
|
keyword: '香酥鸭,但家',
|
|
|
|
|
deliveryTypes: [],
|
|
|
|
|
deliveryText: '',
|
|
|
|
|
introduction: '但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭',
|
2024-06-03 18:35:53 +08:00
|
|
|
|
})
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-03 18:35:53 +08:00
|
|
|
|
const rules = {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
name: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请输入商品名称',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
picUrl: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请上传商品封面图',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
sliderPicUrls: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请上传商品轮播图',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
categoryId: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请选择商品分类',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
brandId: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请选择商品品牌',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
skus: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请选择商品规格',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
keyword: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请输入商品关键字',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
introduction: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请输入商品简介',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
deliveryTypes: {
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
required: true,
|
|
|
|
|
errorMessage: '请选择商品物流',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
2024-06-03 18:35:53 +08:00
|
|
|
|
}
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-03 18:35:53 +08:00
|
|
|
|
const formRef = ref(null)
|
2024-06-04 18:43:13 +08:00
|
|
|
|
const pickerMode = ref('single')
|
|
|
|
|
const popMark = ref('')
|
|
|
|
|
const categoryList = ref([])
|
2024-06-05 18:58:12 +08:00
|
|
|
|
const brandList = ref([])
|
2024-06-04 18:43:13 +08:00
|
|
|
|
const optionsCols = ref([])
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-04 18:43:13 +08:00
|
|
|
|
function openPicker(mark, mode) {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
pickerMode.value = mode
|
|
|
|
|
popMark.value = mark
|
|
|
|
|
if (mark === 'delivery') {
|
|
|
|
|
optionsCols.value = DELIVERY_TYPES
|
|
|
|
|
pickerRef.value.onOpen([0])
|
|
|
|
|
} else if (mark === 'category') {
|
|
|
|
|
optionsCols.value = categoryList.value
|
|
|
|
|
pickerRef.value.onOpen([0, 0])
|
|
|
|
|
} else if (mark === 'brand') {
|
|
|
|
|
optionsCols.value = brandList.value
|
|
|
|
|
pickerRef.value.onOpen([0])
|
|
|
|
|
}
|
2024-06-04 01:13:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-04 18:43:13 +08:00
|
|
|
|
function onRDPickerConfirm(e) {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
if (popMark.value === 'delivery') {
|
|
|
|
|
formData.value.deliveryTypes = []
|
|
|
|
|
formData.value.deliveryText = DELIVERY_TYPES[e.value[0]].label
|
|
|
|
|
formData.value.deliveryTypes.push(DELIVERY_TYPES[e.value[0]].value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (popMark.value === 'category') {
|
|
|
|
|
formData.value.categoryId = categoryList.value[e.value[0]].children[e.value[1]].id
|
|
|
|
|
formData.value.categoryText =
|
|
|
|
|
categoryList.value[e.value[0]].name + '/' + categoryList.value[e.value[0]].children[e.value[1]].name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (popMark.value === 'brand') {
|
|
|
|
|
formData.value.brandId = brandList.value[e.value[0]].id
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-06 02:20:25 +08:00
|
|
|
|
function clickSetProperty() {
|
|
|
|
|
// 如果是多规格,处理格式问题,合并属性
|
|
|
|
|
let temp = formData.value.skus.map((item) => {
|
|
|
|
|
return item.properties.map((sitem) => ({
|
|
|
|
|
id: sitem.propertyId,
|
|
|
|
|
children: [sitem.valueId],
|
|
|
|
|
}));
|
|
|
|
|
})
|
|
|
|
|
.flat(1);
|
|
|
|
|
|
|
|
|
|
// 去除重复数据
|
|
|
|
|
let result = temp.reduce((pre, cur) => {
|
|
|
|
|
let index = pre.findIndex((item) => item.id === cur.id);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
pre[index].children.push(...new Set(cur.children));
|
|
|
|
|
} else {
|
|
|
|
|
pre.push(cur);
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
2024-06-05 18:58:12 +08:00
|
|
|
|
|
2024-06-06 02:20:25 +08:00
|
|
|
|
return pre;
|
|
|
|
|
}, []);
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-06 02:20:25 +08:00
|
|
|
|
peach.$store('trade').$patch({
|
|
|
|
|
selectedProperty: result,
|
|
|
|
|
goodsInfo: formData.value,
|
2024-06-07 02:05:33 +08:00
|
|
|
|
skus: formData.value.skus
|
2024-06-06 02:20:25 +08:00
|
|
|
|
})
|
|
|
|
|
peach.$router.go('/pages/product/sku')
|
2024-06-05 18:58:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getProduct(id) {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
GoodsApi.getProduct({ id }).then((res) => {
|
|
|
|
|
formData.value = res.data
|
|
|
|
|
|
|
|
|
|
// 循环遍历 categoryList,从二级分类找出和 formData.value.categoryId 相等的
|
|
|
|
|
let tempCategory = categoryList.value.find((item) => {
|
|
|
|
|
return item.children.find((child) => {
|
|
|
|
|
return child.id === formData.value.categoryId
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
formData.value.categoryText =
|
|
|
|
|
tempCategory.name +
|
|
|
|
|
'/' +
|
|
|
|
|
tempCategory.children.find((item) => {
|
|
|
|
|
return item.id === formData.value.categoryId
|
|
|
|
|
}).name
|
|
|
|
|
|
|
|
|
|
// 循环遍历 brandList, 从一级分类找出和 formData.value.brandId 相等的
|
|
|
|
|
let tempBrand = brandList.value.find((item) => {
|
|
|
|
|
return item.id === formData.value.brandId
|
2024-06-04 01:13:55 +08:00
|
|
|
|
})
|
2024-06-06 02:20:25 +08:00
|
|
|
|
|
|
|
|
|
formData.value.brandText = tempBrand.name
|
|
|
|
|
|
|
|
|
|
// 从 DELIVERY_TYPES 找出和 formData.value.deliveryTypes 相等的
|
|
|
|
|
formData.value.deliveryText = DELIVERY_TYPES.find((item) => {
|
|
|
|
|
return item.value === formData.value.deliveryTypes[0]
|
|
|
|
|
}).label
|
|
|
|
|
})
|
2024-06-03 01:09:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-04 18:43:13 +08:00
|
|
|
|
function onSubmit() {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
console.log('res', formData.value)
|
|
|
|
|
|
|
|
|
|
formRef.value
|
|
|
|
|
.validate()
|
|
|
|
|
.then(async (res) => {
|
|
|
|
|
let tempObj = { ...res }
|
|
|
|
|
|
|
|
|
|
if (formData.value.id) {
|
|
|
|
|
tempObj.id = formData.value.id
|
|
|
|
|
await GoodsApi.editProduct(tempObj)
|
|
|
|
|
} else {
|
|
|
|
|
await GoodsApi.addProduct(tempObj)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
console.log('err', err)
|
|
|
|
|
})
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获得商品分类
|
|
|
|
|
async function getCategoryList() {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
let { data } = await GoodsApi.getGoodsCategory()
|
|
|
|
|
categoryList.value = handleTree(data)
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获得商品品牌
|
|
|
|
|
async function getBrandList() {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
let { data } = await GoodsApi.getBrand()
|
|
|
|
|
brandList.value = data
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
2024-06-03 01:09:01 +08:00
|
|
|
|
|
2024-06-05 18:58:12 +08:00
|
|
|
|
onLoad(async (options) => {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
await getCategoryList()
|
|
|
|
|
await getBrandList()
|
|
|
|
|
if (options.id) {
|
|
|
|
|
getProduct(options.id)
|
|
|
|
|
}
|
2024-06-03 18:35:53 +08:00
|
|
|
|
})
|
2024-06-03 01:09:01 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.manage-goods {
|
2024-06-06 02:20:25 +08:00
|
|
|
|
.goods-form {
|
|
|
|
|
margin: 40rpx;
|
|
|
|
|
|
|
|
|
|
:deep() {
|
|
|
|
|
.uni-easyinput__content-input {
|
|
|
|
|
font-size: 28rpx !important;
|
|
|
|
|
color: #333333 !important;
|
|
|
|
|
line-height: normal !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.uni-easyinput__placeholder-class {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.is-direction-left {
|
|
|
|
|
.uni-forms-item__label {
|
|
|
|
|
padding-left: 10px;
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
border-radius: 10px 0 0 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uni-icons {
|
|
|
|
|
margin-right: 10px;
|
2024-06-04 18:43:13 +08:00
|
|
|
|
}
|
2024-06-06 02:20:25 +08:00
|
|
|
|
|
|
|
|
|
.uni-easyinput__content {
|
|
|
|
|
border-radius: 0 10px 10px 0;
|
2024-06-05 18:58:12 +08:00
|
|
|
|
}
|
2024-06-06 02:20:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.is-disabled {
|
|
|
|
|
color: #333333;
|
|
|
|
|
text-align: right;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-group {
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
align-items: center;
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
border-radius: 0 10px 10px 0;
|
|
|
|
|
|
|
|
|
|
.ss-set-property {
|
|
|
|
|
width: 80px;
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
line-height: normal;
|
|
|
|
|
background: var(--ui-BG-Main);
|
|
|
|
|
border-radius: 28rpx;
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
2024-06-03 01:09:01 +08:00
|
|
|
|
}
|
2024-06-06 02:20:25 +08:00
|
|
|
|
}
|
2024-06-03 01:09:01 +08:00
|
|
|
|
}
|
|
|
|
|
</style>
|