feat(商品属性)
This commit is contained in:
parent
50e03907e7
commit
c188d92c11
|
@ -9,12 +9,8 @@
|
|||
<view class="property-value ss-flex ss-gap-40">
|
||||
<view class="property-value-text">规格值</view>
|
||||
<view class="property-value-value ss-flex ss-gap-10">
|
||||
<view
|
||||
v-for="sitem in item.propertyValues"
|
||||
@tap="chooseProperty(item)"
|
||||
:class="['item', item.checked ? 'active' : '']"
|
||||
>{{ sitem.name }}</view
|
||||
>
|
||||
<view v-for="sitem in item.propertyValues" @tap="chooseProperty(item)"
|
||||
:class="['item', sitem.checked ? 'active' : '']">{{ sitem.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
@ -24,6 +20,7 @@
|
|||
|
||||
<script setup>
|
||||
import { defineProps, ref, computed } from 'vue'
|
||||
import { goodsPropertyList } from '../js/sku';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
|
@ -58,6 +55,7 @@ function chooseProperty(item) {
|
|||
.property-value-text {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.property-value-value {
|
||||
.item {
|
||||
text-align: center;
|
||||
|
@ -67,6 +65,7 @@ function chooseProperty(item) {
|
|||
border-radius: 10px;
|
||||
background-color: var(--ui-BG-4);
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
|
|
|
@ -6,12 +6,8 @@
|
|||
<view class="button-link" @click="onConfirmPopup">确定</view>
|
||||
</view>
|
||||
<view class="popup-content">
|
||||
<view
|
||||
v-for="item in goodsPropertyList"
|
||||
:key="item.id"
|
||||
:class="['property-item', item.checked ? 'active' : '']"
|
||||
@tap="chooseProperty(item)"
|
||||
>
|
||||
<view v-for="item in nowGoodsPropertyList" :key="item.id"
|
||||
:class="['property-item', item.checked ? 'active' : '']" @tap="chooseProperty(item)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
|
@ -22,6 +18,7 @@
|
|||
<script setup>
|
||||
import { ref, computed, defineEmits, defineProps, defineExpose } from 'vue'
|
||||
import peach from '@/peach'
|
||||
import { cloneDeep } from 'lodash';
|
||||
|
||||
/**
|
||||
* todo 底部高度配置
|
||||
|
@ -40,7 +37,9 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const nowGoodsPropertyList = ref([])
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'confirm'])
|
||||
|
||||
const propertyListPopupRef = ref()
|
||||
|
||||
|
@ -53,7 +52,8 @@ function chooseProperty(item) {
|
|||
}
|
||||
|
||||
function onConfirmPopup() {
|
||||
let resut = props.goodsPropertyList
|
||||
|
||||
let result = nowGoodsPropertyList.value
|
||||
.filter((item) => {
|
||||
if (item.checked) {
|
||||
return item.propertyValues.filter((sitem) => sitem.checked)
|
||||
|
@ -67,12 +67,15 @@ function onConfirmPopup() {
|
|||
}
|
||||
})
|
||||
|
||||
console.log(resut)
|
||||
// emit('update:modelValue', props.goodsPropertyList.filter((item) => item.checked).map((item) => item.id) ?? [])
|
||||
|
||||
peach.$store('trade').selectedProperty = result
|
||||
emit('confirm')
|
||||
emit('update:modelValue', result)
|
||||
onClosePopup()
|
||||
}
|
||||
|
||||
function onOpen() {
|
||||
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
|
||||
propertyListPopupRef.value.open('bottom')
|
||||
}
|
||||
|
||||
|
@ -90,6 +93,7 @@ defineExpose({
|
|||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
justify-content: flex-start;
|
||||
|
||||
.property-item {
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
|
@ -98,6 +102,7 @@ defineExpose({
|
|||
border-radius: 10px;
|
||||
background-color: var(--ui-BG-4);
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
|
@ -108,10 +113,12 @@ defineExpose({
|
|||
color: #1892ea;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.button-cancel {
|
||||
color: #888;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -1,78 +1,82 @@
|
|||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import peach from '@/peach'
|
||||
import GoodsApi from '@/peach/api/trade/goods'
|
||||
import { SPEC_TYPE } from './config'
|
||||
import { ref, computed } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import peach from "@/peach";
|
||||
import GoodsApi from "@/peach/api/trade/goods";
|
||||
import { SPEC_TYPE } from "./config";
|
||||
|
||||
const pickerRef = ref(null)
|
||||
const pickerRef = ref(null);
|
||||
|
||||
const propertyList = ref([
|
||||
{
|
||||
id: 36,
|
||||
children: [68],
|
||||
},
|
||||
{
|
||||
id: 37,
|
||||
children: [],
|
||||
},
|
||||
])
|
||||
const propertyList = ref([]);
|
||||
|
||||
const goodsPropertyList = ref([])
|
||||
const goodsPropertyList = ref([]);
|
||||
|
||||
const propertyListRef = ref(null)
|
||||
const propertyListRef = ref(null);
|
||||
|
||||
const formData = ref({
|
||||
specType: true,
|
||||
specText: SPEC_TYPE[0].label,
|
||||
})
|
||||
});
|
||||
|
||||
async function showPropertyList() {
|
||||
await getGoodsProperty()
|
||||
propertyListRef.value.onOpen()
|
||||
await getGoodsProperty();
|
||||
propertyListRef.value.onOpen();
|
||||
}
|
||||
|
||||
function onRDPickerConfirm(e) {
|
||||
peach.$store('trade').specType = SPEC_TYPE[e.value[0]].value
|
||||
formData.value.specText = SPEC_TYPE[e.value[0]].label
|
||||
formData.value.specType = SPEC_TYPE[e.value[0]].value
|
||||
peach.$store("trade").specType = SPEC_TYPE[e.value[0]].value;
|
||||
formData.value.specText = SPEC_TYPE[e.value[0]].label;
|
||||
formData.value.specType = SPEC_TYPE[e.value[0]].value;
|
||||
}
|
||||
|
||||
function pickerProperty() {
|
||||
let index = specType ? 1 : 0
|
||||
pickerRef.value.onOpen([index])
|
||||
let index = specType ? 1 : 0;
|
||||
pickerRef.value.onOpen([index]);
|
||||
}
|
||||
|
||||
function onPropertyConfirm(e) {
|
||||
console.log(e)
|
||||
getGoodsProperty();
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
async function getGoodsProperty() {
|
||||
let { data } = await GoodsApi.getHistoryProperty()
|
||||
let { data } = await GoodsApi.getHistoryProperty();
|
||||
propertyList.value = [];
|
||||
|
||||
// 把 propertyList 中 id 相同的属性合并,并去重
|
||||
propertyList.value = peach.$store("trade").selectedProperty;
|
||||
|
||||
// 根据已经选择数据,设置默认选中
|
||||
data.forEach((item) => {
|
||||
// 判断属性是否已经选中
|
||||
let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id)
|
||||
let propertyParent = propertyList.value.find(
|
||||
(sitem) => sitem?.id === item.id
|
||||
);
|
||||
|
||||
item.checked = propertyParent ? true : false
|
||||
item.checked = propertyParent ? true : false;
|
||||
|
||||
// 如果属性已经选中,查询子类中是否有选中
|
||||
if (item.checked) {
|
||||
item.propertyValues.forEach((child) => {
|
||||
let childResult = propertyParent?.children.some((schild) => schild?.id === child.id)
|
||||
child.checked = childResult ? true : false
|
||||
})
|
||||
let childResult = propertyParent?.children.some(
|
||||
(schild) => schild?.id === child.id
|
||||
);
|
||||
console.log(childResult);
|
||||
child.checked = childResult ? true : false;
|
||||
});
|
||||
}
|
||||
})
|
||||
goodsPropertyList.value = data
|
||||
});
|
||||
|
||||
goodsPropertyList.value = data;
|
||||
}
|
||||
|
||||
const specType = computed(() => peach.$store('trade').specType)
|
||||
const specType = computed(() => peach.$store("trade").specType);
|
||||
|
||||
function initial() {
|
||||
onLoad(() => {
|
||||
formData.value.specType = specType ? true : false
|
||||
formData.value.specText = SPEC_TYPE[specType ? 1 : 0].label
|
||||
})
|
||||
formData.value.specType = specType ? true : false;
|
||||
formData.value.specText = SPEC_TYPE[specType ? 1 : 0].label;
|
||||
getGoodsProperty();
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
|
@ -86,4 +90,4 @@ export {
|
|||
propertyList,
|
||||
showPropertyList,
|
||||
goodsPropertyList,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,75 +1,31 @@
|
|||
<template>
|
||||
<pb-layout
|
||||
class="manage-goods"
|
||||
title="发布商品"
|
||||
leftIcon="leftIcon"
|
||||
navbar="normal"
|
||||
:bgStyle="bgStyle"
|
||||
opacityBgUi="bg-white"
|
||||
color="black"
|
||||
>
|
||||
<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' }"
|
||||
/>
|
||||
<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' }"
|
||||
/>
|
||||
<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
|
||||
>
|
||||
<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
|
||||
>
|
||||
<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>
|
||||
|
@ -84,31 +40,12 @@
|
|||
<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-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
|
||||
>
|
||||
<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>
|
||||
|
@ -117,12 +54,7 @@
|
|||
</uni-forms>
|
||||
</view>
|
||||
|
||||
<p-picker
|
||||
ref="pickerRef"
|
||||
:mode="pickerMode"
|
||||
:options-cols="optionsCols"
|
||||
@confirm="onRDPickerConfirm"
|
||||
></p-picker>
|
||||
<p-picker ref="pickerRef" :mode="pickerMode" :options-cols="optionsCols" @confirm="onRDPickerConfirm"></p-picker>
|
||||
</pb-layout>
|
||||
</template>
|
||||
|
||||
|
@ -289,8 +221,29 @@ function onRDPickerConfirm(e) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return pre;
|
||||
}, []);
|
||||
|
||||
peach.$store('trade').$patch({
|
||||
selectedProperty: formData.value.skus,
|
||||
selectedProperty: result,
|
||||
goodsInfo: formData.value,
|
||||
})
|
||||
peach.$router.go('/pages/product/sku')
|
||||
|
@ -406,6 +359,7 @@ onLoad(async (options) => {
|
|||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
|
Loading…
Reference in New Issue